From ff2f287f82630ab3887d7d5c1e64e5b888ea0beb Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 1 Apr 2019 13:05:24 +0200 Subject: Remove crashreporter toolkit files. Resolves #20 --- .../src/breakpad_googletest_includes.h | 57 - .../google-breakpad/src/build/all.gyp | 41 - .../google-breakpad/src/build/common.gypi | 1045 ---- .../google-breakpad/src/build/filename_rules.gypi | 57 - .../google-breakpad/src/build/gyp_breakpad | 67 - .../google-breakpad/src/build/testing.gypi | 90 - .../src/client/apple/Framework/BreakpadDefines.h | 73 - .../google-breakpad/src/client/ios/Breakpad.h | 246 - .../google-breakpad/src/client/ios/Breakpad.mm | 916 --- .../client/ios/Breakpad.xcodeproj/project.pbxproj | 578 -- .../src/client/ios/BreakpadController.h | 141 - .../src/client/ios/BreakpadController.mm | 354 -- .../src/client/ios/Breakpad_Prefix.pch | 7 - .../ios/handler/ios_exception_minidump_generator.h | 74 - .../handler/ios_exception_minidump_generator.mm | 210 - .../client/linux/crash_generation/client_info.h | 53 - .../crash_generation/crash_generation_client.cc | 105 - .../crash_generation/crash_generation_client.h | 65 - .../crash_generation/crash_generation_server.cc | 333 - .../crash_generation/crash_generation_server.h | 135 - .../src/client/linux/data/linux-gate-amd.sym | 3 - .../src/client/linux/data/linux-gate-intel.sym | 3 - .../client/linux/dump_writer_common/mapping_info.h | 61 - .../linux/dump_writer_common/raw_context_cpu.h | 53 - .../client/linux/dump_writer_common/thread_info.cc | 305 - .../client/linux/dump_writer_common/thread_info.h | 91 - .../linux/dump_writer_common/ucontext_reader.cc | 259 - .../linux/dump_writer_common/ucontext_reader.h | 64 - .../src/client/linux/handler/exception_handler.cc | 789 --- .../src/client/linux/handler/exception_handler.h | 278 - .../linux/handler/exception_handler_unittest.cc | 1179 ---- .../client/linux/handler/microdump_extra_info.h | 52 - .../client/linux/handler/minidump_descriptor.cc | 87 - .../src/client/linux/handler/minidump_descriptor.h | 149 - .../google-breakpad/src/client/linux/log/log.cc | 84 - .../google-breakpad/src/client/linux/log/log.h | 55 - .../linux/microdump_writer/microdump_writer.cc | 609 -- .../linux/microdump_writer/microdump_writer.h | 65 - .../microdump_writer/microdump_writer_unittest.cc | 257 - .../src/client/linux/minidump_writer/cpu_set.h | 144 - .../linux/minidump_writer/cpu_set_unittest.cc | 164 - .../linux/minidump_writer/directory_reader.h | 106 - .../minidump_writer/directory_reader_unittest.cc | 78 - .../src/client/linux/minidump_writer/line_reader.h | 131 - .../linux/minidump_writer/line_reader_unittest.cc | 169 - .../linux/minidump_writer/linux_core_dumper.cc | 258 - .../linux/minidump_writer/linux_core_dumper.h | 125 - .../minidump_writer/linux_core_dumper_unittest.cc | 128 - .../client/linux/minidump_writer/linux_dumper.cc | 776 --- .../client/linux/minidump_writer/linux_dumper.h | 265 - .../linux_dumper_unittest_helper.cc | 94 - .../linux/minidump_writer/linux_ptrace_dumper.cc | 355 -- .../linux/minidump_writer/linux_ptrace_dumper.h | 92 - .../linux_ptrace_dumper_unittest.cc | 470 -- .../linux/minidump_writer/minidump_writer.cc | 1376 ----- .../client/linux/minidump_writer/minidump_writer.h | 124 - .../minidump_writer/minidump_writer_unittest.cc | 775 --- .../minidump_writer_unittest_utils.cc | 66 - .../minidump_writer_unittest_utils.h | 49 - .../linux/minidump_writer/proc_cpuinfo_reader.h | 130 - .../proc_cpuinfo_reader_unittest.cc | 199 - .../google-breakpad/src/client/linux/moz.build | 35 - .../linux/sender/google_crash_report_sender.cc | 104 - .../client/mac/Breakpad.xcodeproj/project.pbxproj | 2788 --------- .../src/client/mac/Framework/Breakpad.h | 285 - .../src/client/mac/Framework/Breakpad.mm | 1043 ---- .../src/client/mac/Framework/Breakpad_Prefix.pch | 8 - .../src/client/mac/Framework/Info.plist | 26 - .../src/client/mac/Framework/OnDemandServer.h | 145 - .../src/client/mac/Framework/OnDemandServer.mm | 189 - .../src/client/mac/UnitTests-Info.plist | 20 - .../src/client/mac/crash_generation/ConfigFile.h | 83 - .../src/client/mac/crash_generation/ConfigFile.mm | 167 - .../src/client/mac/crash_generation/Inspector.h | 162 - .../src/client/mac/crash_generation/Inspector.mm | 362 -- .../client/mac/crash_generation/InspectorMain.mm | 65 - .../src/client/mac/crash_generation/client_info.h | 47 - .../crash_generation/crash_generation_client.cc | 72 - .../mac/crash_generation/crash_generation_client.h | 65 - .../crash_generation/crash_generation_server.cc | 166 - .../mac/crash_generation/crash_generation_server.h | 150 - .../src/client/mac/crash_generation/moz.build | 19 - .../src/client/mac/handler/breakpad_nlist_64.cc | 402 -- .../src/client/mac/handler/breakpad_nlist_64.h | 47 - .../src/client/mac/handler/dynamic_images.cc | 573 -- .../src/client/mac/handler/dynamic_images.h | 319 - .../src/client/mac/handler/exception_handler.cc | 854 --- .../src/client/mac/handler/exception_handler.h | 281 - .../src/client/mac/handler/mach_vm_compat.h | 48 - .../src/client/mac/handler/minidump_generator.cc | 1604 ----- .../src/client/mac/handler/minidump_generator.h | 236 - .../minidump_test.xcodeproj/project.pbxproj | 841 --- .../client/mac/handler/minidump_tests32-Info.plist | 20 - .../client/mac/handler/minidump_tests64-Info.plist | 22 - .../src/client/mac/handler/moz.build | 22 - .../client/mac/handler/obj-cTestCases-Info.plist | 20 - .../mac/handler/protected_memory_allocator.cc | 92 - .../mac/handler/protected_memory_allocator.h | 85 - .../mac/handler/testcases/DynamicImagesTests.cc | 79 - .../mac/handler/testcases/DynamicImagesTests.h | 52 - .../mac/handler/testcases/breakpad_nlist_test.cc | 106 - .../mac/handler/testcases/breakpad_nlist_test.h | 62 - .../src/client/mac/handler/testcases/dwarftests.h | 46 - .../src/client/mac/handler/testcases/dwarftests.mm | 60 - .../testcases/testdata/dump_syms_dwarf_data | Bin 702795 -> 0 bytes .../testcases/testdata/dump_syms_i386_breakpad.sym | 5300 ---------------- .../src/client/mac/handler/ucontext_compat.h | 47 - .../src/client/mac/sender/Breakpad.xib | 1140 ---- .../mac/sender/English.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../mac/sender/English.lproj/Localizable.strings | Bin 2428 -> 0 bytes .../src/client/mac/sender/ReporterIcon.graffle | 2489 -------- .../mac/sender/crash_report_sender-Info.plist | 32 - .../src/client/mac/sender/crash_report_sender.h | 117 - .../src/client/mac/sender/crash_report_sender.icns | Bin 170816 -> 0 bytes .../src/client/mac/sender/crash_report_sender.m | 755 --- .../client/mac/sender/da.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/da.lproj/Localizable.strings | Bin 2428 -> 0 bytes .../client/mac/sender/de.lproj/InfoPlist.strings | Bin 192 -> 0 bytes .../client/mac/sender/de.lproj/Localizable.strings | Bin 2746 -> 0 bytes .../client/mac/sender/es.lproj/InfoPlist.strings | Bin 184 -> 0 bytes .../client/mac/sender/es.lproj/Localizable.strings | Bin 2578 -> 0 bytes .../client/mac/sender/fr.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/fr.lproj/Localizable.strings | Bin 2694 -> 0 bytes .../src/client/mac/sender/goArrow.png | Bin 3591 -> 0 bytes .../client/mac/sender/it.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/it.lproj/Localizable.strings | Bin 2590 -> 0 bytes .../client/mac/sender/ja.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/ja.lproj/Localizable.strings | Bin 1792 -> 0 bytes .../client/mac/sender/nl.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/nl.lproj/Localizable.strings | Bin 2546 -> 0 bytes .../client/mac/sender/no.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/no.lproj/Localizable.strings | Bin 2484 -> 0 bytes .../client/mac/sender/sl.lproj/InfoPlist.strings | Bin 184 -> 0 bytes .../client/mac/sender/sl.lproj/Localizable.strings | Bin 2632 -> 0 bytes .../client/mac/sender/sv.lproj/InfoPlist.strings | Bin 156 -> 0 bytes .../client/mac/sender/sv.lproj/Localizable.strings | Bin 2588 -> 0 bytes .../client/mac/sender/tr.lproj/InfoPlist.strings | Bin 168 -> 0 bytes .../client/mac/sender/tr.lproj/Localizable.strings | Bin 2430 -> 0 bytes .../src/client/mac/sender/uploader.h | 89 - .../src/client/mac/sender/uploader.mm | 636 -- .../src/client/mac/testapp/Controller.h | 65 - .../src/client/mac/testapp/Controller.m | 261 - .../mac/testapp/English.lproj/InfoPlist.strings | Bin 192 -> 0 bytes .../client/mac/testapp/English.lproj/MainMenu.xib | 3748 ------------ .../src/client/mac/testapp/Info.plist | 55 - .../src/client/mac/testapp/TestClass.h | 37 - .../src/client/mac/testapp/TestClass.mm | 95 - .../src/client/mac/testapp/bomb.icns | Bin 23659 -> 0 bytes .../src/client/mac/testapp/crashInMain | Bin 12588 -> 0 bytes .../src/client/mac/testapp/crashduringload | Bin 12588 -> 0 bytes .../google-breakpad/src/client/mac/testapp/main.m | 34 - .../src/client/mac/tests/BreakpadFramework_Test.mm | 217 - .../mac/tests/crash_generation_server_test.cc | 398 -- .../src/client/mac/tests/exception_handler_test.cc | 713 --- .../client/mac/tests/minidump_generator_test.cc | 319 - .../mac/tests/minidump_generator_test_helper.cc | 74 - .../src/client/mac/tests/spawn_child_process.h | 149 - .../src/client/mac/tests/testlogging.h | 9 - .../src/client/minidump_file_writer-inl.h | 97 - .../src/client/minidump_file_writer.cc | 350 -- .../src/client/minidump_file_writer.h | 272 - .../src/client/minidump_file_writer_unittest.cc | 179 - .../google-breakpad/src/client/moz.build | 18 - .../src/client/solaris/handler/Makefile | 78 - .../client/solaris/handler/exception_handler.cc | 258 - .../src/client/solaris/handler/exception_handler.h | 201 - .../solaris/handler/exception_handler_test.cc | 119 - .../client/solaris/handler/minidump_generator.cc | 786 --- .../client/solaris/handler/minidump_generator.h | 70 - .../src/client/solaris/handler/minidump_test.cc | 75 - .../src/client/solaris/handler/moz.build | 18 - .../src/client/solaris/handler/solaris_lwp.cc | 436 -- .../src/client/solaris/handler/solaris_lwp.h | 160 - .../src/client/windows/breakpad_client.gyp | 66 - .../client/windows/common/auto_critical_section.h | 81 - .../src/client/windows/common/ipc_protocol.h | 181 - .../src/client/windows/crash_generation/ReadMe.txt | 58 - .../client/windows/crash_generation/client_info.cc | 223 - .../client/windows/crash_generation/client_info.h | 177 - .../windows/crash_generation/crash_generation.gyp | 63 - .../crash_generation/crash_generation_client.cc | 405 -- .../crash_generation/crash_generation_client.h | 182 - .../crash_generation/crash_generation_server.cc | 931 --- .../crash_generation/crash_generation_server.h | 299 - .../windows/crash_generation/minidump_generator.cc | 579 -- .../windows/crash_generation/minidump_generator.h | 199 - .../client/windows/crash_generation/objs.mozbuild | 17 - .../client/windows/handler/exception_handler.cc | 1073 ---- .../client/windows/handler/exception_handler.gyp | 47 - .../src/client/windows/handler/exception_handler.h | 524 -- .../src/client/windows/handler/objs.mozbuild | 14 - .../client/windows/sender/crash_report_sender.cc | 142 - .../client/windows/sender/crash_report_sender.gyp | 46 - .../client/windows/sender/crash_report_sender.h | 125 - .../src/client/windows/sender/objs.mozbuild | 14 - .../tests/crash_generation_app/abstract_class.cc | 53 - .../tests/crash_generation_app/abstract_class.h | 57 - .../crash_generation_app/crash_generation_app.cc | 522 -- .../crash_generation_app/crash_generation_app.gyp | 63 - .../crash_generation_app/crash_generation_app.h | 35 - .../crash_generation_app/crash_generation_app.ico | Bin 23558 -> 0 bytes .../crash_generation_app/crash_generation_app.rc | 144 - .../windows/tests/crash_generation_app/resource.h | 73 - .../windows/tests/crash_generation_app/small.ico | Bin 23558 -> 0 bytes .../src/client/windows/unittests/client_tests.gyp | 80 - .../unittests/crash_generation_server_test.cc | 305 - .../src/client/windows/unittests/dump_analysis.cc | 184 - .../src/client/windows/unittests/dump_analysis.h | 102 - .../unittests/exception_handler_death_test.cc | 582 -- .../unittests/exception_handler_nesting_test.cc | 327 - .../windows/unittests/exception_handler_test.cc | 501 -- .../windows/unittests/exception_handler_test.h | 61 - .../src/client/windows/unittests/minidump_test.cc | 333 - .../src/client/windows/unittests/testing.gyp | 83 - .../google-breakpad/src/common/Makefile.in | 9 - .../src/common/android/breakpad_getcontext.S | 489 -- .../common/android/breakpad_getcontext_unittest.cc | 186 - .../src/common/android/include/elf.h | 168 - .../src/common/android/include/link.h | 73 - .../src/common/android/include/sgidefs.h | 41 - .../src/common/android/include/stab.h | 100 - .../src/common/android/include/sys/procfs.h | 124 - .../src/common/android/include/sys/signal.h | 35 - .../src/common/android/include/sys/user.h | 85 - .../src/common/android/include/ucontext.h | 56 - .../src/common/android/testing/include/wchar.h | 76 - .../src/common/android/testing/mkdtemp.h | 110 - .../src/common/android/testing/pthread_fixes.h | 99 - .../src/common/android/ucontext_constants.h | 144 - .../google-breakpad/src/common/arm_ex_reader.cc | 487 -- .../google-breakpad/src/common/arm_ex_reader.h | 114 - .../google-breakpad/src/common/arm_ex_to_module.cc | 209 - .../google-breakpad/src/common/arm_ex_to_module.h | 119 - .../google-breakpad/src/common/basictypes.h | 58 - .../google-breakpad/src/common/byte_cursor.h | 265 - .../src/common/byte_cursor_unittest.cc | 776 --- .../google-breakpad/src/common/common.gyp | 250 - .../google-breakpad/src/common/convert_UTF.c | 554 -- .../google-breakpad/src/common/convert_UTF.h | 164 - .../src/common/dwarf/bytereader-inl.h | 170 - .../google-breakpad/src/common/dwarf/bytereader.cc | 250 - .../google-breakpad/src/common/dwarf/bytereader.h | 315 - .../src/common/dwarf/bytereader_unittest.cc | 707 --- .../src/common/dwarf/cfi_assembler.cc | 198 - .../src/common/dwarf/cfi_assembler.h | 269 - .../src/common/dwarf/dwarf2diehandler.cc | 199 - .../src/common/dwarf/dwarf2diehandler.h | 365 -- .../src/common/dwarf/dwarf2diehandler_unittest.cc | 527 -- .../google-breakpad/src/common/dwarf/dwarf2enums.h | 675 -- .../src/common/dwarf/dwarf2reader.cc | 2734 --------- .../src/common/dwarf/dwarf2reader.h | 1288 ---- .../src/common/dwarf/dwarf2reader_cfi_unittest.cc | 2468 -------- .../src/common/dwarf/dwarf2reader_die_unittest.cc | 487 -- .../src/common/dwarf/dwarf2reader_test_common.h | 149 - .../google-breakpad/src/common/dwarf/elf_reader.cc | 1273 ---- .../google-breakpad/src/common/dwarf/elf_reader.h | 166 - .../src/common/dwarf/functioninfo.cc | 231 - .../src/common/dwarf/functioninfo.h | 188 - .../src/common/dwarf/line_state_machine.h | 61 - .../google-breakpad/src/common/dwarf/moz.build | 35 - .../google-breakpad/src/common/dwarf/types.h | 51 - .../src/common/dwarf_cfi_to_module.cc | 295 - .../src/common/dwarf_cfi_to_module.h | 202 - .../src/common/dwarf_cfi_to_module_unittest.cc | 306 - .../src/common/dwarf_cu_to_module.cc | 1075 ---- .../src/common/dwarf_cu_to_module.h | 320 - .../src/common/dwarf_cu_to_module_unittest.cc | 1804 ------ .../src/common/dwarf_line_to_module.cc | 143 - .../src/common/dwarf_line_to_module.h | 188 - .../src/common/dwarf_line_to_module_unittest.cc | 391 -- .../google-breakpad/src/common/language.cc | 83 - .../google-breakpad/src/common/language.h | 88 - .../google-breakpad/src/common/linux/crc32.cc | 70 - .../google-breakpad/src/common/linux/crc32.h | 53 - .../src/common/linux/dump_symbols.cc | 1159 ---- .../src/common/linux/dump_symbols.h | 86 - .../src/common/linux/dump_symbols_unittest.cc | 204 - .../src/common/linux/eintr_wrapper.h | 58 - .../src/common/linux/elf_core_dump.cc | 179 - .../src/common/linux/elf_core_dump.h | 148 - .../src/common/linux/elf_core_dump_unittest.cc | 256 - .../src/common/linux/elf_gnu_compat.h | 46 - .../src/common/linux/elf_symbols_to_module.cc | 178 - .../src/common/linux/elf_symbols_to_module.h | 58 - .../common/linux/elf_symbols_to_module_unittest.cc | 370 -- .../src/common/linux/elfutils-inl.h | 74 - .../google-breakpad/src/common/linux/elfutils.cc | 194 - .../google-breakpad/src/common/linux/elfutils.h | 126 - .../google-breakpad/src/common/linux/file_id.cc | 202 - .../google-breakpad/src/common/linux/file_id.h | 87 - .../src/common/linux/file_id_unittest.cc | 338 -- .../src/common/linux/google_crashdump_uploader.cc | 202 - .../src/common/linux/google_crashdump_uploader.h | 107 - .../common/linux/google_crashdump_uploader_test.cc | 170 - .../src/common/linux/guid_creator.cc | 104 - .../src/common/linux/guid_creator.h | 48 - .../src/common/linux/http_upload.cc | 230 - .../google-breakpad/src/common/linux/http_upload.h | 90 - .../google-breakpad/src/common/linux/ignore_ret.h | 40 - .../src/common/linux/libcurl_wrapper.cc | 241 - .../src/common/linux/libcurl_wrapper.h | 93 - .../src/common/linux/linux_libc_support.cc | 237 - .../src/common/linux/linux_libc_support.h | 96 - .../common/linux/linux_libc_support_unittest.cc | 213 - .../src/common/linux/memory_mapped_file.cc | 107 - .../src/common/linux/memory_mapped_file.h | 87 - .../common/linux/memory_mapped_file_unittest.cc | 208 - .../google-breakpad/src/common/linux/moz.build | 56 - .../src/common/linux/safe_readlink.cc | 53 - .../src/common/linux/safe_readlink.h | 65 - .../src/common/linux/safe_readlink_unittest.cc | 89 - .../src/common/linux/symbol_upload.cc | 155 - .../src/common/linux/symbol_upload.h | 59 - .../google-breakpad/src/common/linux/synth_elf.cc | 263 - .../google-breakpad/src/common/linux/synth_elf.h | 197 - .../src/common/linux/synth_elf_unittest.cc | 413 -- .../src/common/linux/tests/auto_testfile.h | 124 - .../src/common/linux/tests/crash_generator.cc | 322 - .../src/common/linux/tests/crash_generator.h | 117 - .../src/common/mac/Breakpad.xcconfig | 52 - .../src/common/mac/BreakpadDebug.xcconfig | 32 - .../src/common/mac/BreakpadRelease.xcconfig | 34 - .../google-breakpad/src/common/mac/GTMDefines.h | 456 -- .../google-breakpad/src/common/mac/GTMLogger.h | 504 -- .../google-breakpad/src/common/mac/GTMLogger.m | 611 -- .../src/common/mac/HTTPMultipartUpload.h | 61 - .../src/common/mac/HTTPMultipartUpload.m | 269 - .../google-breakpad/src/common/mac/MachIPC.h | 301 - .../google-breakpad/src/common/mac/MachIPC.mm | 306 - .../src/common/mac/arch_utilities.cc | 211 - .../src/common/mac/arch_utilities.h | 47 - .../src/common/mac/bootstrap_compat.cc | 42 - .../src/common/mac/bootstrap_compat.h | 54 - .../google-breakpad/src/common/mac/byteswap.h | 73 - .../google-breakpad/src/common/mac/dump_syms.cc | 646 -- .../google-breakpad/src/common/mac/dump_syms.h | 196 - .../google-breakpad/src/common/mac/file_id.cc | 106 - .../google-breakpad/src/common/mac/file_id.h | 81 - .../src/common/mac/launch_reporter.cc | 84 - .../src/common/mac/launch_reporter.h | 43 - .../google-breakpad/src/common/mac/macho_id.cc | 369 -- .../google-breakpad/src/common/mac/macho_id.h | 131 - .../google-breakpad/src/common/mac/macho_reader.cc | 539 -- .../google-breakpad/src/common/mac/macho_reader.h | 460 -- .../src/common/mac/macho_reader_unittest.cc | 1902 ------ .../src/common/mac/macho_utilities.cc | 155 - .../src/common/mac/macho_utilities.h | 95 - .../google-breakpad/src/common/mac/macho_walker.cc | 268 - .../google-breakpad/src/common/mac/macho_walker.h | 119 - .../google-breakpad/src/common/mac/moz.build | 52 - .../src/common/mac/scoped_task_suspend-inl.h | 56 - .../src/common/mac/string_utilities.cc | 84 - .../src/common/mac/string_utilities.h | 52 - .../src/common/mac/super_fat_arch.h | 88 - .../src/common/mac/testing/GTMSenTestCase.h | 1110 ---- .../src/common/mac/testing/GTMSenTestCase.m | 428 -- .../google-breakpad/src/common/md5.cc | 251 - .../crashreporter/google-breakpad/src/common/md5.h | 27 - .../google-breakpad/src/common/memory.h | 249 - .../google-breakpad/src/common/memory_range.h | 145 - .../src/common/memory_range_unittest.cc | 193 - .../google-breakpad/src/common/memory_unittest.cc | 124 - .../src/common/minidump_type_helper.h | 56 - .../google-breakpad/src/common/module.cc | 348 -- .../google-breakpad/src/common/module.h | 351 -- .../google-breakpad/src/common/module_unittest.cc | 616 -- .../google-breakpad/src/common/moz.build | 72 - .../google-breakpad/src/common/scoped_ptr.h | 404 -- .../src/common/simple_string_dictionary.cc | 45 - .../src/common/simple_string_dictionary.h | 260 - .../common/simple_string_dictionary_unittest.cc | 308 - .../src/common/solaris/dump_symbols.cc | 681 --- .../src/common/solaris/dump_symbols.h | 49 - .../google-breakpad/src/common/solaris/file_id.cc | 197 - .../google-breakpad/src/common/solaris/file_id.h | 66 - .../src/common/solaris/guid_creator.cc | 84 - .../src/common/solaris/guid_creator.h | 50 - .../src/common/solaris/message_output.h | 54 - .../google-breakpad/src/common/solaris/moz.build | 34 - .../google-breakpad/src/common/stabs_reader.cc | 315 - .../google-breakpad/src/common/stabs_reader.h | 325 - .../src/common/stabs_reader_unittest.cc | 611 -- .../google-breakpad/src/common/stabs_to_module.cc | 197 - .../google-breakpad/src/common/stabs_to_module.h | 143 - .../src/common/stabs_to_module_unittest.cc | 258 - .../google-breakpad/src/common/stdio_wrapper.h | 43 - .../src/common/string_conversion.cc | 155 - .../google-breakpad/src/common/string_conversion.h | 68 - .../google-breakpad/src/common/symbol_data.h | 42 - .../google-breakpad/src/common/test_assembler.cc | 359 -- .../google-breakpad/src/common/test_assembler.h | 484 -- .../src/common/test_assembler_unittest.cc | 1662 ----- .../src/common/testdata/func-line-pairing.h | 676 --- .../src/common/tests/auto_tempdir.h | 100 - .../google-breakpad/src/common/tests/file_utils.cc | 153 - .../google-breakpad/src/common/tests/file_utils.h | 52 - .../google-breakpad/src/common/unordered.h | 62 - .../google-breakpad/src/common/using_std_string.h | 65 - .../src/common/windows/common_windows.gyp | 105 - .../google-breakpad/src/common/windows/dia_util.cc | 92 - .../google-breakpad/src/common/windows/dia_util.h | 64 - .../src/common/windows/guid_string.cc | 76 - .../src/common/windows/guid_string.h | 58 - .../src/common/windows/http_upload.cc | 420 -- .../src/common/windows/http_upload.h | 129 - .../src/common/windows/objs.mozbuild | 15 - .../google-breakpad/src/common/windows/omap.cc | 694 --- .../google-breakpad/src/common/windows/omap.h | 72 - .../src/common/windows/omap_internal.h | 137 - .../src/common/windows/omap_unittest.cc | 330 - .../src/common/windows/pdb_source_line_writer.cc | 1369 ----- .../src/common/windows/pdb_source_line_writer.h | 257 - .../src/common/windows/string_utils-inl.h | 142 - .../src/common/windows/string_utils.cc | 133 - .../crashreporter/google-breakpad/src/config.h.in | 79 - .../src/google_breakpad/common/breakpad_types.h | 68 - .../google_breakpad/common/minidump_cpu_amd64.h | 235 - .../src/google_breakpad/common/minidump_cpu_arm.h | 151 - .../google_breakpad/common/minidump_cpu_arm64.h | 140 - .../src/google_breakpad/common/minidump_cpu_mips.h | 176 - .../src/google_breakpad/common/minidump_cpu_ppc.h | 168 - .../google_breakpad/common/minidump_cpu_ppc64.h | 134 - .../google_breakpad/common/minidump_cpu_sparc.h | 163 - .../src/google_breakpad/common/minidump_cpu_x86.h | 174 - .../common/minidump_exception_linux.h | 87 - .../common/minidump_exception_mac.h | 205 - .../common/minidump_exception_ps3.h | 67 - .../common/minidump_exception_solaris.h | 94 - .../common/minidump_exception_win32.h | 2264 ------- .../src/google_breakpad/common/minidump_format.h | 1045 ---- .../src/google_breakpad/common/minidump_size.h | 113 - .../processor/basic_source_line_resolver.h | 144 - .../src/google_breakpad/processor/call_stack.h | 87 - .../src/google_breakpad/processor/code_module.h | 101 - .../src/google_breakpad/processor/code_modules.h | 111 - .../src/google_breakpad/processor/dump_context.h | 116 - .../src/google_breakpad/processor/dump_object.h | 53 - .../src/google_breakpad/processor/exploitability.h | 82 - .../processor/fast_source_line_resolver.h | 100 - .../src/google_breakpad/processor/memory_region.h | 79 - .../src/google_breakpad/processor/microdump.h | 132 - .../processor/microdump_processor.h | 63 - .../src/google_breakpad/processor/minidump.h | 1171 ---- .../google_breakpad/processor/minidump_processor.h | 147 - .../google_breakpad/processor/proc_maps_linux.h | 60 - .../src/google_breakpad/processor/process_result.h | 66 - .../src/google_breakpad/processor/process_state.h | 198 - .../processor/source_line_resolver_base.h | 128 - .../processor/source_line_resolver_interface.h | 117 - .../src/google_breakpad/processor/stack_frame.h | 144 - .../google_breakpad/processor/stack_frame_cpu.h | 405 -- .../processor/stack_frame_symbolizer.h | 108 - .../src/google_breakpad/processor/stackwalker.h | 235 - .../google_breakpad/processor/symbol_supplier.h | 99 - .../src/google_breakpad/processor/system_info.h | 106 - .../src/processor/address_map-inl.h | 93 - .../google-breakpad/src/processor/address_map.h | 85 - .../src/processor/address_map_unittest.cc | 196 - .../src/processor/basic_code_module.h | 116 - .../src/processor/basic_code_modules.cc | 155 - .../src/processor/basic_code_modules.h | 98 - .../src/processor/basic_source_line_resolver.cc | 612 -- .../processor/basic_source_line_resolver_types.h | 177 - .../basic_source_line_resolver_unittest.cc | 682 --- .../google-breakpad/src/processor/call_stack.cc | 54 - .../src/processor/cfi_frame_info-inl.h | 119 - .../src/processor/cfi_frame_info.cc | 186 - .../google-breakpad/src/processor/cfi_frame_info.h | 275 - .../src/processor/cfi_frame_info_unittest.cc | 546 -- .../src/processor/contained_range_map-inl.h | 197 - .../src/processor/contained_range_map.h | 150 - .../src/processor/contained_range_map_unittest.cc | 263 - .../src/processor/disassembler_x86.cc | 240 - .../src/processor/disassembler_x86.h | 127 - .../src/processor/disassembler_x86_unittest.cc | 233 - .../google-breakpad/src/processor/dump_context.cc | 659 -- .../google-breakpad/src/processor/dump_object.cc | 39 - .../src/processor/exploitability.cc | 119 - .../src/processor/exploitability_linux.cc | 625 -- .../src/processor/exploitability_linux.h | 129 - .../src/processor/exploitability_unittest.cc | 306 - .../src/processor/exploitability_win.cc | 283 - .../src/processor/exploitability_win.h | 55 - .../src/processor/fast_source_line_resolver.cc | 275 - .../processor/fast_source_line_resolver_types.h | 185 - .../fast_source_line_resolver_unittest.cc | 491 -- .../google-breakpad/src/processor/linked_ptr.h | 193 - .../google-breakpad/src/processor/logging.cc | 111 - .../google-breakpad/src/processor/logging.h | 186 - .../src/processor/map_serializers-inl.h | 266 - .../src/processor/map_serializers.h | 168 - .../src/processor/map_serializers_unittest.cc | 386 -- .../google-breakpad/src/processor/microdump.cc | 385 -- .../src/processor/microdump_processor.cc | 100 - .../src/processor/microdump_processor_unittest.cc | 273 - .../src/processor/microdump_stackwalk.cc | 151 - .../microdump_stackwalk_machine_readable_test | 43 - .../src/processor/microdump_stackwalk_test | 43 - .../src/processor/microdump_stackwalk_test_vars | 1 - .../google-breakpad/src/processor/minidump.cc | 4989 --------------- .../google-breakpad/src/processor/minidump_dump.cc | 213 - .../src/processor/minidump_dump_test | 36 - .../src/processor/minidump_processor.cc | 1577 ----- .../src/processor/minidump_processor_unittest.cc | 645 -- .../src/processor/minidump_stackwalk.cc | 162 - .../minidump_stackwalk_machine_readable_test | 37 - .../src/processor/minidump_stackwalk_test | 37 - .../src/processor/minidump_unittest.cc | 1521 ----- .../src/processor/module_comparer.cc | 302 - .../src/processor/module_comparer.h | 98 - .../google-breakpad/src/processor/module_factory.h | 72 - .../src/processor/module_serializer.cc | 207 - .../src/processor/module_serializer.h | 127 - .../google-breakpad/src/processor/moz.build | 66 - .../src/processor/pathname_stripper.cc | 56 - .../src/processor/pathname_stripper.h | 53 - .../src/processor/pathname_stripper_unittest.cc | 87 - .../src/processor/postfix_evaluator-inl.h | 363 -- .../src/processor/postfix_evaluator.h | 179 - .../src/processor/postfix_evaluator_unittest.cc | 403 -- .../src/processor/proc_maps_linux.cc | 106 - .../src/processor/proc_maps_linux_unittest.cc | 251 - .../google-breakpad/src/processor/process_state.cc | 69 - .../google-breakpad/src/processor/processor.gyp | 184 - .../src/processor/processor_tools.gypi | 57 - .../google-breakpad/src/processor/proto/README | 20 - .../src/processor/proto/process_state.proto | 210 - .../google-breakpad/src/processor/range_map-inl.h | 272 - .../google-breakpad/src/processor/range_map.h | 161 - .../processor/range_map_shrink_down_unittest.cc | 355 -- .../src/processor/range_map_unittest.cc | 559 -- .../src/processor/simple_serializer-inl.h | 260 - .../src/processor/simple_serializer.h | 63 - .../src/processor/simple_symbol_supplier.cc | 204 - .../src/processor/simple_symbol_supplier.h | 140 - .../src/processor/source_line_resolver_base.cc | 341 -- .../processor/source_line_resolver_base_types.h | 158 - .../src/processor/stack_frame_cpu.cc | 79 - .../src/processor/stack_frame_symbolizer.cc | 138 - .../src/processor/stackwalk_common.cc | 950 --- .../src/processor/stackwalk_common.h | 49 - .../google-breakpad/src/processor/stackwalker.cc | 296 - .../src/processor/stackwalker_address_list.cc | 92 - .../src/processor/stackwalker_address_list.h | 72 - .../processor/stackwalker_address_list_unittest.cc | 197 - .../src/processor/stackwalker_amd64.cc | 340 -- .../src/processor/stackwalker_amd64.h | 116 - .../src/processor/stackwalker_amd64_unittest.cc | 932 --- .../src/processor/stackwalker_arm.cc | 296 - .../src/processor/stackwalker_arm.h | 107 - .../src/processor/stackwalker_arm64.cc | 278 - .../src/processor/stackwalker_arm64.h | 104 - .../src/processor/stackwalker_arm64_unittest.cc | 880 --- .../src/processor/stackwalker_arm_unittest.cc | 974 --- .../src/processor/stackwalker_mips.cc | 448 -- .../src/processor/stackwalker_mips.h | 85 - .../src/processor/stackwalker_mips_unittest.cc | 707 --- .../src/processor/stackwalker_ppc.cc | 146 - .../src/processor/stackwalker_ppc.h | 79 - .../src/processor/stackwalker_ppc64.cc | 137 - .../src/processor/stackwalker_ppc64.h | 77 - .../src/processor/stackwalker_selftest.cc | 433 -- .../src/processor/stackwalker_selftest_sol.s | 111 - .../src/processor/stackwalker_sparc.cc | 139 - .../src/processor/stackwalker_sparc.h | 78 - .../src/processor/stackwalker_unittest_utils.h | 224 - .../src/processor/stackwalker_x86.cc | 672 -- .../src/processor/stackwalker_x86.h | 117 - .../src/processor/stackwalker_x86_unittest.cc | 2128 ------- .../src/processor/static_address_map-inl.h | 71 - .../src/processor/static_address_map.h | 78 - .../src/processor/static_address_map_unittest.cc | 236 - .../src/processor/static_contained_range_map-inl.h | 92 - .../src/processor/static_contained_range_map.h | 96 - .../static_contained_range_map_unittest.cc | 320 - .../google-breakpad/src/processor/static_map-inl.h | 176 - .../google-breakpad/src/processor/static_map.h | 144 - .../src/processor/static_map_iterator-inl.h | 147 - .../src/processor/static_map_iterator.h | 112 - .../src/processor/static_map_unittest.cc | 386 -- .../src/processor/static_range_map-inl.h | 130 - .../src/processor/static_range_map.h | 106 - .../src/processor/static_range_map_unittest.cc | 421 -- .../src/processor/symbolic_constants_win.cc | 6418 -------------------- .../src/processor/symbolic_constants_win.h | 50 - .../src/processor/synth_minidump.cc | 391 -- .../google-breakpad/src/processor/synth_minidump.h | 372 -- .../src/processor/synth_minidump_unittest.cc | 336 - .../src/processor/synth_minidump_unittest_data.h | 418 -- .../google-breakpad/src/processor/tokenize.cc | 79 - .../google-breakpad/src/processor/tokenize.h | 63 - .../src/processor/windows_frame_info.h | 209 - .../google-breakpad/src/third_party/curl/COPYING | 22 - .../google-breakpad/src/third_party/curl/curl.h | 1936 ------ .../src/third_party/curl/curlbuild.h | 202 - .../src/third_party/curl/curlrules.h | 249 - .../google-breakpad/src/third_party/curl/curlver.h | 70 - .../google-breakpad/src/third_party/curl/easy.h | 103 - .../google-breakpad/src/third_party/curl/mprintf.h | 82 - .../google-breakpad/src/third_party/curl/multi.h | 346 -- .../src/third_party/curl/stdcheaders.h | 34 - .../src/third_party/curl/typecheck-gcc.h | 551 -- .../google-breakpad/src/third_party/curl/types.h | 1 - .../src/third_party/libdisasm/Makefile.am | 43 - .../google-breakpad/src/third_party/libdisasm/TODO | 43 - .../src/third_party/libdisasm/ia32_implicit.c | 422 -- .../src/third_party/libdisasm/ia32_implicit.h | 13 - .../src/third_party/libdisasm/ia32_insn.c | 623 -- .../src/third_party/libdisasm/ia32_insn.h | 506 -- .../src/third_party/libdisasm/ia32_invariant.c | 313 - .../src/third_party/libdisasm/ia32_invariant.h | 11 - .../src/third_party/libdisasm/ia32_modrm.c | 310 - .../src/third_party/libdisasm/ia32_modrm.h | 13 - .../src/third_party/libdisasm/ia32_opcode_tables.c | 2939 --------- .../src/third_party/libdisasm/ia32_opcode_tables.h | 57 - .../src/third_party/libdisasm/ia32_operand.c | 425 -- .../src/third_party/libdisasm/ia32_operand.h | 11 - .../src/third_party/libdisasm/ia32_reg.c | 234 - .../src/third_party/libdisasm/ia32_reg.h | 41 - .../src/third_party/libdisasm/ia32_settings.c | 13 - .../src/third_party/libdisasm/ia32_settings.h | 27 - .../src/third_party/libdisasm/libdis.h | 832 --- .../src/third_party/libdisasm/libdisasm.gyp | 67 - .../src/third_party/libdisasm/qword.h | 14 - .../src/third_party/libdisasm/swig/Makefile | 70 - .../src/third_party/libdisasm/swig/README | 128 - .../src/third_party/libdisasm/swig/libdisasm.i | 508 -- .../src/third_party/libdisasm/swig/libdisasm_oop.i | 1114 ---- .../third_party/libdisasm/swig/perl/Makefile-swig | 65 - .../third_party/libdisasm/swig/perl/Makefile.PL | 7 - .../libdisasm/swig/python/Makefile-swig | 64 - .../third_party/libdisasm/swig/ruby/Makefile-swig | 68 - .../src/third_party/libdisasm/swig/ruby/extconf.rb | 4 - .../third_party/libdisasm/swig/tcl/Makefile-swig | 63 - .../src/third_party/libdisasm/x86_disasm.c | 210 - .../src/third_party/libdisasm/x86_format.c | 1430 ----- .../src/third_party/libdisasm/x86_imm.c | 70 - .../src/third_party/libdisasm/x86_imm.h | 18 - .../src/third_party/libdisasm/x86_insn.c | 182 - .../src/third_party/libdisasm/x86_misc.c | 71 - .../src/third_party/libdisasm/x86_operand_list.c | 191 - .../src/third_party/libdisasm/x86_operand_list.h | 8 - .../src/third_party/linux/include/gflags/gflags.h | 533 -- .../linux/include/gflags/gflags_completions.h | 121 - .../src/third_party/lss/codereview.settings | 5 - .../src/third_party/lss/linux_syscall_support.h | 4496 -------------- .../src/third_party/mac_headers/README | 2 - .../mac_headers/architecture/byte_order.h | 45 - .../src/third_party/mac_headers/i386/_types.h | 34 - .../src/third_party/mac_headers/mach-o/arch.h | 105 - .../src/third_party/mac_headers/mach-o/fat.h | 64 - .../src/third_party/mac_headers/mach-o/loader.h | 1402 ----- .../src/third_party/mac_headers/mach-o/nlist.h | 312 - .../src/third_party/mac_headers/mach/boolean.h | 88 - .../third_party/mac_headers/mach/i386/boolean.h | 74 - .../third_party/mac_headers/mach/i386/vm_param.h | 157 - .../third_party/mac_headers/mach/i386/vm_types.h | 140 - .../src/third_party/mac_headers/mach/machine.h | 346 -- .../third_party/mac_headers/mach/machine/boolean.h | 40 - .../mac_headers/mach/machine/thread_state.h | 9 - .../mac_headers/mach/machine/thread_status.h | 1 - .../mac_headers/mach/machine/vm_types.h | 40 - .../third_party/mac_headers/mach/thread_status.h | 94 - .../src/third_party/mac_headers/mach/vm_prot.h | 140 - .../google-breakpad/src/third_party/musl/COPYRIGHT | 163 - .../google-breakpad/src/third_party/musl/README | 23 - .../src/third_party/musl/README.breakpad | 3 - .../google-breakpad/src/third_party/musl/VERSION | 1 - .../src/third_party/musl/include/elf.h | 2827 --------- .../src/tools/linux/core2md/core2md.cc | 72 - .../src/tools/linux/dump_syms/dump_syms.cc | 113 - .../src/tools/linux/dump_syms/moz.build | 33 - .../src/tools/linux/md2core/minidump-2-core.cc | 1276 ---- .../tools/linux/md2core/minidump_memory_range.h | 89 - .../md2core/minidump_memory_range_unittest.cc | 258 - .../src/tools/linux/symupload/minidump_upload.cc | 153 - .../src/tools/linux/symupload/sym_upload.cc | 112 - .../src/tools/linux/tools_linux.gypi | 83 - .../src/tools/mac/crash_report/crash_report.mm | 408 -- .../crash_report.xcodeproj/project.pbxproj | 587 -- .../mac/crash_report/on_demand_symbol_supplier.h | 111 - .../mac/crash_report/on_demand_symbol_supplier.mm | 316 - .../dump_syms/dump_syms.xcodeproj/project.pbxproj | 1839 ------ .../src/tools/mac/dump_syms/dump_syms_tool.cc | 264 - .../src/tools/mac/dump_syms/macho_dump.cc | 203 - .../src/tools/mac/dump_syms/moz.build | 40 - .../src/tools/mac/symupload/minidump_upload.m | 135 - .../src/tools/mac/symupload/symupload.m | 204 - .../symupload/symupload.xcodeproj/project.pbxproj | 254 - .../google-breakpad/src/tools/mac/tools_mac.gypi | 116 - .../mac/upload_system_symbols/arch_constants.h | 61 - .../tools/mac/upload_system_symbols/arch_reader.go | 65 - .../upload_system_symbols/upload_system_symbols.go | 420 -- .../src/tools/python/filter_syms.py | 204 - .../src/tools/python/tests/filter_syms_unittest.py | 138 - .../src/tools/solaris/dump_syms/Makefile | 64 - .../src/tools/solaris/dump_syms/Makefile.in | 5 - .../src/tools/solaris/dump_syms/dump_syms.cc | 54 - .../src/tools/solaris/dump_syms/moz.build | 29 - .../src/tools/solaris/dump_syms/run_regtest.sh | 51 - .../dump_syms/testdata/dump_syms_regtest.cc | 64 - .../dump_syms/testdata/dump_syms_regtest.stabs | 129 - .../dump_syms/testdata/dump_syms_regtest.sym | 33 - .../google-breakpad/src/tools/tools.gyp | 38 - .../src/tools/windows/binaries/dump_syms.exe | Bin 130048 -> 0 bytes .../src/tools/windows/binaries/symupload.exe | Bin 195072 -> 0 bytes .../converter/ms_symbol_server_converter.cc | 576 -- .../converter/ms_symbol_server_converter.gyp | 46 - .../windows/converter/ms_symbol_server_converter.h | 219 - .../src/tools/windows/dump_syms/dump_syms.cc | 61 - .../src/tools/windows/dump_syms/dump_syms.gyp | 64 - .../tools/windows/dump_syms/dump_syms_unittest.cc | 204 - .../src/tools/windows/dump_syms/moz.build | 31 - .../src/tools/windows/dump_syms/run_regtest.sh | 53 - .../src/tools/windows/refresh_binaries.bat | 27 - .../src/tools/windows/symupload/symupload.cc | 259 - .../src/tools/windows/symupload/symupload.gyp | 45 - 717 files changed, 203249 deletions(-) delete mode 100644 toolkit/crashreporter/google-breakpad/src/breakpad_googletest_includes.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/build/all.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/build/common.gypi delete mode 100644 toolkit/crashreporter/google-breakpad/src/build/filename_rules.gypi delete mode 100755 toolkit/crashreporter/google-breakpad/src/build/gyp_breakpad delete mode 100644 toolkit/crashreporter/google-breakpad/src/build/testing.gypi delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/apple/Framework/BreakpadDefines.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad_Prefix.pch delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/client_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-amd.sym delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-intel.sym delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/mapping_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/raw_context_cpu.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/microdump_extra_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/log/log.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/log/log.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/linux/sender/google_crash_report_sender.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Breakpad.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad_Prefix.pch delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/UnitTests-Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/InspectorMain.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/client_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/mach_vm_compat.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests32-Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests64-Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/obj-cTestCases-Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_dwarf_data delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/handler/ucontext_compat.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/Breakpad.xib delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/ReporterIcon.graffle delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender-Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.icns delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/goArrow.png delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/Localizable.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/InfoPlist.strings delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/MainMenu.xib delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Info.plist delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/bomb.icns delete mode 100755 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashInMain delete mode 100755 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashduringload delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/testapp/main.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/BreakpadFramework_Test.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/exception_handler_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test_helper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/spawn_child_process.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/mac/tests/testlogging.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/breakpad_client.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/common/auto_critical_section.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/common/ipc_protocol.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/ReadMe.txt delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/objs.mozbuild delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/handler/objs.mozbuild delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/sender/objs.mozbuild delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.ico delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.rc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/resource.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/small.ico delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/Makefile.in delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/link.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/sgidefs.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/stab.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/sys/procfs.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/sys/signal.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/include/ucontext.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/testing/include/wchar.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/testing/mkdtemp.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/testing/pthread_fixes.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/basictypes.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/byte_cursor.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/byte_cursor_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/common.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/convert_UTF.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/convert_UTF.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2enums.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_cfi_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_test_common.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/line_state_machine.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf/types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/language.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/language.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/crc32.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/crc32.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/eintr_wrapper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_gnu_compat.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elfutils-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/file_id.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/file_id_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader_test.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/ignore_ret.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/tests/auto_testfile.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/Breakpad.xcconfig delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadDebug.xcconfig delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadRelease.xcconfig delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/GTMDefines.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/byteswap.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/file_id.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/file_id.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/scoped_task_suspend-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/super_fat_arch.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/md5.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/md5.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/memory.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/memory_range.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/memory_range_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/memory_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/minidump_type_helper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/scoped_ptr.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/message_output.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/solaris/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_reader_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stabs_to_module_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/stdio_wrapper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/string_conversion.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/string_conversion.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/symbol_data.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/test_assembler.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/test_assembler.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/test_assembler_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/testdata/func-line-pairing.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/tests/auto_tempdir.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/unordered.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/using_std_string.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/common_windows.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/omap.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/omap.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/omap_internal.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/omap_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/string_utils-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/common/windows/string_utils.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/config.h.in delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/breakpad_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_amd64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_mips.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_sparc.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_x86.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_linux.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_mac.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_ps3.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_solaris.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_win32.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_format.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_size.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/basic_source_line_resolver.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/call_stack.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_modules.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_context.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_object.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/exploitability.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/fast_source_line_resolver.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/memory_region.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump_processor.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump_processor.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/proc_maps_linux.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_result.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_state.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_base.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_interface.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_cpu.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_symbolizer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/symbol_supplier.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/system_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/address_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/address_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/call_stack.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/contained_range_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/contained_range_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/dump_context.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/dump_object.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/linked_ptr.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/logging.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/logging.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/map_serializers.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/map_serializers_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/microdump.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/microdump_processor.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/microdump_processor_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk.cc delete mode 100755 toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_machine_readable_test delete mode 100755 toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test_vars delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump_dump.cc delete mode 100755 toolkit/crashreporter/google-breakpad/src/processor/minidump_dump_test delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk.cc delete mode 100755 toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_machine_readable_test delete mode 100755 toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_test delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/module_comparer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/module_factory.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/module_serializer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/module_serializer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/process_state.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/processor.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/processor_tools.gypi delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/proto/README delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/proto/process_state.proto delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/range_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/range_map_shrink_down_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/range_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/simple_serializer-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/simple_serializer.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stack_frame_cpu.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stack_frame_symbolizer.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest_sol.s delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_address_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_address_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_address_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_range_map-inl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_range_map.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/static_range_map_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/tokenize.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/tokenize.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/COPYING delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/curl.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/curlbuild.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/curlrules.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/curlver.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/easy.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/mprintf.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/multi.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/stdcheaders.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/typecheck-gcc.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/curl/types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/Makefile.am delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/TODO delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdis.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdisasm.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/qword.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/Makefile delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/README delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm.i delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm_oop.i delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile-swig delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile.PL delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/python/Makefile-swig delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/Makefile-swig delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/extconf.rb delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/tcl/Makefile-swig delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_disasm.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_format.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_misc.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.c delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags_completions.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/lss/codereview.settings delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/README delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/architecture/byte_order.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/i386/_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/arch.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/fat.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/loader.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/nlist.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/boolean.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/boolean.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_param.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/boolean.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_state.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_status.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/vm_types.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/thread_status.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/vm_prot.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/musl/COPYRIGHT delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/musl/README delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/musl/README.breakpad delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/musl/VERSION delete mode 100644 toolkit/crashreporter/google-breakpad/src/third_party/musl/include/elf.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/tools.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build delete mode 100755 toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc delete mode 100644 toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp (limited to 'toolkit/crashreporter/google-breakpad/src') diff --git a/toolkit/crashreporter/google-breakpad/src/breakpad_googletest_includes.h b/toolkit/crashreporter/google-breakpad/src/breakpad_googletest_includes.h deleted file mode 100644 index 19a3e9807..000000000 --- a/toolkit/crashreporter/google-breakpad/src/breakpad_googletest_includes.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef BREAKPAD_GOOGLETEST_INCLUDES_H__ -#define BREAKPAD_GOOGLETEST_INCLUDES_H__ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" - -// If AddressSanitizer is used, NULL pointer dereferences generate SIGILL -// (illegal instruction) instead of SIGSEGV (segmentation fault). Also, -// the number of memory regions differs, so there is no point in running -// this test if AddressSanitizer is used. -// -// Ideally we'd use this attribute to disable ASAN on a per-func basis, -// but this doesn't seem to actually work, and it's changed names over -// time. So just stick with disabling the actual tests. -// http://crbug.com/304575 -//#define NO_ASAN __attribute__((no_sanitize_address)) -#if defined(__clang__) && defined(__has_feature) -// Have to keep this check sep from above as newer gcc will barf on it. -# if __has_feature(address_sanitizer) -# define ADDRESS_SANITIZER -# endif -#elif defined(__GNUC__) && defined(__SANITIZE_ADDRESS__) -# define ADDRESS_SANITIZER -#else -# undef ADDRESS_SANITIZER -#endif - -#endif // BREAKPAD_GOOGLETEST_INCLUDES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/build/all.gyp b/toolkit/crashreporter/google-breakpad/src/build/all.gyp deleted file mode 100644 index 4b59d917b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/build/all.gyp +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'targets': [ - { - 'target_name': 'All', - 'type': 'none', - 'dependencies': [ - '../common/common.gyp:*', - '../processor/processor.gyp:*', - '../tools/tools.gyp:*', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/build/common.gypi b/toolkit/crashreporter/google-breakpad/src/build/common.gypi deleted file mode 100644 index b9466a325..000000000 --- a/toolkit/crashreporter/google-breakpad/src/build/common.gypi +++ /dev/null @@ -1,1045 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# IMPORTANT: -# Please don't directly include this file if you are building via gyp_chromium, -# since gyp_chromium is automatically forcing its inclusion. -{ - 'variables': { - # Variables expected to be overriden on the GYP command line (-D) or by - # ~/.gyp/include.gypi. - - # Putting a variables dict inside another variables dict looks kind of - # weird. This is necessary to get these variables defined for the conditions - # within this variables dict that operate on these variables. - 'variables': { - 'variables': { - # Compute the architecture that we're building on. - 'conditions': [ - [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', { - # This handles the Linux platforms we generally deal with. Anything - # else gets passed through, which probably won't work very well; such - # hosts should pass an explicit target_arch to gyp. - 'host_arch%': - '. - # Additional documentation on these macros is available at - # http://developer.apple.com/mac/library/technotes/tn2002/tn2064.html#SECTION3 - # Chrome normally builds with the Mac OS X 10.5 SDK and sets the - # deployment target to 10.5. Other projects, such as O3D, may override - # these defaults. - 'mac_sdk%': '10.5', - 'mac_deployment_target%': '10.5', - - # Set to 1 to enable code coverage. In addition to build changes - # (e.g. extra CFLAGS), also creates a new target in the src/chrome - # project file called "coverage". - # Currently ignored on Windows. - 'coverage%': 0, - - # Although base/allocator lets you select a heap library via an - # environment variable, the libcmt shim it uses sometimes gets in - # the way. To disable it entirely, and switch to normal msvcrt, do e.g. - # 'win_use_allocator_shim': 0, - # 'win_release_RuntimeLibrary': 2 - # to ~/.gyp/include.gypi, gclient runhooks --force, and do a release build. - 'win_use_allocator_shim%': 1, # 0 = shim allocator via libcmt; 1 = msvcrt - - # Whether usage of OpenMAX is enabled. - 'enable_openmax%': 0, - - # TODO(bradnelson): eliminate this when possible. - # To allow local gyp files to prevent release.vsprops from being included. - # Yes(1) means include release.vsprops. - # Once all vsprops settings are migrated into gyp, this can go away. - 'msvs_use_common_release%': 1, - - # TODO(bradnelson): eliminate this when possible. - # To allow local gyp files to override additional linker options for msvs. - # Yes(1) means set use the common linker options. - 'msvs_use_common_linker_extras%': 1, - - # TODO(sgk): eliminate this if possible. - # It would be nicer to support this via a setting in 'target_defaults' - # in chrome/app/locales/locales.gypi overriding the setting in the - # 'Debug' configuration in the 'target_defaults' dict below, - # but that doesn't work as we'd like. - 'msvs_debug_link_incremental%': '2', - - # This is the location of the sandbox binary. Chrome looks for this before - # running the zygote process. If found, and SUID, it will be used to - # sandbox the zygote process and, thus, all renderer processes. - 'linux_sandbox_path%': '', - - # Set this to true to enable SELinux support. - 'selinux%': 0, - - # Strip the binary after dumping symbols. - 'linux_strip_binary%': 0, - - # Enable TCMalloc. - 'linux_use_tcmalloc%': 1, - - # Disable TCMalloc's debugallocation. - 'linux_use_debugallocation%': 0, - - # Disable TCMalloc's heapchecker. - 'linux_use_heapchecker%': 0, - - # Set to 1 to turn on seccomp sandbox by default. - # (Note: this is ignored for official builds.) - 'linux_use_seccomp_sandbox%': 0, - - # Set to select the Title Case versions of strings in GRD files. - 'use_titlecase_in_grd%': 0, - - # Used to disable Native Client at compile time, for platforms where it - # isn't supported - 'disable_nacl%': 0, - - # Set Thumb compilation flags. - 'arm_thumb%': 0, - - # Set ARM fpu compilation flags (only meaningful if arm_version==7 and - # arm_neon==0). - 'arm_fpu%': 'vfpv3', - - # Enable new NPDevice API. - 'enable_new_npdevice_api%': 0, - - 'conditions': [ - # Whether to use multiple cores to compile with visual studio. This is - # optional because it sometimes causes corruption on VS 2005. - # It is on by default on VS 2008 and off on VS 2005. - ['OS=="win"', { - 'conditions': [ - ['MSVS_VERSION=="2005"', { - 'msvs_multi_core_compile%': 0, - },{ - 'msvs_multi_core_compile%': 1, - }], - # Don't do incremental linking for large modules on 32-bit. - ['MSVS_OS_BITS==32', { - 'msvs_large_module_debug_link_mode%': '1', # No - },{ - 'msvs_large_module_debug_link_mode%': '2', # Yes - }], - ], - 'nacl_win64_defines': [ - # This flag is used to minimize dependencies when building - # Native Client loader for 64-bit Windows. - 'NACL_WIN64', - ], - }], - ], - - # NOTE: When these end up in the Mac bundle, we need to replace '-' for '_' - # so Cocoa is happy (http://crbug.com/20441). - 'locales': [ - 'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB', - 'en-US', 'es-419', 'es', 'et', 'fi', 'fil', 'fr', 'gu', 'he', - 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'kn', 'ko', 'lt', 'lv', - 'ml', 'mr', 'nb', 'nl', 'pl', 'pt-BR', 'pt-PT', 'ro', 'ru', - 'sk', 'sl', 'sr', 'sv', 'sw', 'ta', 'te', 'th', 'tr', 'uk', - 'vi', 'zh-CN', 'zh-TW', - ], - }, - 'target_defaults': { - 'includes': [ - 'filename_rules.gypi', - ], - 'variables': { - # See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Optimize-Options.html - 'mac_release_optimization%': '3', # Use -O3 unless overridden - 'mac_debug_optimization%': '0', # Use -O0 unless overridden - # See http://msdn.microsoft.com/en-us/library/aa652360(VS.71).aspx - 'win_release_Optimization%': '2', # 2 = /Os - 'win_debug_Optimization%': '0', # 0 = /Od - # See http://msdn.microsoft.com/en-us/library/aa652367(VS.71).aspx - 'win_release_RuntimeLibrary%': '0', # 0 = /MT (nondebug static) - 'win_debug_RuntimeLibrary%': '1', # 1 = /MTd (debug static) - - 'release_extra_cflags%': '', - 'debug_extra_cflags%': '', - 'release_valgrind_build%': 0, - }, - 'conditions': [ - ['selinux==1', { - 'defines': ['CHROMIUM_SELINUX=1'], - }], - ['win_use_allocator_shim==0', { - 'conditions': [ - ['OS=="win"', { - 'defines': ['NO_TCMALLOC'], - }], - ], - }], - ['coverage!=0', { - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_INSTRUMENT_PROGRAM_FLOW_ARCS': 'YES', # -fprofile-arcs - 'GCC_GENERATE_TEST_COVERAGE_FILES': 'YES', # -ftest-coverage - }, - # Add -lgcov for types executable, shared_library, and - # loadable_module; not for static_library. - # This is a delayed conditional. - 'target_conditions': [ - ['_type!="static_library"', { - 'xcode_settings': { 'OTHER_LDFLAGS': [ '-lgcov' ] }, - }], - ], - }], - # Linux gyp (into scons) doesn't like target_conditions? - # TODO(???): track down why 'target_conditions' doesn't work - # on Linux gyp into scons like it does on Mac gyp into xcodeproj. - ['OS=="linux"', { - 'cflags': [ '-ftest-coverage', - '-fprofile-arcs' ], - 'link_settings': { 'libraries': [ '-lgcov' ] }, - }], - # Finally, for Windows, we simply turn on profiling. - ['OS=="win"', { - 'msvs_settings': { - 'VCLinkerTool': { - 'Profile': 'true', - }, - 'VCCLCompilerTool': { - # /Z7, not /Zi, so coverage is happyb - 'DebugInformationFormat': '1', - 'AdditionalOptions': ['/Yd'], - } - } - }], # OS==win - ], # conditions for coverage - }], # coverage!=0 - ], # conditions for 'target_defaults' - 'target_conditions': [ - [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', { - 'cflags!': [ - '-Wall', - '-Wextra', - '-Werror', - ], - }], - [ 'OS=="win"', { - 'defines': [ - '_CRT_SECURE_NO_DEPRECATE', - '_CRT_NONSTDC_NO_WARNINGS', - '_CRT_NONSTDC_NO_DEPRECATE', - # This is required for ATL to use XP-safe versions of its functions. - '_USING_V110_SDK71_', - ], - 'msvs_disabled_warnings': [4800], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'WarnAsError': 'true', - 'Detect64BitPortabilityProblems': 'false', - }, - }, - }], - [ 'OS=="mac"', { - 'xcode_settings': { - 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', - 'WARNING_CFLAGS!': ['-Wall'], - }, - }], - ], # target_conditions for 'target_defaults' - 'default_configuration': 'Debug', - 'configurations': { - # VCLinkerTool LinkIncremental values below: - # 0 == default - # 1 == /INCREMENTAL:NO - # 2 == /INCREMENTAL - # Debug links incremental, Release does not. - # - # Abstract base configurations to cover common - # attributes. - # - 'Common_Base': { - 'abstract': 1, - 'msvs_configuration_attributes': { - 'OutputDirectory': '$(SolutionDir)$(ConfigurationName)', - 'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)', - 'CharacterSet': '1', - }, - }, - 'x86_Base': { - 'abstract': 1, - 'msvs_settings': { - 'VCLinkerTool': { - 'MinimumRequiredVersion': '5.01', # XP. - 'TargetMachine': '1', - }, - }, - 'msvs_configuration_platform': 'Win32', - }, - 'x64_Base': { - 'abstract': 1, - 'msvs_configuration_platform': 'x64', - 'msvs_settings': { - 'VCLinkerTool': { - 'TargetMachine': '17', # x86 - 64 - 'AdditionalLibraryDirectories!': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib'], - 'AdditionalLibraryDirectories': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib/x64'], - }, - 'VCLibrarianTool': { - 'AdditionalLibraryDirectories!': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib'], - 'AdditionalLibraryDirectories': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib/x64'], - }, - }, - 'defines': [ - # Not sure if tcmalloc works on 64-bit Windows. - 'NO_TCMALLOC', - ], - }, - 'Debug_Base': { - 'abstract': 1, - 'xcode_settings': { - 'COPY_PHASE_STRIP': 'NO', - 'GCC_OPTIMIZATION_LEVEL': '<(mac_debug_optimization)', - 'OTHER_CFLAGS': [ '<@(debug_extra_cflags)', ], - }, - 'msvs_settings': { - 'VCCLCompilerTool': { - 'Optimization': '<(win_debug_Optimization)', - 'PreprocessorDefinitions': ['_DEBUG'], - 'BasicRuntimeChecks': '3', - 'RuntimeLibrary': '<(win_debug_RuntimeLibrary)', - }, - 'VCLinkerTool': { - 'LinkIncremental': '<(msvs_debug_link_incremental)', - }, - 'VCResourceCompilerTool': { - 'PreprocessorDefinitions': ['_DEBUG'], - }, - }, - 'conditions': [ - ['OS=="linux"', { - 'cflags': [ - '<@(debug_extra_cflags)', - ], - }], - ], - }, - 'Release_Base': { - 'abstract': 1, - 'defines': [ - 'NDEBUG', - ], - 'xcode_settings': { - 'DEAD_CODE_STRIPPING': 'YES', # -Wl,-dead_strip - 'GCC_OPTIMIZATION_LEVEL': '<(mac_release_optimization)', - 'OTHER_CFLAGS': [ '<@(release_extra_cflags)', ], - }, - 'msvs_settings': { - 'VCCLCompilerTool': { - 'Optimization': '<(win_release_Optimization)', - 'RuntimeLibrary': '<(win_release_RuntimeLibrary)', - }, - 'VCLinkerTool': { - 'LinkIncremental': '1', - }, - }, - 'conditions': [ - ['release_valgrind_build==0', { - 'defines': ['NVALGRIND'], - }], - ['win_use_allocator_shim==0', { - 'defines': ['NO_TCMALLOC'], - }], - ['win_release_RuntimeLibrary==2', { - # Visual C++ 2008 barfs when building anything with /MD (msvcrt): - # VC\include\typeinfo(139) : warning C4275: non dll-interface - # class 'stdext::exception' used as base for dll-interface - # class 'std::bad_cast' - 'msvs_disabled_warnings': [4275], - }], - ['OS=="linux"', { - 'cflags': [ - '<@(release_extra_cflags)', - ], - }], - ], - }, - 'Purify_Base': { - 'abstract': 1, - 'defines': [ - 'PURIFY', - 'NO_TCMALLOC', - ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'Optimization': '0', - 'RuntimeLibrary': '0', - 'BufferSecurityCheck': 'false', - }, - 'VCLinkerTool': { - 'EnableCOMDATFolding': '1', - 'LinkIncremental': '1', - }, - }, - }, - # - # Concrete configurations - # - 'Debug': { - 'inherit_from': ['Common_Base', 'x86_Base', 'Debug_Base'], - }, - 'Release': { - 'inherit_from': ['Common_Base', 'x86_Base', 'Release_Base'], - 'conditions': [ - ['msvs_use_common_release', { - 'defines': ['OFFICIAL_BUILD'], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'Optimization': '3', - 'StringPooling': 'true', - 'OmitFramePointers': 'true', - 'InlineFunctionExpansion': '2', - 'EnableIntrinsicFunctions': 'true', - 'FavorSizeOrSpeed': '2', - 'OmitFramePointers': 'true', - 'EnableFiberSafeOptimizations': 'true', - 'WholeProgramOptimization': 'true', - }, - 'VCLibrarianTool': { - 'AdditionalOptions': ['/ltcg', '/expectedoutputsize:120000000'], - }, - 'VCLinkerTool': { - 'LinkIncremental': '1', - 'OptimizeReferences': '2', - 'EnableCOMDATFolding': '2', - 'OptimizeForWindows98': '1', - 'LinkTimeCodeGeneration': '1', - }, - }, - }], - ] - }, - 'conditions': [ - [ 'OS=="win"', { - # TODO(bradnelson): add a gyp mechanism to make this more graceful. - 'Purify': { - 'inherit_from': ['Common_Base', 'x86_Base', 'Release_Base', 'Purify'], - }, - 'Debug_x64': { - 'inherit_from': ['Common_Base', 'x64_Base', 'Debug_Base'], - }, - 'Release_x64': { - 'inherit_from': ['Common_Base', 'x64_Base', 'Release_Base'], - }, - 'Purify_x64': { - 'inherit_from': ['Common_Base', 'x64_Base', 'Release_Base', 'Purify_Base'], - }, - }], - ], - }, - }, - 'conditions': [ - ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { - 'target_defaults': { - # Enable -Werror by default, but put it in a variable so it can - # be disabled in ~/.gyp/include.gypi on the valgrind builders. - 'variables': { - # Use -fno-strict-aliasing by default since gcc 4.4 has periodic - # issues that slip through the cracks. We could do this just for - # gcc 4.4 but it makes more sense to be consistent on all - # compilers in use. TODO(Craig): turn this off again when - # there is some 4.4 test infrastructure in place and existing - # aliasing issues have been fixed. - 'no_strict_aliasing%': 1, - 'conditions': [['OS=="linux"', {'werror%': '-Werror',}], - ['OS=="freebsd"', {'werror%': '',}], - ['OS=="openbsd"', {'werror%': '',}], - ], - }, - 'cflags': [ - '<(werror)', # See note above about the werror variable. - '-pthread', - '-fno-exceptions', - '-Wall', - # TODO(evan): turn this back on once all the builds work. - # '-Wextra', - # Don't warn about unused function params. We use those everywhere. - '-Wno-unused-parameter', - # Don't warn about the "struct foo f = {0};" initialization pattern. - '-Wno-missing-field-initializers', - '-D_FILE_OFFSET_BITS=64', - # Don't export any symbols (for example, to plugins we dlopen()). - # Note: this is *required* to make some plugins work. - '-fvisibility=hidden', - ], - 'cflags_cc': [ - '-frtti', - '-fno-threadsafe-statics', - # Make inline functions have hidden visiblity by default. - # Surprisingly, not covered by -fvisibility=hidden. - '-fvisibility-inlines-hidden', - ], - 'ldflags': [ - '-pthread', '-Wl,-z,noexecstack', - ], - 'scons_variable_settings': { - 'LIBPATH': ['$LIB_DIR'], - # Linking of large files uses lots of RAM, so serialize links - # using the handy flock command from util-linux. - 'FLOCK_LINK': ['flock', '$TOP_BUILDDIR/linker.lock', '$LINK'], - 'FLOCK_SHLINK': ['flock', '$TOP_BUILDDIR/linker.lock', '$SHLINK'], - 'FLOCK_LDMODULE': ['flock', '$TOP_BUILDDIR/linker.lock', '$LDMODULE'], - - # We have several cases where archives depend on each other in - # a cyclic fashion. Since the GNU linker does only a single - # pass over the archives we surround the libraries with - # --start-group and --end-group (aka -( and -) ). That causes - # ld to loop over the group until no more undefined symbols - # are found. In an ideal world we would only make groups from - # those libraries which we knew to be in cycles. However, - # that's tough with SCons, so we bodge it by making all the - # archives a group by redefining the linking command here. - # - # TODO: investigate whether we still have cycles that - # require --{start,end}-group. There has been a lot of - # refactoring since this was first coded, which might have - # eliminated the circular dependencies. - # - # Note: $_LIBDIRFLAGS comes before ${LINK,SHLINK,LDMODULE}FLAGS - # so that we prefer our own built libraries (e.g. -lpng) to - # system versions of libraries that pkg-config might turn up. - # TODO(sgk): investigate handling this not by re-ordering the - # flags this way, but by adding a hook to use the SCons - # ParseFlags() option on the output from pkg-config. - 'LINKCOM': [['$FLOCK_LINK', '-o', '$TARGET', - '$_LIBDIRFLAGS', '$LINKFLAGS', '$SOURCES', - '-Wl,--start-group', '$_LIBFLAGS', '-Wl,--end-group']], - 'SHLINKCOM': [['$FLOCK_SHLINK', '-o', '$TARGET', - '$_LIBDIRFLAGS', '$SHLINKFLAGS', '$SOURCES', - '-Wl,--start-group', '$_LIBFLAGS', '-Wl,--end-group']], - 'LDMODULECOM': [['$FLOCK_LDMODULE', '-o', '$TARGET', - '$_LIBDIRFLAGS', '$LDMODULEFLAGS', '$SOURCES', - '-Wl,--start-group', '$_LIBFLAGS', '-Wl,--end-group']], - 'IMPLICIT_COMMAND_DEPENDENCIES': 0, - }, - 'scons_import_variables': [ - 'AS', - 'CC', - 'CXX', - 'LINK', - ], - 'scons_propagate_variables': [ - 'AS', - 'CC', - 'CCACHE_DIR', - 'CXX', - 'DISTCC_DIR', - 'DISTCC_HOSTS', - 'HOME', - 'INCLUDE_SERVER_ARGS', - 'INCLUDE_SERVER_PORT', - 'LINK', - 'CHROME_BUILD_TYPE', - 'CHROMIUM_BUILD', - 'OFFICIAL_BUILD', - ], - 'configurations': { - 'Debug_Base': { - 'variables': { - 'debug_optimize%': '0', - }, - 'defines': [ - '_DEBUG', - ], - 'cflags': [ - '-O>(debug_optimize)', - '-g', - # One can use '-gstabs' to enable building the debugging - # information in STABS format for breakpad's dumpsyms. - ], - 'ldflags': [ - '-rdynamic', # Allows backtrace to resolve symbols. - ], - }, - 'Release_Base': { - 'variables': { - 'release_optimize%': '2', - }, - 'cflags': [ - '-O>(release_optimize)', - # Don't emit the GCC version ident directives, they just end up - # in the .comment section taking up binary size. - '-fno-ident', - # Put data and code in their own sections, so that unused symbols - # can be removed at link time with --gc-sections. - '-fdata-sections', - '-ffunction-sections', - ], - 'ldflags': [ - '-Wl,--gc-sections', - ], - }, - }, - 'variants': { - 'coverage': { - 'cflags': ['-fprofile-arcs', '-ftest-coverage'], - 'ldflags': ['-fprofile-arcs'], - }, - 'profile': { - 'cflags': ['-pg', '-g'], - 'ldflags': ['-pg'], - }, - 'symbols': { - 'cflags': ['-g'], - }, - }, - 'conditions': [ - [ 'target_arch=="ia32"', { - 'asflags': [ - # Needed so that libs with .s files (e.g. libicudata.a) - # are compatible with the general 32-bit-ness. - '-32', - ], - # All floating-point computations on x87 happens in 80-bit - # precision. Because the C and C++ language standards allow - # the compiler to keep the floating-point values in higher - # precision than what's specified in the source and doing so - # is more efficient than constantly rounding up to 64-bit or - # 32-bit precision as specified in the source, the compiler, - # especially in the optimized mode, tries very hard to keep - # values in x87 floating-point stack (in 80-bit precision) - # as long as possible. This has important side effects, that - # the real value used in computation may change depending on - # how the compiler did the optimization - that is, the value - # kept in 80-bit is different than the value rounded down to - # 64-bit or 32-bit. There are possible compiler options to make - # this behavior consistent (e.g. -ffloat-store would keep all - # floating-values in the memory, thus force them to be rounded - # to its original precision) but they have significant runtime - # performance penalty. - # - # -mfpmath=sse -msse2 makes the compiler use SSE instructions - # which keep floating-point values in SSE registers in its - # native precision (32-bit for single precision, and 64-bit for - # double precision values). This means the floating-point value - # used during computation does not change depending on how the - # compiler optimized the code, since the value is always kept - # in its specified precision. - 'conditions': [ - ['disable_sse2==0', { - 'cflags': [ - '-march=pentium4', - '-msse2', - '-mfpmath=sse', - ], - }], - ], - # -mmmx allows mmintrin.h to be used for mmx intrinsics. - # video playback is mmx and sse2 optimized. - 'cflags': [ - '-m32', - '-mmmx', - ], - 'ldflags': [ - '-m32', - ], - }], - ['target_arch=="arm"', { - 'target_conditions': [ - ['_toolset=="target"', { - 'cflags_cc': [ - # The codesourcery arm-2009q3 toolchain warns at that the ABI - # has changed whenever it encounters a varargs function. This - # silences those warnings, as they are not helpful and - # clutter legitimate warnings. - '-Wno-abi', - ], - 'conditions': [ - ['arm_thumb == 1', { - 'cflags': [ - '-mthumb', - # TODO(piman): -Wa,-mimplicit-it=thumb is needed for - # inline assembly that uses condition codes but it's - # suboptimal. Better would be to #ifdef __thumb__ at the - # right place and have a separate thumb path. - '-Wa,-mimplicit-it=thumb', - ] - }], - ['arm_version==7', { - 'cflags': [ - '-march=armv7-a', - '-mtune=cortex-a8', - '-mfloat-abi=softfp', - ], - 'conditions': [ - ['arm_neon==1', { - 'cflags': [ '-mfpu=neon', ], - }, { - 'cflags': [ '-mfpu=<(arm_fpu)', ], - }] - ], - }], - ], - }], - ], - }], - ['linux_fpic==1', { - 'cflags': [ - '-fPIC', - ], - }], - ['sysroot!=""', { - 'target_conditions': [ - ['_toolset=="target"', { - 'cflags': [ - '--sysroot=<(sysroot)', - ], - 'ldflags': [ - '--sysroot=<(sysroot)', - ], - }]] - }], - ['no_strict_aliasing==1', { - 'cflags': [ - '-fno-strict-aliasing', - ], - }], - ['linux_use_heapchecker==1', { - 'variables': {'linux_use_tcmalloc%': 1}, - }], - ['linux_use_tcmalloc==0', { - 'defines': ['NO_TCMALLOC'], - }], - ['linux_use_heapchecker==0', { - 'defines': ['NO_HEAPCHECKER'], - }], - ], - }, - }], - # FreeBSD-specific options; note that most FreeBSD options are set above, - # with Linux. - ['OS=="freebsd"', { - 'target_defaults': { - 'ldflags': [ - '-Wl,--no-keep-memory', - ], - }, - }], - ['OS=="solaris"', { - 'cflags!': ['-fvisibility=hidden'], - 'cflags_cc!': ['-fvisibility-inlines-hidden'], - }], - ['OS=="mac"', { - 'target_defaults': { - 'variables': { - # This should be 'mac_real_dsym%', but there seems to be a bug - # with % in variables that are intended to be set to different - # values in different targets, like this one. - 'mac_real_dsym': 0, # Fake .dSYMs are fine in most cases. - }, - 'mac_bundle': 0, - 'xcode_settings': { - 'ALWAYS_SEARCH_USER_PATHS': 'NO', - 'GCC_C_LANGUAGE_STANDARD': 'c99', # -std=c99 - 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks - 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic - # (Equivalent to -fPIC) - 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions - 'GCC_ENABLE_CPP_RTTI': 'YES', # -frtti - 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings - # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden - 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES', - 'GCC_OBJC_CALL_CXX_CDTORS': 'YES', # -fobjc-call-cxx-cdtors - 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics - 'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', # -Werror - 'GCC_VERSION': '4.2', - 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof - # MACOSX_DEPLOYMENT_TARGET maps to -mmacosx-version-min - 'MACOSX_DEPLOYMENT_TARGET': '<(mac_deployment_target)', - 'PREBINDING': 'NO', # No -Wl,-prebind - 'USE_HEADERMAP': 'NO', - 'WARNING_CFLAGS': ['-Wall', '-Wendif-labels'], - 'conditions': [ - ['chromium_mac_pch', {'GCC_PRECOMPILE_PREFIX_HEADER': 'YES'}, - {'GCC_PRECOMPILE_PREFIX_HEADER': 'NO'} - ], - ], - }, - 'target_conditions': [ - ['_type!="static_library"', { - 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']}, - }], - ['_mac_bundle', { - 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-ObjC']}, - }], - ], # target_conditions - }, # target_defaults - }], # OS=="mac" - ['OS=="win"', { - 'target_defaults': { - 'defines': [ - '_WIN32_WINNT=0x0600', - 'WINVER=0x0600', - 'WIN32', - '_WINDOWS', - '_HAS_EXCEPTIONS=0', - 'NOMINMAX', - '_CRT_RAND_S', - 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS', - 'WIN32_LEAN_AND_MEAN', - '_SECURE_ATL', - '_HAS_TR1=0', - ], - 'msvs_system_include_dirs': [ - '<(DEPTH)/third_party/platformsdk_win7/files/Include', - '$(VSInstallDir)/VC/atlmfc/include', - ], - 'msvs_cygwin_dirs': ['<(DEPTH)/third_party/cygwin'], - 'msvs_disabled_warnings': [ - 4100, 4127, 4396, 4503, 4512, 4819, 4995, 4702 - ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'MinimalRebuild': 'false', - 'ExceptionHandling': '0', - 'BufferSecurityCheck': 'true', - 'EnableFunctionLevelLinking': 'true', - 'RuntimeTypeInfo': 'false', - 'WarningLevel': '4', - 'WarnAsError': 'true', - 'DebugInformationFormat': '3', - 'conditions': [ - [ 'msvs_multi_core_compile', { - 'AdditionalOptions': ['/MP'], - }], - ], - }, - 'VCLibrarianTool': { - 'AdditionalOptions': ['/ignore:4221'], - 'AdditionalLibraryDirectories': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib'], - }, - 'VCLinkerTool': { - 'AdditionalDependencies': [ - 'wininet.lib', - 'version.lib', - 'msimg32.lib', - 'ws2_32.lib', - 'usp10.lib', - 'psapi.lib', - 'dbghelp.lib', - ], - 'AdditionalLibraryDirectories': - ['<(DEPTH)/third_party/platformsdk_win7/files/Lib'], - 'GenerateDebugInformation': 'true', - 'MapFileName': '$(OutDir)\\$(TargetName).map', - 'ImportLibrary': '$(OutDir)\\lib\\$(TargetName).lib', - 'FixedBaseAddress': '1', - # SubSystem values: - # 0 == not set - # 1 == /SUBSYSTEM:CONSOLE - # 2 == /SUBSYSTEM:WINDOWS - # Most of the executables we'll ever create are tests - # and utilities with console output. - 'SubSystem': '1', - }, - 'VCMIDLTool': { - 'GenerateStublessProxies': 'true', - 'TypeLibraryName': '$(InputName).tlb', - 'OutputDirectory': '$(IntDir)', - 'HeaderFileName': '$(InputName).h', - 'DLLDataFileName': 'dlldata.c', - 'InterfaceIdentifierFileName': '$(InputName)_i.c', - 'ProxyFileName': '$(InputName)_p.c', - }, - 'VCResourceCompilerTool': { - 'Culture' : '1033', - 'AdditionalIncludeDirectories': ['<(DEPTH)'], - }, - }, - }, - }], - ['disable_nacl==1 or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { - 'target_defaults': { - 'defines': [ - 'DISABLE_NACL', - ], - }, - }], - ['OS=="win" and msvs_use_common_linker_extras', { - 'target_defaults': { - 'msvs_settings': { - 'VCLinkerTool': { - 'DelayLoadDLLs': [ - 'dbghelp.dll', - 'dwmapi.dll', - 'uxtheme.dll', - ], - }, - }, - 'configurations': { - 'x86_Base': { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalOptions': [ - '/safeseh', - '/dynamicbase', - '/ignore:4199', - '/ignore:4221', - '/nxcompat', - ], - }, - }, - }, - 'x64_Base': { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalOptions': [ - # safeseh is not compatible with x64 - '/dynamicbase', - '/ignore:4199', - '/ignore:4221', - '/nxcompat', - ], - }, - }, - }, - }, - }, - }], - ['enable_new_npdevice_api==1', { - 'target_defaults': { - 'defines': [ - 'ENABLE_NEW_NPDEVICE_API', - ], - }, - }], - ], - 'scons_settings': { - 'sconsbuild_dir': '<(DEPTH)/sconsbuild', - 'tools': ['ar', 'as', 'gcc', 'g++', 'gnulink', 'chromium_builders'], - }, - 'xcode_settings': { - # DON'T ADD ANYTHING NEW TO THIS BLOCK UNLESS YOU REALLY REALLY NEED IT! - # This block adds *project-wide* configuration settings to each project - # file. It's almost always wrong to put things here. Specify your - # custom xcode_settings in target_defaults to add them to targets instead. - - # In an Xcode Project Info window, the "Base SDK for All Configurations" - # setting sets the SDK on a project-wide basis. In order to get the - # configured SDK to show properly in the Xcode UI, SDKROOT must be set - # here at the project level. - 'SDKROOT': 'macosx<(mac_sdk)', # -isysroot - - # The Xcode generator will look for an xcode_settings section at the root - # of each dict and use it to apply settings on a file-wide basis. Most - # settings should not be here, they should be in target-specific - # xcode_settings sections, or better yet, should use non-Xcode-specific - # settings in target dicts. SYMROOT is a special case, because many other - # Xcode variables depend on it, including variables such as - # PROJECT_DERIVED_FILE_DIR. When a source group corresponding to something - # like PROJECT_DERIVED_FILE_DIR is added to a project, in order for the - # files to appear (when present) in the UI as actual files and not red - # red "missing file" proxies, the correct path to PROJECT_DERIVED_FILE_DIR, - # and therefore SYMROOT, needs to be set at the project level. - 'SYMROOT': '<(DEPTH)/xcodebuild', - }, -} diff --git a/toolkit/crashreporter/google-breakpad/src/build/filename_rules.gypi b/toolkit/crashreporter/google-breakpad/src/build/filename_rules.gypi deleted file mode 100644 index 78cd1808a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/build/filename_rules.gypi +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'target_conditions': [ - ['OS!="win"', { - 'sources/': [ - ['exclude', '(^|/)windows/'], - ], - }], - ['OS!="linux"', { - 'sources/': [ - ['exclude', '(^|/)linux/'], - ], - }], - ['OS!="mac"', { - 'sources/': [ - ['exclude', '(^|/)mac/'], - ], - }], - ['OS!="android"', { - 'sources/': [ - ['exclude', '(^|/)android/'], - ], - }], - ['OS!="solaris"', { - 'sources/': [ - ['exclude', '(^|/)solaris/'], - ], - }], - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/build/gyp_breakpad b/toolkit/crashreporter/google-breakpad/src/build/gyp_breakpad deleted file mode 100755 index 0b8077d2f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/build/gyp_breakpad +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import os -import platform -import sys - -script_dir = os.path.dirname(os.path.realpath(__file__)) -breakpad_root = os.path.abspath(os.path.join(script_dir, os.pardir)) - -sys.path.insert(0, os.path.join(breakpad_root, 'tools', 'gyp', 'pylib')) -import gyp - -def run_gyp(args): - rc = gyp.main(args) - if rc != 0: - print 'Error running GYP' - sys.exit(rc) - - -def main(): - args = sys.argv[1:] - args.append(os.path.join(script_dir, 'all.gyp')) - - args.append('-I') - args.append(os.path.join(breakpad_root, 'build', 'common.gypi')) - - args.extend(['-D', 'gyp_output_dir=out']) - - # Set the GYP DEPTH variable to the root of the project. - args.append('--depth=' + os.path.relpath(breakpad_root)) - - print 'Updating projects from gyp files...' - sys.stdout.flush() - - run_gyp(args) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/toolkit/crashreporter/google-breakpad/src/build/testing.gypi b/toolkit/crashreporter/google-breakpad/src/build/testing.gypi deleted file mode 100644 index 3a77230a5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/build/testing.gypi +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'targets': [ - { - 'target_name': 'gtest', - 'type': 'static_library', - 'sources': [ - '../testing/gtest/src/gtest-all.cc', - ], - 'include_dirs': [ - '../testing/gtest', - '../testing/gtest/include', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../testing/gtest/include', - ], - }, - }, - { - 'target_name': 'gtest_main', - 'type': 'static_library', - 'dependencies': [ - 'gtest', - ], - 'sources': [ - 'gtest/src/gtest_main.cc', - ], - }, - { - 'target_name': 'gmock', - 'type': 'static_library', - 'dependencies': [ - 'gtest', - ], - 'sources': [ - '../testing/src/gmock-all.cc', - ], - 'include_dirs': [ - '../testing', - '../testing/include', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../testing/include', - ], - }, - 'export_dependent_settings': [ - 'gtest', - ], - }, - { - 'target_name': 'gmock_main', - 'type': 'static_library', - 'dependencies': [ - 'gmock', - ], - 'sources': [ - '../testing/src/gmock_main.cc', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/apple/Framework/BreakpadDefines.h b/toolkit/crashreporter/google-breakpad/src/client/apple/Framework/BreakpadDefines.h deleted file mode 100644 index 410a5a6f3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/apple/Framework/BreakpadDefines.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Keys for configuration file -#define kReporterMinidumpDirectoryKey "MinidumpDir" -#define kReporterMinidumpIDKey "MinidumpID" - -// Filename for recording uploaded IDs -#define kReporterLogFilename "uploads.log" - -// The default subdirectory of the Library to put crash dumps in -// The subdirectory is -// ~/Library// -#define kDefaultLibrarySubdirectory "Breakpad" - -// Specify some special keys to be used in the configuration file that is -// generated by Breakpad and consumed by the crash_sender. -#define BREAKPAD_PRODUCT "BreakpadProduct" -#define BREAKPAD_PRODUCT_DISPLAY "BreakpadProductDisplay" -#define BREAKPAD_VERSION "BreakpadVersion" -#define BREAKPAD_VENDOR "BreakpadVendor" -#define BREAKPAD_URL "BreakpadURL" -#define BREAKPAD_REPORT_INTERVAL "BreakpadReportInterval" -#define BREAKPAD_SKIP_CONFIRM "BreakpadSkipConfirm" -#define BREAKPAD_CONFIRM_TIMEOUT "BreakpadConfirmTimeout" -#define BREAKPAD_SEND_AND_EXIT "BreakpadSendAndExit" -#define BREAKPAD_DUMP_DIRECTORY "BreakpadMinidumpLocation" -#define BREAKPAD_INSPECTOR_LOCATION "BreakpadInspectorLocation" -#define BREAKPAD_REPORTER_EXE_LOCATION \ - "BreakpadReporterExeLocation" -#define BREAKPAD_LOGFILES "BreakpadLogFiles" -#define BREAKPAD_LOGFILE_UPLOAD_SIZE "BreakpadLogFileTailSize" -#define BREAKPAD_REQUEST_COMMENTS "BreakpadRequestComments" -#define BREAKPAD_COMMENTS "BreakpadComments" -#define BREAKPAD_REQUEST_EMAIL "BreakpadRequestEmail" -#define BREAKPAD_EMAIL "BreakpadEmail" -#define BREAKPAD_SERVER_TYPE "BreakpadServerType" -#define BREAKPAD_SERVER_PARAMETER_DICT "BreakpadServerParameters" -#define BREAKPAD_IN_PROCESS "BreakpadInProcess" - -// The keys below are NOT user supplied, and are used internally. -#define BREAKPAD_PROCESS_START_TIME "BreakpadProcStartTime" -#define BREAKPAD_PROCESS_UP_TIME "BreakpadProcessUpTime" -#define BREAKPAD_PROCESS_CRASH_TIME "BreakpadProcessCrashTime" -#define BREAKPAD_LOGFILE_KEY_PREFIX "BreakpadAppLogFile" -#define BREAKPAD_SERVER_PARAMETER_PREFIX "BreakpadServerParameterPrefix_" -#define BREAKPAD_ON_DEMAND "BreakpadOnDemand" diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.h b/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.h deleted file mode 100644 index c099ad07c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.h +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Framework to provide a simple C API to crash reporting for -// applications. By default, if any machine-level exception (e.g., -// EXC_BAD_ACCESS) occurs, it will be handled by the BreakpadRef -// object as follows: -// -// 1. Create a minidump file (see Breakpad for details) -// 2. Create a config file. -// -// These files can then be uploaded to a server. - -typedef void *BreakpadRef; - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -// The keys in the dictionary returned by |BreakpadGenerateReport|. -#define BREAKPAD_OUTPUT_DUMP_FILE "BreakpadDumpFile" -#define BREAKPAD_OUTPUT_CONFIG_FILE "BreakpadConfigFile" - -// Optional user-defined function to decide if we should handle this crash or -// forward it along. -// Return true if you want Breakpad to handle it. -// Return false if you want Breakpad to skip it -// The exception handler always returns false, as if SEND_AND_EXIT were false -// (which means the next exception handler will take the exception) -typedef bool (*BreakpadFilterCallback)(int exception_type, - int exception_code, - mach_port_t crashing_thread, - void *context); - -// Create a new BreakpadRef object and install it as an exception -// handler. The |parameters| will typically be the contents of your -// bundle's Info.plist. -// -// You can also specify these additional keys for customizable behavior: -// Key: Value: -// BREAKPAD_PRODUCT Product name (e.g., "MyAwesomeProduct") -// This one is used as the key to identify -// the product when uploading. Falls back to -// CFBundleName if not specified. -// REQUIRED -// -// BREAKPAD_PRODUCT_DISPLAY This is the display name, e.g. a pretty -// name for the product when the crash_sender -// pops up UI for the user. Falls back first to -// CFBundleDisplayName and then to -// BREAKPAD_PRODUCT if not specified. -// -// BREAKPAD_VERSION Product version (e.g., 1.2.3), used -// as metadata for crash report. Falls back to -// CFBundleVersion if not specified. -// REQUIRED -// -// BREAKPAD_VENDOR Vendor name, used in UI (e.g. "A report has -// been created that you can send to ") -// -// BREAKPAD_URL URL destination for reporting -// REQUIRED -// -// BREAKPAD_DUMP_DIRECTORY The directory to store crash-dumps -// in. By default, we use -// ~/Library/Cache/Breakpad/ -// The path you specify here is tilde-expanded. -// -// BREAKPAD_SERVER_TYPE A parameter that tells Breakpad how to -// rewrite the upload parameters for a specific -// server type. The currently valid values are -// 'socorro' or 'google'. If you want to add -// other types, see the function in -// crash_report_sender.m that maps parameters to -// URL parameters. Defaults to 'google'. -// -// BREAKPAD_SERVER_PARAMETER_DICT A plist dictionary of static -// parameters that are uploaded to the -// server. The parameters are sent as -// is to the crash server. Their -// content isn't added to the minidump -// but pass as URL parameters when -// uploading theminidump to the crash -// server. -//============================================================================= -// The BREAKPAD_PRODUCT, BREAKPAD_VERSION and BREAKPAD_URL are -// required to have non-NULL values. By default, the BREAKPAD_PRODUCT -// will be the CFBundleName and the BREAKPAD_VERSION will be the -// CFBundleVersion when these keys are present in the bundle's -// Info.plist, which is usually passed in to BreakpadCreate() as an -// NSDictionary (you could also pass in another dictionary that had -// the same keys configured). If the BREAKPAD_PRODUCT or -// BREAKPAD_VERSION are ultimately undefined, BreakpadCreate() will -// fail. You have been warned. -// -// If you are running in a debugger, Breakpad will not install, unless the -// BREAKPAD_IGNORE_DEBUGGER envionment variable is set and/or non-zero. -// -//============================================================================= -// The following are NOT user-supplied but are documented here for -// completeness. They are calculated by Breakpad during initialization & -// crash-dump generation, or entered in by the user. -// -// BREAKPAD_PROCESS_START_TIME The time, in seconds since the Epoch, the -// process started -// -// BREAKPAD_PROCESS_CRASH_TIME The time, in seconds since the Epoch, the -// process crashed. -// -// BREAKPAD_PROCESS_UP_TIME The total time in milliseconds the process -// has been running. This parameter is not -// set until the crash-dump-generation phase. -// -// BREAKPAD_SERVER_PARAMETER_PREFIX This prefix is used by Breakpad -// internally, because Breakpad uses -// the same dictionary internally to -// track both its internal -// configuration parameters and -// parameters meant to be uploaded -// to the server. This string is -// used internally by Breakpad to -// prefix user-supplied parameter -// names so those can be sent to the -// server without leaking Breakpad's -// internal values. - -// Returns a new BreakpadRef object on success, NULL otherwise. -BreakpadRef BreakpadCreate(NSDictionary *parameters); - -// Uninstall and release the data associated with |ref|. -void BreakpadRelease(BreakpadRef ref); - -// User defined key and value string storage. Generally this is used -// to configure Breakpad's internal operation, such as whether the -// crash_sender should prompt the user, or the filesystem location for -// the minidump file. See Breakpad.h for some parameters that can be -// set. Anything longer than 255 bytes will be truncated. Note that -// the string is converted to UTF8 before truncation, so any multibyte -// character that straddles the 255(256 - 1 for terminator) byte limit -// will be mangled. -// -// A maximum number of 64 key/value pairs are supported. An assert() -// will fire if more than this number are set. Unfortunately, right -// now, the same dictionary is used for both Breakpad's parameters AND -// the Upload parameters. -// -// TODO (nealsid): Investigate how necessary this is if we don't -// automatically upload parameters to the server anymore. -// TODO (nealsid): separate server parameter dictionary from the -// dictionary used to configure Breakpad, and document limits for each -// independently. -void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value); -NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key); -void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key); - -// You can use this method to specify parameters that will be uploaded -// to the crash server. They will be automatically encoded as -// necessary. Note that as mentioned above there are limits on both -// the number of keys and their length. -void BreakpadAddUploadParameter(BreakpadRef ref, NSString *key, - NSString *value); - -// This method will remove a previously-added parameter from the -// upload parameter set. -void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key); - -// Method to handle uploading data to the server - -// Returns the number of crash reports waiting to send to the server. -int BreakpadGetCrashReportCount(BreakpadRef ref); - -// Returns the next upload configuration. The report file is deleted. -NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref); - -// Upload next report to the server. -void BreakpadUploadNextReport(BreakpadRef ref); - -// Upload next report to the server. -// |server_parameters| is additional server parameters to send. -void BreakpadUploadNextReportWithParameters(BreakpadRef ref, - NSDictionary *server_parameters); - -// Upload a report to the server. -// |server_parameters| is additional server parameters to send. -// |configuration| is the configuration of the breakpad report to send. -void BreakpadUploadReportWithParametersAndConfiguration( - BreakpadRef ref, - NSDictionary *server_parameters, - NSDictionary *configuration); - -// Handles the network response of a breakpad upload. This function is needed if -// the actual upload is done by the Breakpad client. -// |configuration| is the configuration of the upload. It must contain the same -// fields as the configuration passed to -// BreakpadUploadReportWithParametersAndConfiguration. -// |data| and |error| contain the network response. -void BreakpadHandleNetworkResponse(BreakpadRef ref, - NSDictionary *configuration, - NSData *data, - NSError *error); - -// Upload a file to the server. |data| is the content of the file to sent. -// |server_parameters| is additional server parameters to send. -void BreakpadUploadData(BreakpadRef ref, NSData *data, NSString *name, - NSDictionary *server_parameters); - -// Generate a breakpad minidump and configuration file in the dump directory. -// The report will be available for uploading. The paths of the created files -// are returned in the dictionary. |server_parameters| is additional server -// parameters to add in the config file. -NSDictionary *BreakpadGenerateReport(BreakpadRef ref, - NSDictionary *server_parameters); - -#ifdef __cplusplus -} -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.mm b/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.mm deleted file mode 100644 index ce635bd27..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.mm +++ /dev/null @@ -1,916 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#define IGNORE_DEBUGGER "BREAKPAD_IGNORE_DEBUGGER" - -#import "client/ios/Breakpad.h" - -#include -#import -#include -#include -#include - -#import "client/ios/handler/ios_exception_minidump_generator.h" -#import "client/mac/crash_generation/ConfigFile.h" -#import "client/mac/handler/exception_handler.h" -#import "client/mac/handler/minidump_generator.h" -#import "client/mac/sender/uploader.h" -#import "client/mac/handler/protected_memory_allocator.h" -#import "common/simple_string_dictionary.h" - -#if !defined(__EXCEPTIONS) || (__clang__ && !__has_feature(cxx_exceptions)) -// This file uses C++ try/catch (but shouldn't). Duplicate the macros from -// allowing this file to work properly with -// exceptions disabled even when other C++ libraries are used. #undef the try -// and catch macros first in case libstdc++ is in use and has already provided -// its own definitions. -#undef try -#define try if (true) -#undef catch -#define catch(X) if (false) -#endif // __EXCEPTIONS - -using google_breakpad::ConfigFile; -using google_breakpad::EnsureDirectoryPathExists; -using google_breakpad::SimpleStringDictionary; - -//============================================================================= -// We want any memory allocations which are used by breakpad during the -// exception handling process (after a crash has happened) to be read-only -// to prevent them from being smashed before a crash occurs. Unfortunately -// we cannot protect against smashes to our exception handling thread's -// stack. -// -// NOTE: Any memory allocations which are not used during the exception -// handling process may be allocated in the normal ways. -// -// The ProtectedMemoryAllocator class provides an Allocate() method which -// we'll using in conjunction with placement operator new() to control -// allocation of C++ objects. Note that we don't use operator delete() -// but instead call the objects destructor directly: object->~ClassName(); -// -ProtectedMemoryAllocator *gMasterAllocator = NULL; -ProtectedMemoryAllocator *gKeyValueAllocator = NULL; -ProtectedMemoryAllocator *gBreakpadAllocator = NULL; - -// Mutex for thread-safe access to the key/value dictionary used by breakpad. -// It's a global instead of an instance variable of Breakpad -// since it can't live in a protected memory area. -pthread_mutex_t gDictionaryMutex; - -//============================================================================= -// Stack-based object for thread-safe access to a memory-protected region. -// It's assumed that normally the memory block (allocated by the allocator) -// is protected (read-only). Creating a stack-based instance of -// ProtectedMemoryLocker will unprotect this block after taking the lock. -// Its destructor will first re-protect the memory then release the lock. -class ProtectedMemoryLocker { - public: - ProtectedMemoryLocker(pthread_mutex_t *mutex, - ProtectedMemoryAllocator *allocator) - : mutex_(mutex), - allocator_(allocator) { - // Lock the mutex - __attribute__((unused)) int rv = pthread_mutex_lock(mutex_); - assert(rv == 0); - - // Unprotect the memory - allocator_->Unprotect(); - } - - ~ProtectedMemoryLocker() { - // First protect the memory - allocator_->Protect(); - - // Then unlock the mutex - __attribute__((unused)) int rv = pthread_mutex_unlock(mutex_); - assert(rv == 0); - }; - - private: - ProtectedMemoryLocker(); - ProtectedMemoryLocker(const ProtectedMemoryLocker&); - ProtectedMemoryLocker& operator=(const ProtectedMemoryLocker&); - - pthread_mutex_t *mutex_; - ProtectedMemoryAllocator *allocator_; -}; - -//============================================================================= -class Breakpad { - public: - // factory method - static Breakpad *Create(NSDictionary *parameters) { - // Allocate from our special allocation pool - Breakpad *breakpad = - new (gBreakpadAllocator->Allocate(sizeof(Breakpad))) - Breakpad(); - - if (!breakpad) - return NULL; - - if (!breakpad->Initialize(parameters)) { - // Don't use operator delete() here since we allocated from special pool - breakpad->~Breakpad(); - return NULL; - } - - return breakpad; - } - - ~Breakpad(); - - void SetKeyValue(NSString *key, NSString *value); - NSString *KeyValue(NSString *key); - void RemoveKeyValue(NSString *key); - NSArray *CrashReportsToUpload(); - NSString *NextCrashReportToUpload(); - NSDictionary *NextCrashReportConfiguration(); - void UploadNextReport(NSDictionary *server_parameters); - void UploadReportWithConfiguration(NSDictionary *configuration, - NSDictionary *server_parameters); - void UploadData(NSData *data, NSString *name, - NSDictionary *server_parameters); - void HandleNetworkResponse(NSDictionary *configuration, - NSData *data, - NSError *error); - NSDictionary *GenerateReport(NSDictionary *server_parameters); - - private: - Breakpad() - : handler_(NULL), - config_params_(NULL) {} - - bool Initialize(NSDictionary *parameters); - - bool ExtractParameters(NSDictionary *parameters); - - // Dispatches to HandleMinidump() - static bool HandleMinidumpCallback(const char *dump_dir, - const char *minidump_id, - void *context, bool succeeded); - - bool HandleMinidump(const char *dump_dir, - const char *minidump_id); - - // NSException handler - static void UncaughtExceptionHandler(NSException *exception); - - // Handle an uncaught NSException. - void HandleUncaughtException(NSException *exception); - - // Since ExceptionHandler (w/o namespace) is defined as typedef in OSX's - // MachineExceptions.h, we have to explicitly name the handler. - google_breakpad::ExceptionHandler *handler_; // The actual handler (STRONG) - - SimpleStringDictionary *config_params_; // Create parameters (STRONG) - - ConfigFile config_file_; - - // A static reference to the current Breakpad instance. Used for handling - // NSException. - static Breakpad *current_breakpad_; -}; - -Breakpad *Breakpad::current_breakpad_ = NULL; - -#pragma mark - -#pragma mark Helper functions - -//============================================================================= -// Helper functions - -//============================================================================= -static BOOL IsDebuggerActive() { - BOOL result = NO; - NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults]; - - // We check both defaults and the environment variable here - - BOOL ignoreDebugger = [stdDefaults boolForKey:@IGNORE_DEBUGGER]; - - if (!ignoreDebugger) { - char *ignoreDebuggerStr = getenv(IGNORE_DEBUGGER); - ignoreDebugger = - (ignoreDebuggerStr ? strtol(ignoreDebuggerStr, NULL, 10) : 0) != 0; - } - - if (!ignoreDebugger) { - pid_t pid = getpid(); - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - int mibSize = sizeof(mib) / sizeof(int); - size_t actualSize; - - if (sysctl(mib, mibSize, NULL, &actualSize, NULL, 0) == 0) { - struct kinfo_proc *info = (struct kinfo_proc *)malloc(actualSize); - - if (info) { - // This comes from looking at the Darwin xnu Kernel - if (sysctl(mib, mibSize, info, &actualSize, NULL, 0) == 0) - result = (info->kp_proc.p_flag & P_TRACED) ? YES : NO; - - free(info); - } - } - } - - return result; -} - -//============================================================================= -bool Breakpad::HandleMinidumpCallback(const char *dump_dir, - const char *minidump_id, - void *context, bool succeeded) { - Breakpad *breakpad = (Breakpad *)context; - - // If our context is damaged or something, just return false to indicate that - // the handler should continue without us. - if (!breakpad || !succeeded) - return false; - - return breakpad->HandleMinidump(dump_dir, minidump_id); -} - -//============================================================================= -void Breakpad::UncaughtExceptionHandler(NSException *exception) { - NSSetUncaughtExceptionHandler(NULL); - if (current_breakpad_) { - current_breakpad_->HandleUncaughtException(exception); - BreakpadRelease(current_breakpad_); - } -} - -//============================================================================= -#pragma mark - - -//============================================================================= -bool Breakpad::Initialize(NSDictionary *parameters) { - // Initialize - current_breakpad_ = this; - config_params_ = NULL; - handler_ = NULL; - - // Gather any user specified parameters - if (!ExtractParameters(parameters)) { - return false; - } - - // Check for debugger - if (IsDebuggerActive()) { - return true; - } - - // Create the handler (allocating it in our special protected pool) - handler_ = - new (gBreakpadAllocator->Allocate( - sizeof(google_breakpad::ExceptionHandler))) - google_breakpad::ExceptionHandler( - config_params_->GetValueForKey(BREAKPAD_DUMP_DIRECTORY), - 0, &HandleMinidumpCallback, this, true, 0); - NSSetUncaughtExceptionHandler(&Breakpad::UncaughtExceptionHandler); - return true; -} - -//============================================================================= -Breakpad::~Breakpad() { - NSSetUncaughtExceptionHandler(NULL); - current_breakpad_ = NULL; - // Note that we don't use operator delete() on these pointers, - // since they were allocated by ProtectedMemoryAllocator objects. - // - if (config_params_) { - config_params_->~SimpleStringDictionary(); - } - - if (handler_) - handler_->~ExceptionHandler(); -} - -//============================================================================= -bool Breakpad::ExtractParameters(NSDictionary *parameters) { - NSString *serverType = [parameters objectForKey:@BREAKPAD_SERVER_TYPE]; - NSString *display = [parameters objectForKey:@BREAKPAD_PRODUCT_DISPLAY]; - NSString *product = [parameters objectForKey:@BREAKPAD_PRODUCT]; - NSString *version = [parameters objectForKey:@BREAKPAD_VERSION]; - NSString *urlStr = [parameters objectForKey:@BREAKPAD_URL]; - NSString *vendor = - [parameters objectForKey:@BREAKPAD_VENDOR]; - // We check both parameters and the environment variable here. - char *envVarDumpSubdirectory = getenv(BREAKPAD_DUMP_DIRECTORY); - NSString *dumpSubdirectory = envVarDumpSubdirectory ? - [NSString stringWithUTF8String:envVarDumpSubdirectory] : - [parameters objectForKey:@BREAKPAD_DUMP_DIRECTORY]; - - NSDictionary *serverParameters = - [parameters objectForKey:@BREAKPAD_SERVER_PARAMETER_DICT]; - - if (!product) - product = [parameters objectForKey:@"CFBundleName"]; - - if (!display) { - display = [parameters objectForKey:@"CFBundleDisplayName"]; - if (!display) { - display = product; - } - } - - if (!version.length) // Default nil or empty string to CFBundleVersion - version = [parameters objectForKey:@"CFBundleVersion"]; - - if (!vendor) { - vendor = @"Vendor not specified"; - } - - if (!dumpSubdirectory) { - NSString *cachePath = - [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, - NSUserDomainMask, - YES) - objectAtIndex:0]; - dumpSubdirectory = - [cachePath stringByAppendingPathComponent:@kDefaultLibrarySubdirectory]; - - EnsureDirectoryPathExists(dumpSubdirectory); - } - - // The product, version, and URL are required values. - if (![product length]) { - return false; - } - - if (![version length]) { - return false; - } - - if (![urlStr length]) { - return false; - } - - config_params_ = - new (gKeyValueAllocator->Allocate(sizeof(SimpleStringDictionary)) ) - SimpleStringDictionary(); - - SimpleStringDictionary &dictionary = *config_params_; - - dictionary.SetKeyValue(BREAKPAD_SERVER_TYPE, [serverType UTF8String]); - dictionary.SetKeyValue(BREAKPAD_PRODUCT_DISPLAY, [display UTF8String]); - dictionary.SetKeyValue(BREAKPAD_PRODUCT, [product UTF8String]); - dictionary.SetKeyValue(BREAKPAD_VERSION, [version UTF8String]); - dictionary.SetKeyValue(BREAKPAD_URL, [urlStr UTF8String]); - dictionary.SetKeyValue(BREAKPAD_VENDOR, [vendor UTF8String]); - dictionary.SetKeyValue(BREAKPAD_DUMP_DIRECTORY, - [dumpSubdirectory UTF8String]); - - struct timeval tv; - gettimeofday(&tv, NULL); - char timeStartedString[32]; - sprintf(timeStartedString, "%zd", tv.tv_sec); - dictionary.SetKeyValue(BREAKPAD_PROCESS_START_TIME, timeStartedString); - - if (serverParameters) { - // For each key-value pair, call BreakpadAddUploadParameter() - NSEnumerator *keyEnumerator = [serverParameters keyEnumerator]; - NSString *aParameter; - while ((aParameter = [keyEnumerator nextObject])) { - BreakpadAddUploadParameter(this, aParameter, - [serverParameters objectForKey:aParameter]); - } - } - return true; -} - -//============================================================================= -void Breakpad::SetKeyValue(NSString *key, NSString *value) { - // We allow nil values. This is the same as removing the keyvalue. - if (!config_params_ || !key) - return; - - config_params_->SetKeyValue([key UTF8String], [value UTF8String]); -} - -//============================================================================= -NSString *Breakpad::KeyValue(NSString *key) { - if (!config_params_ || !key) - return nil; - - const char *value = config_params_->GetValueForKey([key UTF8String]); - return value ? [NSString stringWithUTF8String:value] : nil; -} - -//============================================================================= -void Breakpad::RemoveKeyValue(NSString *key) { - if (!config_params_ || !key) return; - - config_params_->RemoveKey([key UTF8String]); -} - -//============================================================================= -NSArray *Breakpad::CrashReportsToUpload() { - NSString *directory = KeyValue(@BREAKPAD_DUMP_DIRECTORY); - if (!directory) - return nil; - NSArray *dirContents = [[NSFileManager defaultManager] - contentsOfDirectoryAtPath:directory error:nil]; - NSArray *configs = [dirContents filteredArrayUsingPredicate:[NSPredicate - predicateWithFormat:@"self BEGINSWITH 'Config-'"]]; - return configs; -} - -//============================================================================= -NSString *Breakpad::NextCrashReportToUpload() { - NSString *directory = KeyValue(@BREAKPAD_DUMP_DIRECTORY); - if (!directory) - return nil; - NSString *config = [CrashReportsToUpload() lastObject]; - if (!config) - return nil; - return [NSString stringWithFormat:@"%@/%@", directory, config]; -} - -//============================================================================= -NSDictionary *Breakpad::NextCrashReportConfiguration() { - return [Uploader readConfigurationDataFromFile:NextCrashReportToUpload()]; -} - -//============================================================================= -void Breakpad::HandleNetworkResponse(NSDictionary *configuration, - NSData *data, - NSError *error) { - Uploader *uploader = [[[Uploader alloc] - initWithConfig:configuration] autorelease]; - [uploader handleNetworkResponse:data withError:error]; -} - -//============================================================================= -void Breakpad::UploadReportWithConfiguration(NSDictionary *configuration, - NSDictionary *server_parameters) { - Uploader *uploader = [[[Uploader alloc] - initWithConfig:configuration] autorelease]; - if (!uploader) - return; - for (NSString *key in server_parameters) { - [uploader addServerParameter:[server_parameters objectForKey:key] - forKey:key]; - } - [uploader report]; -} - -//============================================================================= -void Breakpad::UploadNextReport(NSDictionary *server_parameters) { - NSDictionary *configuration = NextCrashReportConfiguration(); - if (configuration) { - return UploadReportWithConfiguration(configuration, server_parameters); - } -} - -//============================================================================= -void Breakpad::UploadData(NSData *data, NSString *name, - NSDictionary *server_parameters) { - NSMutableDictionary *config = [NSMutableDictionary dictionary]; - - SimpleStringDictionary::Iterator it(*config_params_); - while (const SimpleStringDictionary::Entry *next = it.Next()) { - [config setValue:[NSString stringWithUTF8String:next->value] - forKey:[NSString stringWithUTF8String:next->key]]; - } - - Uploader *uploader = - [[[Uploader alloc] initWithConfig:config] autorelease]; - for (NSString *key in server_parameters) { - [uploader addServerParameter:[server_parameters objectForKey:key] - forKey:key]; - } - [uploader uploadData:data name:name]; -} - -//============================================================================= -NSDictionary *Breakpad::GenerateReport(NSDictionary *server_parameters) { - NSString *dumpDirAsNSString = KeyValue(@BREAKPAD_DUMP_DIRECTORY); - if (!dumpDirAsNSString) - return nil; - const char *dumpDir = [dumpDirAsNSString UTF8String]; - - google_breakpad::MinidumpGenerator generator(mach_task_self(), - MACH_PORT_NULL); - std::string dumpId; - std::string dumpFilename = generator.UniqueNameInDirectory(dumpDir, &dumpId); - bool success = generator.Write(dumpFilename.c_str()); - if (!success) - return nil; - - SimpleStringDictionary params = *config_params_; - for (NSString *key in server_parameters) { - params.SetKeyValue([key UTF8String], - [[server_parameters objectForKey:key] UTF8String]); - } - ConfigFile config_file; - config_file.WriteFile(dumpDir, ¶ms, dumpDir, dumpId.c_str()); - - // Handle results. - NSMutableDictionary *result = [NSMutableDictionary dictionary]; - NSString *dumpFullPath = [NSString stringWithUTF8String:dumpFilename.c_str()]; - [result setValue:dumpFullPath - forKey:@BREAKPAD_OUTPUT_DUMP_FILE]; - [result setValue:[NSString stringWithUTF8String:config_file.GetFilePath()] - forKey:@BREAKPAD_OUTPUT_CONFIG_FILE]; - return result; -} - -//============================================================================= -bool Breakpad::HandleMinidump(const char *dump_dir, - const char *minidump_id) { - config_file_.WriteFile(dump_dir, - config_params_, - dump_dir, - minidump_id); - - // Return true here to indicate that we've processed things as much as we - // want. - return true; -} - -//============================================================================= -void Breakpad::HandleUncaughtException(NSException *exception) { - // Generate the minidump. - google_breakpad::IosExceptionMinidumpGenerator generator(exception); - const char *minidump_path = - config_params_->GetValueForKey(BREAKPAD_DUMP_DIRECTORY); - std::string minidump_id; - std::string minidump_filename = generator.UniqueNameInDirectory(minidump_path, - &minidump_id); - generator.Write(minidump_filename.c_str()); - - // Copy the config params and our custom parameter. This is necessary for 2 - // reasons: - // 1- config_params_ is protected. - // 2- If the application crash while trying to handle this exception, a usual - // report will be generated. This report must not contain these special - // keys. - SimpleStringDictionary params = *config_params_; - params.SetKeyValue(BREAKPAD_SERVER_PARAMETER_PREFIX "type", "exception"); - params.SetKeyValue(BREAKPAD_SERVER_PARAMETER_PREFIX "exceptionName", - [[exception name] UTF8String]); - params.SetKeyValue(BREAKPAD_SERVER_PARAMETER_PREFIX "exceptionReason", - [[exception reason] UTF8String]); - - // And finally write the config file. - ConfigFile config_file; - config_file.WriteFile(minidump_path, - ¶ms, - minidump_path, - minidump_id.c_str()); -} - -//============================================================================= - -#pragma mark - -#pragma mark Public API - -//============================================================================= -BreakpadRef BreakpadCreate(NSDictionary *parameters) { - try { - // This is confusing. Our two main allocators for breakpad memory are: - // - gKeyValueAllocator for the key/value memory - // - gBreakpadAllocator for the Breakpad, ExceptionHandler, and other - // breakpad allocations which are accessed at exception handling time. - // - // But in order to avoid these two allocators themselves from being smashed, - // we'll protect them as well by allocating them with gMasterAllocator. - // - // gMasterAllocator itself will NOT be protected, but this doesn't matter, - // since once it does its allocations and locks the memory, smashes to - // itself don't affect anything we care about. - gMasterAllocator = - new ProtectedMemoryAllocator(sizeof(ProtectedMemoryAllocator) * 2); - - gKeyValueAllocator = - new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator))) - ProtectedMemoryAllocator(sizeof(SimpleStringDictionary)); - - // Create a mutex for use in accessing the SimpleStringDictionary - int mutexResult = pthread_mutex_init(&gDictionaryMutex, NULL); - if (mutexResult == 0) { - - // With the current compiler, gBreakpadAllocator is allocating 1444 bytes. - // Let's round up to the nearest page size. - // - int breakpad_pool_size = 4096; - - /* - sizeof(Breakpad) - + sizeof(google_breakpad::ExceptionHandler) - + sizeof( STUFF ALLOCATED INSIDE ExceptionHandler ) - */ - - gBreakpadAllocator = - new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator))) - ProtectedMemoryAllocator(breakpad_pool_size); - - // Stack-based autorelease pool for Breakpad::Create() obj-c code. - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Breakpad *breakpad = Breakpad::Create(parameters); - - if (breakpad) { - // Make read-only to protect against memory smashers - gMasterAllocator->Protect(); - gKeyValueAllocator->Protect(); - gBreakpadAllocator->Protect(); - // Can uncomment this line to figure out how much space was actually - // allocated using this allocator - // printf("gBreakpadAllocator allocated size = %d\n", - // gBreakpadAllocator->GetAllocatedSize() ); - [pool release]; - return (BreakpadRef)breakpad; - } - - [pool release]; - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadCreate() : error\n"); - } - - if (gKeyValueAllocator) { - gKeyValueAllocator->~ProtectedMemoryAllocator(); - gKeyValueAllocator = NULL; - } - - if (gBreakpadAllocator) { - gBreakpadAllocator->~ProtectedMemoryAllocator(); - gBreakpadAllocator = NULL; - } - - delete gMasterAllocator; - gMasterAllocator = NULL; - - return NULL; -} - -//============================================================================= -void BreakpadRelease(BreakpadRef ref) { - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (gMasterAllocator) { - gMasterAllocator->Unprotect(); - gKeyValueAllocator->Unprotect(); - gBreakpadAllocator->Unprotect(); - - breakpad->~Breakpad(); - - // Unfortunately, it's not possible to deallocate this stuff - // because the exception handling thread is still finishing up - // asynchronously at this point... OK, it could be done with - // locks, etc. But since BreakpadRelease() should usually only - // be called right before the process exits, it's not worth - // deallocating this stuff. -#if 0 - gKeyValueAllocator->~ProtectedMemoryAllocator(); - gBreakpadAllocator->~ProtectedMemoryAllocator(); - delete gMasterAllocator; - - gMasterAllocator = NULL; - gKeyValueAllocator = NULL; - gBreakpadAllocator = NULL; -#endif - - pthread_mutex_destroy(&gDictionaryMutex); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRelease() : error\n"); - } -} - -//============================================================================= -void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - breakpad->SetKeyValue(key, value); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadSetKeyValue() : error\n"); - } -} - -void BreakpadAddUploadParameter(BreakpadRef ref, - NSString *key, - NSString *value) { - // The only difference, internally, between an upload parameter and - // a key value one that is set with BreakpadSetKeyValue is that we - // prepend the keyname with a special prefix. This informs the - // crash sender that the parameter should be sent along with the - // POST of the crash dump upload. - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - NSString *prefixedKey = [@BREAKPAD_SERVER_PARAMETER_PREFIX - stringByAppendingString:key]; - breakpad->SetKeyValue(prefixedKey, value); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadSetKeyValue() : error\n"); - } -} - -void BreakpadRemoveUploadParameter(BreakpadRef ref, - NSString *key) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - NSString *prefixedKey = [NSString stringWithFormat:@"%@%@", - @BREAKPAD_SERVER_PARAMETER_PREFIX, key]; - breakpad->RemoveKeyValue(prefixedKey); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRemoveKeyValue() : error\n"); - } -} -//============================================================================= -NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key) { - NSString *value = nil; - - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (!breakpad || !key || !gKeyValueAllocator) - return nil; - - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - value = breakpad->KeyValue(key); - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadKeyValue() : error\n"); - } - - return value; -} - -//============================================================================= -void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - breakpad->RemoveKeyValue(key); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRemoveKeyValue() : error\n"); - } -} - -//============================================================================= -int BreakpadGetCrashReportCount(BreakpadRef ref) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad) { - return static_cast([breakpad->CrashReportsToUpload() count]); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadGetCrashReportCount() : error\n"); - } - return false; -} - -//============================================================================= -void BreakpadUploadNextReport(BreakpadRef ref) { - BreakpadUploadNextReportWithParameters(ref, nil); -} - -//============================================================================= -NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref) { - try { - Breakpad *breakpad = (Breakpad *)ref; - if (breakpad) - return breakpad->NextCrashReportConfiguration(); - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadGetNextReportConfiguration() : error\n"); - } - return nil; -} - -//============================================================================= -void BreakpadUploadReportWithParametersAndConfiguration( - BreakpadRef ref, - NSDictionary *server_parameters, - NSDictionary *configuration) { - try { - Breakpad *breakpad = (Breakpad *)ref; - if (!breakpad || !configuration) - return; - breakpad->UploadReportWithConfiguration(configuration, server_parameters); - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, - "BreakpadUploadReportWithParametersAndConfiguration() : error\n"); - } - -} - -//============================================================================= -void BreakpadUploadNextReportWithParameters(BreakpadRef ref, - NSDictionary *server_parameters) { - try { - Breakpad *breakpad = (Breakpad *)ref; - if (!breakpad) - return; - NSDictionary *configuration = breakpad->NextCrashReportConfiguration(); - if (!configuration) - return; - return BreakpadUploadReportWithParametersAndConfiguration(ref, - server_parameters, - configuration); - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadUploadNextReportWithParameters() : error\n"); - } -} - -void BreakpadHandleNetworkResponse(BreakpadRef ref, - NSDictionary *configuration, - NSData *data, - NSError *error) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - if (breakpad && configuration) - breakpad->HandleNetworkResponse(configuration,data, error); - - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadHandleNetworkResponse() : error\n"); - } -} - -//============================================================================= -void BreakpadUploadData(BreakpadRef ref, NSData *data, NSString *name, - NSDictionary *server_parameters) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad) { - breakpad->UploadData(data, name, server_parameters); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadUploadData() : error\n"); - } -} - -//============================================================================= -NSDictionary *BreakpadGenerateReport(BreakpadRef ref, - NSDictionary *server_parameters) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad) { - return breakpad->GenerateReport(server_parameters); - } else { - return nil; - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadGenerateReport() : error\n"); - return nil; - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.xcodeproj/project.pbxproj deleted file mode 100644 index e9fcae3f9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad.xcodeproj/project.pbxproj +++ /dev/null @@ -1,578 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 14569321182CE29F0029C465 /* ucontext_compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 14569320182CE29F0029C465 /* ucontext_compat.h */; }; - 14569323182CE2C10029C465 /* mach_vm_compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 14569322182CE2C10029C465 /* mach_vm_compat.h */; }; - 16BFA67014E195E9009704F8 /* ios_exception_minidump_generator.h in Headers */ = {isa = PBXBuildFile; fileRef = 16BFA66E14E195E9009704F8 /* ios_exception_minidump_generator.h */; }; - 16BFA67214E1965A009704F8 /* ios_exception_minidump_generator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16BFA67114E1965A009704F8 /* ios_exception_minidump_generator.mm */; }; - 16C7CCCB147D4A4300776EAD /* BreakpadDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7C968147D4A4200776EAD /* BreakpadDefines.h */; }; - 16C7CCCC147D4A4300776EAD /* Breakpad.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7C96A147D4A4200776EAD /* Breakpad.h */; }; - 16C7CCCD147D4A4300776EAD /* Breakpad.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16C7C96B147D4A4200776EAD /* Breakpad.mm */; }; - 16C7CDE8147D4A4300776EAD /* ConfigFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CB9E147D4A4300776EAD /* ConfigFile.h */; }; - 16C7CDE9147D4A4300776EAD /* ConfigFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CB9F147D4A4300776EAD /* ConfigFile.mm */; }; - 16C7CDF5147D4A4300776EAD /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBAD147D4A4300776EAD /* breakpad_nlist_64.cc */; }; - 16C7CDF6147D4A4300776EAD /* breakpad_nlist_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBAE147D4A4300776EAD /* breakpad_nlist_64.h */; }; - 16C7CDF7147D4A4300776EAD /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBAF147D4A4300776EAD /* dynamic_images.cc */; }; - 16C7CDF8147D4A4300776EAD /* dynamic_images.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBB0147D4A4300776EAD /* dynamic_images.h */; }; - 16C7CDF9147D4A4300776EAD /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBB1147D4A4300776EAD /* exception_handler.cc */; }; - 16C7CDFA147D4A4300776EAD /* exception_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBB2147D4A4300776EAD /* exception_handler.h */; }; - 16C7CDFC147D4A4300776EAD /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBB4147D4A4300776EAD /* minidump_generator.cc */; }; - 16C7CDFD147D4A4300776EAD /* minidump_generator.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBB5147D4A4300776EAD /* minidump_generator.h */; }; - 16C7CDFE147D4A4300776EAD /* protected_memory_allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBBC147D4A4300776EAD /* protected_memory_allocator.cc */; }; - 16C7CDFF147D4A4300776EAD /* protected_memory_allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBBD147D4A4300776EAD /* protected_memory_allocator.h */; }; - 16C7CE08147D4A4300776EAD /* uploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CBEA147D4A4300776EAD /* uploader.h */; }; - 16C7CE09147D4A4300776EAD /* uploader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CBEB147D4A4300776EAD /* uploader.mm */; }; - 16C7CE18147D4A4300776EAD /* minidump_file_writer-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC04147D4A4300776EAD /* minidump_file_writer-inl.h */; }; - 16C7CE19147D4A4300776EAD /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC05147D4A4300776EAD /* minidump_file_writer.cc */; }; - 16C7CE1A147D4A4300776EAD /* minidump_file_writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC06147D4A4300776EAD /* minidump_file_writer.h */; }; - 16C7CE40147D4A4300776EAD /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC4A147D4A4300776EAD /* convert_UTF.c */; }; - 16C7CE41147D4A4300776EAD /* convert_UTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC4B147D4A4300776EAD /* convert_UTF.h */; }; - 16C7CE78147D4A4300776EAD /* GTMLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC88147D4A4300776EAD /* GTMLogger.h */; }; - 16C7CE79147D4A4300776EAD /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC89147D4A4300776EAD /* GTMLogger.m */; }; - 16C7CE7A147D4A4300776EAD /* HTTPMultipartUpload.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC8A147D4A4300776EAD /* HTTPMultipartUpload.h */; }; - 16C7CE7B147D4A4300776EAD /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC8B147D4A4300776EAD /* HTTPMultipartUpload.m */; }; - 16C7CE83147D4A4300776EAD /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC93147D4A4300776EAD /* file_id.cc */; }; - 16C7CE84147D4A4300776EAD /* file_id.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC94147D4A4300776EAD /* file_id.h */; }; - 16C7CE85147D4A4300776EAD /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC95147D4A4300776EAD /* macho_id.cc */; }; - 16C7CE86147D4A4300776EAD /* macho_id.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC96147D4A4300776EAD /* macho_id.h */; }; - 16C7CE8A147D4A4300776EAD /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC9A147D4A4300776EAD /* macho_utilities.cc */; }; - 16C7CE8B147D4A4300776EAD /* macho_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC9B147D4A4300776EAD /* macho_utilities.h */; }; - 16C7CE8C147D4A4300776EAD /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC9C147D4A4300776EAD /* macho_walker.cc */; }; - 16C7CE8D147D4A4300776EAD /* macho_walker.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CC9D147D4A4300776EAD /* macho_walker.h */; }; - 16C7CE8F147D4A4300776EAD /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CC9F147D4A4300776EAD /* string_utilities.cc */; }; - 16C7CE90147D4A4300776EAD /* string_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CCA0147D4A4300776EAD /* string_utilities.h */; }; - 16C7CE93147D4A4300776EAD /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CCA4147D4A4300776EAD /* md5.cc */; }; - 16C7CE94147D4A4300776EAD /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CCA5147D4A4300776EAD /* md5.h */; }; - 16C7CEA7147D4A4300776EAD /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 16C7CCB9147D4A4300776EAD /* string_conversion.cc */; }; - 16C7CEA8147D4A4300776EAD /* string_conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7CCBA147D4A4300776EAD /* string_conversion.h */; }; - 16C92FAD150DF8330053D7BA /* BreakpadController.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C92FAB150DF8330053D7BA /* BreakpadController.h */; }; - 16C92FAE150DF8330053D7BA /* BreakpadController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16C92FAC150DF8330053D7BA /* BreakpadController.mm */; }; - 1EEEB60F1720821900F7E689 /* simple_string_dictionary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EEEB60C1720821900F7E689 /* simple_string_dictionary.cc */; }; - 1EEEB6101720821900F7E689 /* simple_string_dictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EEEB60D1720821900F7E689 /* simple_string_dictionary.h */; }; - AA747D9F0F9514B9006C5449 /* Breakpad_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Breakpad_Prefix.pch */; }; - AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 14569320182CE29F0029C465 /* ucontext_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucontext_compat.h; sourceTree = ""; }; - 14569322182CE2C10029C465 /* mach_vm_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_vm_compat.h; sourceTree = ""; }; - 16BFA66E14E195E9009704F8 /* ios_exception_minidump_generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ios_exception_minidump_generator.h; sourceTree = ""; }; - 16BFA67114E1965A009704F8 /* ios_exception_minidump_generator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ios_exception_minidump_generator.mm; sourceTree = ""; }; - 16C7C968147D4A4200776EAD /* BreakpadDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakpadDefines.h; sourceTree = ""; }; - 16C7C96A147D4A4200776EAD /* Breakpad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpad.h; sourceTree = ""; }; - 16C7C96B147D4A4200776EAD /* Breakpad.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Breakpad.mm; sourceTree = ""; }; - 16C7CB9E147D4A4300776EAD /* ConfigFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigFile.h; sourceTree = ""; }; - 16C7CB9F147D4A4300776EAD /* ConfigFile.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConfigFile.mm; sourceTree = ""; }; - 16C7CBAD147D4A4300776EAD /* breakpad_nlist_64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = breakpad_nlist_64.cc; sourceTree = ""; }; - 16C7CBAE147D4A4300776EAD /* breakpad_nlist_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = breakpad_nlist_64.h; sourceTree = ""; }; - 16C7CBAF147D4A4300776EAD /* dynamic_images.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dynamic_images.cc; sourceTree = ""; }; - 16C7CBB0147D4A4300776EAD /* dynamic_images.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dynamic_images.h; sourceTree = ""; }; - 16C7CBB1147D4A4300776EAD /* exception_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exception_handler.cc; sourceTree = ""; }; - 16C7CBB2147D4A4300776EAD /* exception_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exception_handler.h; sourceTree = ""; }; - 16C7CBB4147D4A4300776EAD /* minidump_generator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = minidump_generator.cc; sourceTree = ""; }; - 16C7CBB5147D4A4300776EAD /* minidump_generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = minidump_generator.h; sourceTree = ""; }; - 16C7CBBC147D4A4300776EAD /* protected_memory_allocator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = protected_memory_allocator.cc; sourceTree = ""; }; - 16C7CBBD147D4A4300776EAD /* protected_memory_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protected_memory_allocator.h; sourceTree = ""; }; - 16C7CBEA147D4A4300776EAD /* uploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uploader.h; sourceTree = ""; }; - 16C7CBEB147D4A4300776EAD /* uploader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = uploader.mm; sourceTree = ""; }; - 16C7CC04147D4A4300776EAD /* minidump_file_writer-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "minidump_file_writer-inl.h"; sourceTree = ""; }; - 16C7CC05147D4A4300776EAD /* minidump_file_writer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = minidump_file_writer.cc; sourceTree = ""; }; - 16C7CC06147D4A4300776EAD /* minidump_file_writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = minidump_file_writer.h; sourceTree = ""; }; - 16C7CC07147D4A4300776EAD /* minidump_file_writer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = minidump_file_writer_unittest.cc; sourceTree = ""; }; - 16C7CC4A147D4A4300776EAD /* convert_UTF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = convert_UTF.c; sourceTree = ""; }; - 16C7CC4B147D4A4300776EAD /* convert_UTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = convert_UTF.h; sourceTree = ""; }; - 16C7CC88147D4A4300776EAD /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = ""; }; - 16C7CC89147D4A4300776EAD /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = ""; }; - 16C7CC8A147D4A4300776EAD /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPMultipartUpload.h; sourceTree = ""; }; - 16C7CC8B147D4A4300776EAD /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTTPMultipartUpload.m; sourceTree = ""; }; - 16C7CC93147D4A4300776EAD /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_id.cc; sourceTree = ""; }; - 16C7CC94147D4A4300776EAD /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_id.h; sourceTree = ""; }; - 16C7CC95147D4A4300776EAD /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho_id.cc; sourceTree = ""; }; - 16C7CC96147D4A4300776EAD /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho_id.h; sourceTree = ""; }; - 16C7CC9A147D4A4300776EAD /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho_utilities.cc; sourceTree = ""; }; - 16C7CC9B147D4A4300776EAD /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho_utilities.h; sourceTree = ""; }; - 16C7CC9C147D4A4300776EAD /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho_walker.cc; sourceTree = ""; }; - 16C7CC9D147D4A4300776EAD /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho_walker.h; sourceTree = ""; }; - 16C7CC9F147D4A4300776EAD /* string_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_utilities.cc; sourceTree = ""; }; - 16C7CCA0147D4A4300776EAD /* string_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_utilities.h; sourceTree = ""; }; - 16C7CCA4147D4A4300776EAD /* md5.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cc; sourceTree = ""; }; - 16C7CCA5147D4A4300776EAD /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = ""; }; - 16C7CCB9147D4A4300776EAD /* string_conversion.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_conversion.cc; sourceTree = ""; }; - 16C7CCBA147D4A4300776EAD /* string_conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_conversion.h; sourceTree = ""; }; - 16C92FAB150DF8330053D7BA /* BreakpadController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakpadController.h; sourceTree = ""; }; - 16C92FAC150DF8330053D7BA /* BreakpadController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BreakpadController.mm; sourceTree = ""; }; - 1EEEB60C1720821900F7E689 /* simple_string_dictionary.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simple_string_dictionary.cc; sourceTree = ""; }; - 1EEEB60D1720821900F7E689 /* simple_string_dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simple_string_dictionary.h; sourceTree = ""; }; - AA747D9E0F9514B9006C5449 /* Breakpad_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpad_Prefix.pch; sourceTree = SOURCE_ROOT; }; - AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - D2AAC07E0554694100DB518D /* libBreakpad.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBreakpad.a; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D2AAC07C0554694100DB518D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DFFF38A50411DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - D2AAC07E0554694100DB518D /* libBreakpad.a */, - ); - name = Products; - sourceTree = ""; - }; - 0867D691FE84028FC02AAC07 /* Breakpad */ = { - isa = PBXGroup; - children = ( - 08FB77AEFE84172EC02AAC07 /* Classes */, - 32C88DFF0371C24200C91783 /* Other Sources */, - 0867D69AFE84028FC02AAC07 /* Frameworks */, - 034768DFFF38A50411DB9C8B /* Products */, - ); - name = Breakpad; - sourceTree = ""; - }; - 0867D69AFE84028FC02AAC07 /* Frameworks */ = { - isa = PBXGroup; - children = ( - AACBBE490F95108600F1A2B1 /* Foundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 08FB77AEFE84172EC02AAC07 /* Classes */ = { - isa = PBXGroup; - children = ( - 16C7C965147D4A4200776EAD /* client */, - 16C7CC47147D4A4300776EAD /* common */, - ); - name = Classes; - sourceTree = ""; - }; - 16BFA66A14E195E9009704F8 /* handler */ = { - isa = PBXGroup; - children = ( - 16BFA67114E1965A009704F8 /* ios_exception_minidump_generator.mm */, - 16BFA66E14E195E9009704F8 /* ios_exception_minidump_generator.h */, - ); - path = handler; - sourceTree = ""; - }; - 16C7C965147D4A4200776EAD /* client */ = { - isa = PBXGroup; - children = ( - 16C7C966147D4A4200776EAD /* apple */, - 16C7C969147D4A4200776EAD /* ios */, - 16C7C99E147D4A4200776EAD /* mac */, - 16C7CC04147D4A4300776EAD /* minidump_file_writer-inl.h */, - 16C7CC05147D4A4300776EAD /* minidump_file_writer.cc */, - 16C7CC06147D4A4300776EAD /* minidump_file_writer.h */, - 16C7CC07147D4A4300776EAD /* minidump_file_writer_unittest.cc */, - ); - name = client; - path = ..; - sourceTree = SOURCE_ROOT; - }; - 16C7C966147D4A4200776EAD /* apple */ = { - isa = PBXGroup; - children = ( - 16C7C967147D4A4200776EAD /* Framework */, - ); - path = apple; - sourceTree = ""; - }; - 16C7C967147D4A4200776EAD /* Framework */ = { - isa = PBXGroup; - children = ( - 16C7C968147D4A4200776EAD /* BreakpadDefines.h */, - ); - path = Framework; - sourceTree = ""; - }; - 16C7C969147D4A4200776EAD /* ios */ = { - isa = PBXGroup; - children = ( - 16C92FAB150DF8330053D7BA /* BreakpadController.h */, - 16C92FAC150DF8330053D7BA /* BreakpadController.mm */, - 16BFA66A14E195E9009704F8 /* handler */, - 16C7C96A147D4A4200776EAD /* Breakpad.h */, - 16C7C96B147D4A4200776EAD /* Breakpad.mm */, - ); - path = ios; - sourceTree = ""; - }; - 16C7C99E147D4A4200776EAD /* mac */ = { - isa = PBXGroup; - children = ( - 16C7CB9D147D4A4300776EAD /* crash_generation */, - 16C7CBAA147D4A4300776EAD /* handler */, - 16C7CBC8147D4A4300776EAD /* sender */, - ); - path = mac; - sourceTree = ""; - }; - 16C7CB9D147D4A4300776EAD /* crash_generation */ = { - isa = PBXGroup; - children = ( - 16C7CB9E147D4A4300776EAD /* ConfigFile.h */, - 16C7CB9F147D4A4300776EAD /* ConfigFile.mm */, - ); - path = crash_generation; - sourceTree = ""; - }; - 16C7CBAA147D4A4300776EAD /* handler */ = { - isa = PBXGroup; - children = ( - 16C7CBAD147D4A4300776EAD /* breakpad_nlist_64.cc */, - 16C7CBAE147D4A4300776EAD /* breakpad_nlist_64.h */, - 16C7CBAF147D4A4300776EAD /* dynamic_images.cc */, - 16C7CBB0147D4A4300776EAD /* dynamic_images.h */, - 16C7CBB1147D4A4300776EAD /* exception_handler.cc */, - 16C7CBB2147D4A4300776EAD /* exception_handler.h */, - 14569322182CE2C10029C465 /* mach_vm_compat.h */, - 16C7CBB4147D4A4300776EAD /* minidump_generator.cc */, - 16C7CBB5147D4A4300776EAD /* minidump_generator.h */, - 16C7CBBC147D4A4300776EAD /* protected_memory_allocator.cc */, - 16C7CBBD147D4A4300776EAD /* protected_memory_allocator.h */, - 14569320182CE29F0029C465 /* ucontext_compat.h */, - ); - path = handler; - sourceTree = ""; - }; - 16C7CBC8147D4A4300776EAD /* sender */ = { - isa = PBXGroup; - children = ( - 16C7CBEA147D4A4300776EAD /* uploader.h */, - 16C7CBEB147D4A4300776EAD /* uploader.mm */, - ); - path = sender; - sourceTree = ""; - }; - 16C7CC47147D4A4300776EAD /* common */ = { - isa = PBXGroup; - children = ( - 1EEEB60C1720821900F7E689 /* simple_string_dictionary.cc */, - 1EEEB60D1720821900F7E689 /* simple_string_dictionary.h */, - 16C7CC4A147D4A4300776EAD /* convert_UTF.c */, - 16C7CC4B147D4A4300776EAD /* convert_UTF.h */, - 16C7CC82147D4A4300776EAD /* mac */, - 16C7CCA4147D4A4300776EAD /* md5.cc */, - 16C7CCA5147D4A4300776EAD /* md5.h */, - 16C7CCB9147D4A4300776EAD /* string_conversion.cc */, - 16C7CCBA147D4A4300776EAD /* string_conversion.h */, - ); - name = common; - path = ../../common; - sourceTree = SOURCE_ROOT; - }; - 16C7CC82147D4A4300776EAD /* mac */ = { - isa = PBXGroup; - children = ( - 16C7CC88147D4A4300776EAD /* GTMLogger.h */, - 16C7CC89147D4A4300776EAD /* GTMLogger.m */, - 16C7CC8A147D4A4300776EAD /* HTTPMultipartUpload.h */, - 16C7CC8B147D4A4300776EAD /* HTTPMultipartUpload.m */, - 16C7CC93147D4A4300776EAD /* file_id.cc */, - 16C7CC94147D4A4300776EAD /* file_id.h */, - 16C7CC95147D4A4300776EAD /* macho_id.cc */, - 16C7CC96147D4A4300776EAD /* macho_id.h */, - 16C7CC9A147D4A4300776EAD /* macho_utilities.cc */, - 16C7CC9B147D4A4300776EAD /* macho_utilities.h */, - 16C7CC9C147D4A4300776EAD /* macho_walker.cc */, - 16C7CC9D147D4A4300776EAD /* macho_walker.h */, - 16C7CC9F147D4A4300776EAD /* string_utilities.cc */, - 16C7CCA0147D4A4300776EAD /* string_utilities.h */, - ); - path = mac; - sourceTree = ""; - }; - 32C88DFF0371C24200C91783 /* Other Sources */ = { - isa = PBXGroup; - children = ( - AA747D9E0F9514B9006C5449 /* Breakpad_Prefix.pch */, - ); - name = "Other Sources"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC07A0554694100DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - AA747D9F0F9514B9006C5449 /* Breakpad_Prefix.pch in Headers */, - 16C7CCCB147D4A4300776EAD /* BreakpadDefines.h in Headers */, - 16C7CCCC147D4A4300776EAD /* Breakpad.h in Headers */, - 16C7CDE8147D4A4300776EAD /* ConfigFile.h in Headers */, - 14569321182CE29F0029C465 /* ucontext_compat.h in Headers */, - 16C7CDF6147D4A4300776EAD /* breakpad_nlist_64.h in Headers */, - 16C7CDF8147D4A4300776EAD /* dynamic_images.h in Headers */, - 16C7CDFA147D4A4300776EAD /* exception_handler.h in Headers */, - 16C7CDFD147D4A4300776EAD /* minidump_generator.h in Headers */, - 16C7CDFF147D4A4300776EAD /* protected_memory_allocator.h in Headers */, - 16C7CE08147D4A4300776EAD /* uploader.h in Headers */, - 16C7CE18147D4A4300776EAD /* minidump_file_writer-inl.h in Headers */, - 16C7CE1A147D4A4300776EAD /* minidump_file_writer.h in Headers */, - 16C7CE41147D4A4300776EAD /* convert_UTF.h in Headers */, - 16C7CE78147D4A4300776EAD /* GTMLogger.h in Headers */, - 16C7CE7A147D4A4300776EAD /* HTTPMultipartUpload.h in Headers */, - 16C7CE84147D4A4300776EAD /* file_id.h in Headers */, - 16C7CE86147D4A4300776EAD /* macho_id.h in Headers */, - 16C7CE8B147D4A4300776EAD /* macho_utilities.h in Headers */, - 16C7CE8D147D4A4300776EAD /* macho_walker.h in Headers */, - 16C7CE90147D4A4300776EAD /* string_utilities.h in Headers */, - 16C7CE94147D4A4300776EAD /* md5.h in Headers */, - 16C7CEA8147D4A4300776EAD /* string_conversion.h in Headers */, - 16BFA67014E195E9009704F8 /* ios_exception_minidump_generator.h in Headers */, - 16C92FAD150DF8330053D7BA /* BreakpadController.h in Headers */, - 1EEEB6101720821900F7E689 /* simple_string_dictionary.h in Headers */, - 14569323182CE2C10029C465 /* mach_vm_compat.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - D2AAC07D0554694100DB518D /* Breakpad */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */; - buildPhases = ( - D2AAC07A0554694100DB518D /* Headers */, - D2AAC07B0554694100DB518D /* Sources */, - D2AAC07C0554694100DB518D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Breakpad; - productName = Breakpad; - productReference = D2AAC07E0554694100DB518D /* libBreakpad.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - }; - buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Breakpad" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - da, - de, - es, - fr, - it, - ja, - nl, - no, - sl, - sv, - tr, - ); - mainGroup = 0867D691FE84028FC02AAC07 /* Breakpad */; - productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D2AAC07D0554694100DB518D /* Breakpad */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - D2AAC07B0554694100DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 16C7CCCD147D4A4300776EAD /* Breakpad.mm in Sources */, - 16C7CDE9147D4A4300776EAD /* ConfigFile.mm in Sources */, - 16C7CDF5147D4A4300776EAD /* breakpad_nlist_64.cc in Sources */, - 16C7CDF7147D4A4300776EAD /* dynamic_images.cc in Sources */, - 16C7CDF9147D4A4300776EAD /* exception_handler.cc in Sources */, - 16C7CDFC147D4A4300776EAD /* minidump_generator.cc in Sources */, - 16C7CDFE147D4A4300776EAD /* protected_memory_allocator.cc in Sources */, - 16C7CE09147D4A4300776EAD /* uploader.mm in Sources */, - 16C7CE19147D4A4300776EAD /* minidump_file_writer.cc in Sources */, - 16C7CE40147D4A4300776EAD /* convert_UTF.c in Sources */, - 16C7CE79147D4A4300776EAD /* GTMLogger.m in Sources */, - 16C7CE7B147D4A4300776EAD /* HTTPMultipartUpload.m in Sources */, - 16C7CE83147D4A4300776EAD /* file_id.cc in Sources */, - 16C7CE85147D4A4300776EAD /* macho_id.cc in Sources */, - 16C7CE8A147D4A4300776EAD /* macho_utilities.cc in Sources */, - 16C7CE8C147D4A4300776EAD /* macho_walker.cc in Sources */, - 16C7CE8F147D4A4300776EAD /* string_utilities.cc in Sources */, - 16C7CE93147D4A4300776EAD /* md5.cc in Sources */, - 16C7CEA7147D4A4300776EAD /* string_conversion.cc in Sources */, - 16BFA67214E1965A009704F8 /* ios_exception_minidump_generator.mm in Sources */, - 16C92FAE150DF8330053D7BA /* BreakpadController.mm in Sources */, - 1EEEB60F1720821900F7E689 /* simple_string_dictionary.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB921F08733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - DSTROOT = /tmp/Breakpad.dst; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../mac/build/Debug\"", - ); - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Breakpad_Prefix.pch; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/Breakpad.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/Breakpad.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/breakpadUtilities.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/breakpadUtilities.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/gtest.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/gtest.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Debug\"", - "\"$(SRCROOT)/../mac/gcov\"", - ); - PRODUCT_NAME = Breakpad; - }; - name = Debug; - }; - 1DEB922008733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - DSTROOT = /tmp/Breakpad.dst; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../mac/build/Debug\"", - ); - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Breakpad_Prefix.pch; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/Breakpad.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/Breakpad.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/breakpadUtilities.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/breakpadUtilities.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/gtest.build/Objects-normal/i386\"", - "\"$(SRCROOT)/../mac/build/Breakpad.build/Debug/gtest.build/Objects-normal/x86_64\"", - "\"$(SRCROOT)/../mac/build/Debug\"", - "\"$(SRCROOT)/../mac/gcov\"", - ); - PRODUCT_NAME = Breakpad; - }; - name = Release; - }; - 1DEB922308733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - ../../, - ../../client/apple/Framework, - ../../common/mac, - ); - IPHONEOS_DEPLOYMENT_TARGET = 5.0; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "-ObjC"; - SDKROOT = iphoneos; - WARNING_CFLAGS = "-Wundef"; - }; - name = Debug; - }; - 1DEB922408733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - ../../, - ../../client/apple/Framework, - ../../common/mac, - ); - IPHONEOS_DEPLOYMENT_TARGET = 5.0; - OTHER_LDFLAGS = "-ObjC"; - SDKROOT = iphoneos; - WARNING_CFLAGS = "-Wundef"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB921F08733DC00010E9CD /* Debug */, - 1DEB922008733DC00010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Breakpad" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB922308733DC00010E9CD /* Debug */, - 1DEB922408733DC00010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.h b/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.h deleted file mode 100644 index 13609cb8d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_ -#define CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_ - -#import - -#import "client/ios/Breakpad.h" - -// This class is used to offer a higher level API around BreakpadRef. It -// configures it, ensures thread-safety, and sends crash reports back to the -// collecting server. By default, no crash reports are sent, the user must call -// |setUploadingEnabled:YES| to start the uploading. -@interface BreakpadController : NSObject { - @private - // The dispatch queue that will own the breakpad reference. - dispatch_queue_t queue_; - - // Instance of Breakpad crash reporter. This is owned by the queue, but can - // be created on the main thread at startup. - BreakpadRef breakpadRef_; - - // The dictionary that contains configuration for breakpad. Modifying it - // should only happen when the controller is not started. The initial value - // is the infoDictionary of the bundle of the application. - NSMutableDictionary* configuration_; - - // Whether or not crash reports should be uploaded. - BOOL enableUploads_; - - // Whether the controller has been started on the main thread. This is only - // used to assert the initialization order is correct. - BOOL started_; - - // The interval to wait between two uploads. Value is 0 if no upload must be - // done. - int uploadIntervalInSeconds_; - - // The dictionary that contains additional server parameters to send when - // uploading crash reports. - NSDictionary* uploadTimeParameters_; -} - -// Singleton. -+ (BreakpadController*)sharedInstance; - -// Update the controller configuration. Merges its old configuration with the -// new one. Merge is done by replacing the old values by the new values. -- (void)updateConfiguration:(NSDictionary*)configuration; - -// Reset the controller configuration to its initial value, which is the -// infoDictionary of the bundle of the application. -- (void)resetConfiguration; - -// Configure the URL to upload the report to. This must be called at least once -// if the URL is not in the bundle information. -- (void)setUploadingURL:(NSString*)url; - -// Set the minimal interval between two uploads in seconds. This must be called -// at least once if the interval is not in the bundle information. A value of 0 -// will prevent uploads. -- (void)setUploadInterval:(int)intervalInSeconds; - -// Set additional server parameters to send when uploading crash reports. -- (void)setParametersToAddAtUploadTime:(NSDictionary*)uploadTimeParameters; - -// Specify an upload parameter that will be added to the crash report when a -// crash report is generated. See |BreakpadAddUploadParameter|. -- (void)addUploadParameter:(NSString*)value forKey:(NSString*)key; - -// Remove a previously-added parameter from the upload parameter set. See -// |BreakpadRemoveUploadParameter|. -- (void)removeUploadParameterForKey:(NSString*)key; - -// Access the underlying BreakpadRef. This method is asynchronous, and will be -// executed on the thread owning the BreakpadRef variable. Moreover, if the -// controller is not started, the block will be called with a NULL parameter. -- (void)withBreakpadRef:(void(^)(BreakpadRef))callback; - -// Starts the BreakpadController by registering crash handlers. If -// |onCurrentThread| is YES, all setup is done on the current thread, otherwise -// it is done on a private queue. -- (void)start:(BOOL)onCurrentThread; - -// Unregisters the crash handlers. -- (void)stop; - -// Enables or disables uploading of crash reports, but does not stop the -// BreakpadController. -- (void)setUploadingEnabled:(BOOL)enabled; - -// Check if there is currently a crash report to upload. -- (void)hasReportToUpload:(void(^)(BOOL))callback; - -// Get the number of crash reports waiting to upload. -- (void)getCrashReportCount:(void(^)(int))callback; - -// Get the next report to upload. -// - If upload is disabled, callback will be called with (nil, -1). -// - If a delay is to be waited before sending, callback will be called with -// (nil, n), with n (> 0) being the number of seconds to wait. -// - if no delay is needed, callback will be called with (0, configuration), -// configuration being next report to upload, or nil if none is pending. -- (void)getNextReportConfigurationOrSendDelay: - (void(^)(NSDictionary*, int))callback; - -// Sends synchronously the report specified by |configuration|. This method is -// NOT thread safe and must be called from the breakpad thread. -- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration - withBreakpadRef:(BreakpadRef)ref; - -@end - -#endif // CLIENT_IOS_HANDLER_IOS_BREAKPAD_CONTROLLER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.mm b/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.mm deleted file mode 100644 index dd71cff68..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/BreakpadController.mm +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import "BreakpadController.h" - -#import -#include -#include -#include -#include -#include - -#include - -#pragma mark - -#pragma mark Private Methods - -@interface BreakpadController () - -// Init the singleton instance. -- (id)initSingleton; - -// Load a crash report and send it to the server. -- (void)sendStoredCrashReports; - -// Returns when a report can be sent. |-1| means never, |0| means that a report -// can be sent immediately, a positive number is the number of seconds to wait -// before being allowed to upload a report. -- (int)sendDelay; - -// Notifies that a report will be sent, and update the last sending time -// accordingly. -- (void)reportWillBeSent; - -@end - -#pragma mark - -#pragma mark Anonymous namespace - -namespace { - -// The name of the user defaults key for the last submission to the crash -// server. -NSString* const kLastSubmission = @"com.google.Breakpad.LastSubmission"; - -// Returns a NSString describing the current platform. -NSString* GetPlatform() { - // Name of the system call for getting the platform. - static const char kHwMachineSysctlName[] = "hw.machine"; - - NSString* result = nil; - - size_t size = 0; - if (sysctlbyname(kHwMachineSysctlName, NULL, &size, NULL, 0) || size == 0) - return nil; - google_breakpad::scoped_array machine(new char[size]); - if (sysctlbyname(kHwMachineSysctlName, machine.get(), &size, NULL, 0) == 0) - result = [NSString stringWithUTF8String:machine.get()]; - return result; -} - -} // namespace - -#pragma mark - -#pragma mark BreakpadController Implementation - -@implementation BreakpadController - -+ (BreakpadController*)sharedInstance { - @synchronized(self) { - static BreakpadController* sharedInstance_ = - [[BreakpadController alloc] initSingleton]; - return sharedInstance_; - } -} - -- (id)init { - return nil; -} - -- (id)initSingleton { - self = [super init]; - if (self) { - queue_ = dispatch_queue_create("com.google.BreakpadQueue", NULL); - enableUploads_ = NO; - started_ = NO; - [self resetConfiguration]; - } - return self; -} - -// Since this class is a singleton, this method is not expected to be called. -- (void)dealloc { - assert(!breakpadRef_); - dispatch_release(queue_); - [configuration_ release]; - [uploadTimeParameters_ release]; - [super dealloc]; -} - -#pragma mark - - -- (void)start:(BOOL)onCurrentThread { - if (started_) - return; - started_ = YES; - void(^startBlock)() = ^{ - assert(!breakpadRef_); - breakpadRef_ = BreakpadCreate(configuration_); - if (breakpadRef_) { - BreakpadAddUploadParameter(breakpadRef_, @"platform", GetPlatform()); - } - }; - if (onCurrentThread) - startBlock(); - else - dispatch_async(queue_, startBlock); -} - -- (void)stop { - if (!started_) - return; - started_ = NO; - dispatch_sync(queue_, ^{ - if (breakpadRef_) { - BreakpadRelease(breakpadRef_); - breakpadRef_ = NULL; - } - }); -} - -// This method must be called from the breakpad queue. -- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration - withBreakpadRef:(BreakpadRef)ref { - NSAssert(started_, @"The controller must be started before " - "threadUnsafeSendReportWithConfiguration is called"); - if (breakpadRef_) { - BreakpadUploadReportWithParametersAndConfiguration(breakpadRef_, - uploadTimeParameters_, - configuration); - } -} - -- (void)setUploadingEnabled:(BOOL)enabled { - NSAssert(started_, - @"The controller must be started before setUploadingEnabled is called"); - dispatch_async(queue_, ^{ - if (enabled == enableUploads_) - return; - if (enabled) { - // Set this before calling doSendStoredCrashReport, because that - // calls sendDelay, which in turn checks this flag. - enableUploads_ = YES; - [self sendStoredCrashReports]; - } else { - enableUploads_ = NO; - [NSObject cancelPreviousPerformRequestsWithTarget:self - selector:@selector(sendStoredCrashReports) - object:nil]; - } - }); -} - -- (void)updateConfiguration:(NSDictionary*)configuration { - NSAssert(!started_, - @"The controller must not be started when updateConfiguration is called"); - [configuration_ addEntriesFromDictionary:configuration]; - NSString* uploadInterval = - [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL]; - if (uploadInterval) - [self setUploadInterval:[uploadInterval intValue]]; -} - -- (void)resetConfiguration { - NSAssert(!started_, - @"The controller must not be started when resetConfiguration is called"); - [configuration_ autorelease]; - configuration_ = [[[NSBundle mainBundle] infoDictionary] mutableCopy]; - NSString* uploadInterval = - [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL]; - [self setUploadInterval:[uploadInterval intValue]]; - [self setParametersToAddAtUploadTime:nil]; -} - -- (void)setUploadingURL:(NSString*)url { - NSAssert(!started_, - @"The controller must not be started when setUploadingURL is called"); - [configuration_ setValue:url forKey:@BREAKPAD_URL]; -} - -- (void)setUploadInterval:(int)intervalInSeconds { - NSAssert(!started_, - @"The controller must not be started when setUploadInterval is called"); - [configuration_ removeObjectForKey:@BREAKPAD_REPORT_INTERVAL]; - uploadIntervalInSeconds_ = intervalInSeconds; - if (uploadIntervalInSeconds_ < 0) - uploadIntervalInSeconds_ = 0; -} - -- (void)setParametersToAddAtUploadTime:(NSDictionary*)uploadTimeParameters { - NSAssert(!started_, @"The controller must not be started when " - "setParametersToAddAtUploadTime is called"); - [uploadTimeParameters_ autorelease]; - uploadTimeParameters_ = [uploadTimeParameters copy]; -} - -- (void)addUploadParameter:(NSString*)value forKey:(NSString*)key { - NSAssert(started_, - @"The controller must be started before addUploadParameter is called"); - dispatch_async(queue_, ^{ - if (breakpadRef_) - BreakpadAddUploadParameter(breakpadRef_, key, value); - }); -} - -- (void)removeUploadParameterForKey:(NSString*)key { - NSAssert(started_, @"The controller must be started before " - "removeUploadParameterForKey is called"); - dispatch_async(queue_, ^{ - if (breakpadRef_) - BreakpadRemoveUploadParameter(breakpadRef_, key); - }); -} - -- (void)withBreakpadRef:(void(^)(BreakpadRef))callback { - NSAssert(started_, - @"The controller must be started before withBreakpadRef is called"); - dispatch_async(queue_, ^{ - callback(breakpadRef_); - }); -} - -- (void)hasReportToUpload:(void(^)(BOOL))callback { - NSAssert(started_, @"The controller must be started before " - "hasReportToUpload is called"); - dispatch_async(queue_, ^{ - callback(breakpadRef_ && (BreakpadGetCrashReportCount(breakpadRef_) > 0)); - }); -} - -- (void)getCrashReportCount:(void(^)(int))callback { - NSAssert(started_, @"The controller must be started before " - "getCrashReportCount is called"); - dispatch_async(queue_, ^{ - callback(breakpadRef_ ? BreakpadGetCrashReportCount(breakpadRef_) : 0); - }); -} - -- (void)getNextReportConfigurationOrSendDelay: - (void(^)(NSDictionary*, int))callback { - NSAssert(started_, @"The controller must be started before " - "getNextReportConfigurationOrSendDelay is called"); - dispatch_async(queue_, ^{ - if (!breakpadRef_) { - callback(nil, -1); - return; - } - int delay = [self sendDelay]; - if (delay != 0) { - callback(nil, delay); - return; - } - [self reportWillBeSent]; - callback(BreakpadGetNextReportConfiguration(breakpadRef_), 0); - }); -} - -#pragma mark - - -- (int)sendDelay { - if (!breakpadRef_ || uploadIntervalInSeconds_ <= 0 || !enableUploads_) - return -1; - - // To prevent overloading the crash server, crashes are not sent than one - // report every |uploadIntervalInSeconds_|. A value in the user defaults is - // used to keep the time of the last upload. - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSNumber *lastTimeNum = [userDefaults objectForKey:kLastSubmission]; - NSTimeInterval lastTime = lastTimeNum ? [lastTimeNum floatValue] : 0; - NSTimeInterval spanSeconds = CFAbsoluteTimeGetCurrent() - lastTime; - - if (spanSeconds >= uploadIntervalInSeconds_) - return 0; - return uploadIntervalInSeconds_ - static_cast(spanSeconds); -} - -- (void)reportWillBeSent { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:[NSNumber numberWithDouble:CFAbsoluteTimeGetCurrent()] - forKey:kLastSubmission]; - [userDefaults synchronize]; -} - -- (void)sendStoredCrashReports { - dispatch_async(queue_, ^{ - if (BreakpadGetCrashReportCount(breakpadRef_) == 0) - return; - - int timeToWait = [self sendDelay]; - - // Unable to ever send report. - if (timeToWait == -1) - return; - - // A report can be sent now. - if (timeToWait == 0) { - [self reportWillBeSent]; - BreakpadUploadNextReportWithParameters(breakpadRef_, - uploadTimeParameters_); - - // If more reports must be sent, make sure this method is called again. - if (BreakpadGetCrashReportCount(breakpadRef_) > 0) - timeToWait = uploadIntervalInSeconds_; - } - - // A report must be sent later. - if (timeToWait > 0) { - // performSelector: doesn't work on queue_ - dispatch_async(dispatch_get_main_queue(), ^{ - [self performSelector:@selector(sendStoredCrashReports) - withObject:nil - afterDelay:timeToWait]; - }); - } - }); -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad_Prefix.pch b/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad_Prefix.pch deleted file mode 100644 index bfb739423..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/Breakpad_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project. -// - -#ifdef __OBJC__ - #import -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h deleted file mode 100644 index 21133e632..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ios_exception_minidump_generator.h: Create a fake minidump from a -// NSException. - -#ifndef CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ -#define CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ - -#include - -#include "client/mac/handler/minidump_generator.h" - -namespace google_breakpad { - -class IosExceptionMinidumpGenerator : public MinidumpGenerator { - public: - explicit IosExceptionMinidumpGenerator(NSException *exception); - virtual ~IosExceptionMinidumpGenerator(); - - protected: - virtual bool WriteExceptionStream(MDRawDirectory *exception_stream); - virtual bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread); - - private: - - // Get the crashing program counter from the exception. - uintptr_t GetPCFromException(); - - // Get the crashing link register from the exception. - uintptr_t GetLRFromException(); - - // Write a virtual thread context for the crashing site. - bool WriteCrashingContext(MDLocationDescriptor *register_location); - // Per-CPU implementations of the above method. -#ifdef HAS_ARM_SUPPORT - bool WriteCrashingContextARM(MDLocationDescriptor *register_location); -#endif -#ifdef HAS_ARM64_SUPPORT - bool WriteCrashingContextARM64(MDLocationDescriptor *register_location); -#endif - - NSArray *return_addresses_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm deleted file mode 100644 index 82ea5bb5d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/ios/handler/ios_exception_minidump_generator.h" - -#include - -#include "google_breakpad/common/minidump_cpu_arm.h" -#include "google_breakpad/common/minidump_cpu_arm64.h" -#include "google_breakpad/common/minidump_exception_mac.h" -#include "client/minidump_file_writer-inl.h" -#include "common/scoped_ptr.h" - -#if defined(HAS_ARM_SUPPORT) && defined(HAS_ARM64_SUPPORT) -#error "This file should be compiled for only one architecture at a time" -#endif - -namespace { - -const int kExceptionType = EXC_SOFTWARE; -const int kExceptionCode = MD_EXCEPTION_CODE_MAC_NS_EXCEPTION; - -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) -const uintptr_t kExpectedFinalFp = sizeof(uintptr_t); -const uintptr_t kExpectedFinalSp = 0; - -// Append the given value to the sp position of the stack represented -// by memory. -void AppendToMemory(uint8_t *memory, uintptr_t sp, uintptr_t data) { - memcpy(memory + sp, &data, sizeof(data)); -} -#endif - -} // namespace - -namespace google_breakpad { - -IosExceptionMinidumpGenerator::IosExceptionMinidumpGenerator( - NSException *exception) - : MinidumpGenerator(mach_task_self(), 0) { - return_addresses_ = [[exception callStackReturnAddresses] retain]; - SetExceptionInformation(kExceptionType, - kExceptionCode, - 0, - pthread_mach_thread_np(pthread_self())); -} - -IosExceptionMinidumpGenerator::~IosExceptionMinidumpGenerator() { - [return_addresses_ release]; -} - -bool IosExceptionMinidumpGenerator::WriteCrashingContext( - MDLocationDescriptor *register_location) { -#ifdef HAS_ARM_SUPPORT - return WriteCrashingContextARM(register_location); -#elif defined(HAS_ARM64_SUPPORT) - return WriteCrashingContextARM64(register_location); -#else - assert(false); - return false; -#endif -} - -#ifdef HAS_ARM_SUPPORT -bool IosExceptionMinidumpGenerator::WriteCrashingContextARM( - MDLocationDescriptor *register_location) { - TypedMDRVA context(&writer_); - if (!context.Allocate()) - return false; - *register_location = context.location(); - MDRawContextARM *context_ptr = context.get(); - memset(context_ptr, 0, sizeof(MDRawContextARM)); - context_ptr->context_flags = MD_CONTEXT_ARM_FULL; - context_ptr->iregs[MD_CONTEXT_ARM_REG_IOS_FP] = kExpectedFinalFp; // FP - context_ptr->iregs[MD_CONTEXT_ARM_REG_SP] = kExpectedFinalSp; // SP - context_ptr->iregs[MD_CONTEXT_ARM_REG_LR] = GetLRFromException(); // LR - context_ptr->iregs[MD_CONTEXT_ARM_REG_PC] = GetPCFromException(); // PC - return true; -} -#endif - -#ifdef HAS_ARM64_SUPPORT -bool IosExceptionMinidumpGenerator::WriteCrashingContextARM64( - MDLocationDescriptor *register_location) { - TypedMDRVA context(&writer_); - if (!context.Allocate()) - return false; - *register_location = context.location(); - MDRawContextARM64 *context_ptr = context.get(); - memset(context_ptr, 0, sizeof(*context_ptr)); - context_ptr->context_flags = MD_CONTEXT_ARM64_FULL; - context_ptr->iregs[MD_CONTEXT_ARM64_REG_FP] = kExpectedFinalFp; // FP - context_ptr->iregs[MD_CONTEXT_ARM64_REG_SP] = kExpectedFinalSp; // SP - context_ptr->iregs[MD_CONTEXT_ARM64_REG_LR] = GetLRFromException(); // LR - context_ptr->iregs[MD_CONTEXT_ARM64_REG_PC] = GetPCFromException(); // PC - return true; -} -#endif - -uintptr_t IosExceptionMinidumpGenerator::GetPCFromException() { - return [[return_addresses_ objectAtIndex:0] unsignedIntegerValue]; -} - -uintptr_t IosExceptionMinidumpGenerator::GetLRFromException() { - return [[return_addresses_ objectAtIndex:1] unsignedIntegerValue]; -} - -bool IosExceptionMinidumpGenerator::WriteExceptionStream( - MDRawDirectory *exception_stream) { -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) - TypedMDRVA exception(&writer_); - - if (!exception.Allocate()) - return false; - - exception_stream->stream_type = MD_EXCEPTION_STREAM; - exception_stream->location = exception.location(); - MDRawExceptionStream *exception_ptr = exception.get(); - exception_ptr->thread_id = pthread_mach_thread_np(pthread_self()); - - // This naming is confusing, but it is the proper translation from - // mach naming to minidump naming. - exception_ptr->exception_record.exception_code = kExceptionType; - exception_ptr->exception_record.exception_flags = kExceptionCode; - - if (!WriteCrashingContext(&exception_ptr->thread_context)) - return false; - - exception_ptr->exception_record.exception_address = GetPCFromException(); - return true; -#else - return MinidumpGenerator::WriteExceptionStream(exception_stream); -#endif -} - -bool IosExceptionMinidumpGenerator::WriteThreadStream(mach_port_t thread_id, - MDRawThread *thread) { -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) - if (pthread_mach_thread_np(pthread_self()) != thread_id) - return MinidumpGenerator::WriteThreadStream(thread_id, thread); - - size_t frame_count = [return_addresses_ count]; - if (frame_count == 0) - return false; - UntypedMDRVA memory(&writer_); - size_t pointer_size = sizeof(uintptr_t); - size_t frame_record_size = 2 * pointer_size; - size_t stack_size = frame_record_size * (frame_count - 1) + pointer_size; - if (!memory.Allocate(stack_size)) - return false; - scoped_array stack_memory(new uint8_t[stack_size]); - uintptr_t sp = stack_size - pointer_size; - uintptr_t fp = 0; - uintptr_t lr = 0; - for (size_t current_frame = frame_count - 1; - current_frame > 0; - --current_frame) { - AppendToMemory(stack_memory.get(), sp, lr); - sp -= pointer_size; - AppendToMemory(stack_memory.get(), sp, fp); - fp = sp; - sp -= pointer_size; - lr = [[return_addresses_ objectAtIndex:current_frame] unsignedIntegerValue]; - } - if (!memory.Copy(stack_memory.get(), stack_size)) - return false; - assert(sp == kExpectedFinalSp); - assert(fp == kExpectedFinalFp); - assert(lr == GetLRFromException()); - thread->stack.start_of_memory_range = sp; - thread->stack.memory = memory.location(); - memory_blocks_.push_back(thread->stack); - - if (!WriteCrashingContext(&thread->thread_context)) - return false; - - thread->thread_id = thread_id; - return true; -#else - return MinidumpGenerator::WriteThreadStream(thread_id, thread); -#endif -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/client_info.h b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/client_info.h deleted file mode 100644 index d0a184a63..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/client_info.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_CRASH_GENERATION_CLIENT_INFO_H_ -#define CLIENT_LINUX_CRASH_GENERATION_CLIENT_INFO_H_ - -namespace google_breakpad { - -class CrashGenerationServer; - -class ClientInfo { - public: - ClientInfo(pid_t pid, CrashGenerationServer* crash_server) - : crash_server_(crash_server), - pid_(pid) {} - - CrashGenerationServer* crash_server() const { return crash_server_; } - pid_t pid() const { return pid_; } - - private: - CrashGenerationServer* crash_server_; - pid_t pid_; -}; - -} - -#endif // CLIENT_LINUX_CRASH_GENERATION_CLIENT_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.cc deleted file mode 100644 index d8bfbbad2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/linux/crash_generation/crash_generation_client.h" - -#include -#include -#include - -#include - -#include "common/linux/eintr_wrapper.h" -#include "common/linux/ignore_ret.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -namespace { - -class CrashGenerationClientImpl : public CrashGenerationClient { - public: - explicit CrashGenerationClientImpl(int server_fd) : server_fd_(server_fd) {} - virtual ~CrashGenerationClientImpl() {} - - virtual bool RequestDump(const void* blob, size_t blob_size) { - int fds[2]; - if (sys_pipe(fds) < 0) - return false; - static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); - - struct kernel_iovec iov; - iov.iov_base = const_cast(blob); - iov.iov_len = blob_size; - - struct kernel_msghdr msg = { 0 }; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - char cmsg[kControlMsgSize] = ""; - msg.msg_control = cmsg; - msg.msg_controllen = sizeof(cmsg); - - struct cmsghdr* hdr = CMSG_FIRSTHDR(&msg); - hdr->cmsg_level = SOL_SOCKET; - hdr->cmsg_type = SCM_RIGHTS; - hdr->cmsg_len = CMSG_LEN(sizeof(int)); - int* p = reinterpret_cast(CMSG_DATA(hdr)); - *p = fds[1]; - - ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0)); - sys_close(fds[1]); - if (ret < 0) { - sys_close(fds[0]); - return false; - } - - // Wait for an ACK from the server. - char b; - IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1))); - sys_close(fds[0]); - - return true; - } - - private: - int server_fd_; - - DISALLOW_COPY_AND_ASSIGN(CrashGenerationClientImpl); -}; - -} // namespace - -// static -CrashGenerationClient* CrashGenerationClient::TryCreate(int server_fd) { - if (server_fd < 0) - return NULL; - return new CrashGenerationClientImpl(server_fd); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.h b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.h deleted file mode 100644 index 4e68424ae..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_client.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ -#define CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ - -#include "common/basictypes.h" - -#include - -namespace google_breakpad { - -// CrashGenerationClient is an interface for implementing out-of-process crash -// dumping. The default implementation, accessed via the TryCreate() factory, -// works in conjunction with the CrashGenerationServer to generate a minidump -// via a remote process. -class CrashGenerationClient { - public: - CrashGenerationClient() {} - virtual ~CrashGenerationClient() {} - - // Request the crash server to generate a dump. |blob| is an opaque - // CrashContext pointer from exception_handler.h. - // Returns true if the dump was successful; false otherwise. - virtual bool RequestDump(const void* blob, size_t blob_size) = 0; - - // Returns a new CrashGenerationClient if |server_fd| is valid and - // connects to a CrashGenerationServer. Otherwise, return NULL. - // The returned CrashGenerationClient* is owned by the caller of - // this function. - static CrashGenerationClient* TryCreate(int server_fd); - - private: - DISALLOW_COPY_AND_ASSIGN(CrashGenerationClient); -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc deleted file mode 100644 index 1d7d93b99..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "client/linux/crash_generation/crash_generation_server.h" -#include "client/linux/crash_generation/client_info.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/guid_creator.h" -#include "common/linux/safe_readlink.h" - -static const char kCommandQuit = 'x'; - -namespace google_breakpad { - -CrashGenerationServer::CrashGenerationServer( - const int listen_fd, - OnClientDumpRequestCallback dump_callback, - void* dump_context, - OnClientExitingCallback exit_callback, - void* exit_context, - bool generate_dumps, - const string* dump_path) : - server_fd_(listen_fd), - dump_callback_(dump_callback), - dump_context_(dump_context), - exit_callback_(exit_callback), - exit_context_(exit_context), - generate_dumps_(generate_dumps), - started_(false) -{ - if (dump_path) - dump_dir_ = *dump_path; - else - dump_dir_ = "/tmp"; -} - -CrashGenerationServer::~CrashGenerationServer() -{ - if (started_) - Stop(); -} - -bool -CrashGenerationServer::Start() -{ - if (started_ || 0 > server_fd_) - return false; - - int control_pipe[2]; - if (pipe(control_pipe)) - return false; - - if (fcntl(control_pipe[0], F_SETFD, FD_CLOEXEC)) - return false; - if (fcntl(control_pipe[1], F_SETFD, FD_CLOEXEC)) - return false; - - if (fcntl(control_pipe[0], F_SETFL, O_NONBLOCK)) - return false; - - control_pipe_in_ = control_pipe[0]; - control_pipe_out_ = control_pipe[1]; - - if (pthread_create(&thread_, NULL, - ThreadMain, reinterpret_cast(this))) - return false; - - started_ = true; - return true; -} - -void -CrashGenerationServer::Stop() -{ - assert(pthread_self() != thread_); - - if (!started_) - return; - - HANDLE_EINTR(write(control_pipe_out_, &kCommandQuit, 1)); - - void* dummy; - pthread_join(thread_, &dummy); - - close(control_pipe_in_); - close(control_pipe_out_); - - started_ = false; -} - -//static -bool -CrashGenerationServer::CreateReportChannel(int* server_fd, int* client_fd) -{ - int fds[2]; - - if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds)) - return false; - - static const int on = 1; - // Enable passcred on the server end of the socket - if (setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) - return false; - - if (fcntl(fds[1], F_SETFL, O_NONBLOCK)) - return false; - if (fcntl(fds[1], F_SETFD, FD_CLOEXEC)) - return false; - - *client_fd = fds[0]; - *server_fd = fds[1]; - return true; -} - -// The following methods/functions execute on the server thread - -void -CrashGenerationServer::Run() -{ - struct pollfd pollfds[2]; - memset(&pollfds, 0, sizeof(pollfds)); - - pollfds[0].fd = server_fd_; - pollfds[0].events = POLLIN; - - pollfds[1].fd = control_pipe_in_; - pollfds[1].events = POLLIN; - - while (true) { - // infinite timeout - int nevents = poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), -1); - if (-1 == nevents) { - if (EINTR == errno) { - continue; - } else { - return; - } - } - - if (pollfds[0].revents && !ClientEvent(pollfds[0].revents)) - return; - - if (pollfds[1].revents && !ControlEvent(pollfds[1].revents)) - return; - } -} - -bool -CrashGenerationServer::ClientEvent(short revents) -{ - if (POLLHUP & revents) - return false; - assert(POLLIN & revents); - - // A process has crashed and has signaled us by writing a datagram - // to the death signal socket. The datagram contains the crash context needed - // for writing the minidump as well as a file descriptor and a credentials - // block so that they can't lie about their pid. - - // The length of the control message: - static const unsigned kControlMsgSize = - CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); - // The length of the regular payload: - static const unsigned kCrashContextSize = - sizeof(google_breakpad::ExceptionHandler::CrashContext); - - struct msghdr msg = {0}; - struct iovec iov[1]; - char crash_context[kCrashContextSize]; - char control[kControlMsgSize]; - const ssize_t expected_msg_size = sizeof(crash_context); - - iov[0].iov_base = crash_context; - iov[0].iov_len = sizeof(crash_context); - msg.msg_iov = iov; - msg.msg_iovlen = sizeof(iov)/sizeof(iov[0]); - msg.msg_control = control; - msg.msg_controllen = kControlMsgSize; - - const ssize_t msg_size = HANDLE_EINTR(recvmsg(server_fd_, &msg, 0)); - if (msg_size != expected_msg_size) - return true; - - if (msg.msg_controllen != kControlMsgSize || - msg.msg_flags & ~MSG_TRUNC) - return true; - - // Walk the control payload and extract the file descriptor and validated pid. - pid_t crashing_pid = -1; - int signal_fd = -1; - for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; - hdr = CMSG_NXTHDR(&msg, hdr)) { - if (hdr->cmsg_level != SOL_SOCKET) - continue; - if (hdr->cmsg_type == SCM_RIGHTS) { - const unsigned len = hdr->cmsg_len - - (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr); - assert(len % sizeof(int) == 0u); - const unsigned num_fds = len / sizeof(int); - if (num_fds > 1 || num_fds == 0) { - // A nasty process could try and send us too many descriptors and - // force a leak. - for (unsigned i = 0; i < num_fds; ++i) - close(reinterpret_cast(CMSG_DATA(hdr))[i]); - return true; - } else { - signal_fd = reinterpret_cast(CMSG_DATA(hdr))[0]; - } - } else if (hdr->cmsg_type == SCM_CREDENTIALS) { - const struct ucred *cred = - reinterpret_cast(CMSG_DATA(hdr)); - crashing_pid = cred->pid; - } - } - - if (crashing_pid == -1 || signal_fd == -1) { - if (signal_fd) - close(signal_fd); - return true; - } - - string minidump_filename; - if (!MakeMinidumpFilename(minidump_filename)) - return true; - - if (!google_breakpad::WriteMinidump(minidump_filename.c_str(), - crashing_pid, crash_context, - kCrashContextSize)) { - close(signal_fd); - return true; - } - - if (dump_callback_) { - ClientInfo info(crashing_pid, this); - - dump_callback_(dump_context_, &info, &minidump_filename); - } - - // Send the done signal to the process: it can exit now. - // (Closing this will make the child's sys_read unblock and return 0.) - close(signal_fd); - - return true; -} - -bool -CrashGenerationServer::ControlEvent(short revents) -{ - if (POLLHUP & revents) - return false; - assert(POLLIN & revents); - - char command; - if (read(control_pipe_in_, &command, 1)) - return false; - - switch (command) { - case kCommandQuit: - return false; - default: - assert(0); - } - - return true; -} - -bool -CrashGenerationServer::MakeMinidumpFilename(string& outFilename) -{ - GUID guid; - char guidString[kGUIDStringLength+1]; - - if (!(CreateGUID(&guid) - && GUIDToString(&guid, guidString, sizeof(guidString)))) - return false; - - char path[PATH_MAX]; - snprintf(path, sizeof(path), "%s/%s.dmp", dump_dir_.c_str(), guidString); - - outFilename = path; - return true; -} - -// static -void* -CrashGenerationServer::ThreadMain(void *arg) -{ - reinterpret_cast(arg)->Run(); - return NULL; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.h b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.h deleted file mode 100644 index 483fb709b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.h +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ -#define CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ - -#include - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -class ClientInfo; - -class CrashGenerationServer { -public: - // WARNING: callbacks may be invoked on a different thread - // than that which creates the CrashGenerationServer. They must - // be thread safe. - typedef void (*OnClientDumpRequestCallback)(void* context, - const ClientInfo* client_info, - const string* file_path); - - typedef void (*OnClientExitingCallback)(void* context, - const ClientInfo* client_info); - - // Create an instance with the given parameters. - // - // Parameter listen_fd: The server fd created by CreateReportChannel(). - // Parameter dump_callback: Callback for a client crash dump request. - // Parameter dump_context: Context for client crash dump request callback. - // Parameter exit_callback: Callback for client process exit. - // Parameter exit_context: Context for client exit callback. - // Parameter generate_dumps: Whether to automatically generate dumps. - // Client code of this class might want to generate dumps explicitly - // in the crash dump request callback. In that case, false can be - // passed for this parameter. - // Parameter dump_path: Path for generating dumps; required only if true is - // passed for generateDumps parameter; NULL can be passed otherwise. - CrashGenerationServer(const int listen_fd, - OnClientDumpRequestCallback dump_callback, - void* dump_context, - OnClientExitingCallback exit_callback, - void* exit_context, - bool generate_dumps, - const string* dump_path); - - ~CrashGenerationServer(); - - // Perform initialization steps needed to start listening to clients. - // - // Return true if initialization is successful; false otherwise. - bool Start(); - - // Stop the server. - void Stop(); - - // Create a "channel" that can be used by clients to report crashes - // to a CrashGenerationServer. |*server_fd| should be passed to - // this class's constructor, and |*client_fd| should be passed to - // the ExceptionHandler constructor in the client process. - static bool CreateReportChannel(int* server_fd, int* client_fd); - -private: - // Run the server's event loop - void Run(); - - // Invoked when an child process (client) event occurs - // Returning true => "keep running", false => "exit loop" - bool ClientEvent(short revents); - - // Invoked when the controlling thread (main) event occurs - // Returning true => "keep running", false => "exit loop" - bool ControlEvent(short revents); - - // Return a unique filename at which a minidump can be written - bool MakeMinidumpFilename(string& outFilename); - - // Trampoline to |Run()| - static void* ThreadMain(void* arg); - - int server_fd_; - - OnClientDumpRequestCallback dump_callback_; - void* dump_context_; - - OnClientExitingCallback exit_callback_; - void* exit_context_; - - bool generate_dumps_; - - string dump_dir_; - - bool started_; - - pthread_t thread_; - int control_pipe_in_; - int control_pipe_out_; - - // disable these - CrashGenerationServer(const CrashGenerationServer&); - CrashGenerationServer& operator=(const CrashGenerationServer&); -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-amd.sym b/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-amd.sym deleted file mode 100644 index e042a5ec4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-amd.sym +++ /dev/null @@ -1,3 +0,0 @@ -MODULE Linux x86 B8CFDE93002D54DA1900A40AA1BD67690 linux-gate.so -PUBLIC 400 0 __kernel_vsyscall -STACK WIN 4 400 100 1 1 0 0 0 0 0 1 diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-intel.sym b/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-intel.sym deleted file mode 100644 index c209c2375..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-intel.sym +++ /dev/null @@ -1,3 +0,0 @@ -MODULE Linux x86 4FBDA58B5A1DF5A379E3CF19A235EA090 linux-gate.so -PUBLIC 400 0 __kernel_vsyscall -STACK WIN 4 400 200 3 3 0 0 0 0 0 1 \ No newline at end of file diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/mapping_info.h b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/mapping_info.h deleted file mode 100644 index 5f247cfd4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/mapping_info.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ -#define CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ - -#include -#include -#include - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// One of these is produced for each mapping in the process (i.e. line in -// /proc/$x/maps). -struct MappingInfo { - uintptr_t start_addr; - size_t size; - size_t offset; // offset into the backed file. - bool exec; // true if the mapping has the execute bit set. - char name[NAME_MAX]; -}; - -struct MappingEntry { - MappingInfo first; - uint8_t second[sizeof(MDGUID)]; -}; - -// A list of -typedef std::list MappingList; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/raw_context_cpu.h b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/raw_context_cpu.h deleted file mode 100644 index e2ef45df5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/raw_context_cpu.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H -#define CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -#if defined(__i386__) -typedef MDRawContextX86 RawContextCPU; -#elif defined(__x86_64) -typedef MDRawContextAMD64 RawContextCPU; -#elif defined(__ARM_EABI__) -typedef MDRawContextARM RawContextCPU; -#elif defined(__aarch64__) -typedef MDRawContextARM64 RawContextCPU; -#elif defined(__mips__) -typedef MDRawContextMIPS RawContextCPU; -#else -#error "This code has not been ported to your platform yet." -#endif - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_DUMP_WRITER_COMMON_RAW_CONTEXT_CPU_H diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.cc deleted file mode 100644 index 0a1041d62..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.cc +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/linux/dump_writer_common/thread_info.h" - -#include -#include - -#include "common/linux/linux_libc_support.h" -#include "google_breakpad/common/minidump_format.h" - -namespace { - -#if defined(__i386__) -// Write a uint16_t to memory -// out: memory location to write to -// v: value to write. -void U16(void* out, uint16_t v) { - my_memcpy(out, &v, sizeof(v)); -} - -// Write a uint32_t to memory -// out: memory location to write to -// v: value to write. -void U32(void* out, uint32_t v) { - my_memcpy(out, &v, sizeof(v)); -} -#endif - -} - -namespace google_breakpad { - -#if defined(__i386__) - -uintptr_t ThreadInfo::GetInstructionPointer() const { - return regs.eip; -} - -void ThreadInfo::FillCPUContext(RawContextCPU* out) const { - out->context_flags = MD_CONTEXT_X86_ALL; - - out->dr0 = dregs[0]; - out->dr1 = dregs[1]; - out->dr2 = dregs[2]; - out->dr3 = dregs[3]; - // 4 and 5 deliberatly omitted because they aren't included in the minidump - // format. - out->dr6 = dregs[6]; - out->dr7 = dregs[7]; - - out->gs = regs.xgs; - out->fs = regs.xfs; - out->es = regs.xes; - out->ds = regs.xds; - - out->edi = regs.edi; - out->esi = regs.esi; - out->ebx = regs.ebx; - out->edx = regs.edx; - out->ecx = regs.ecx; - out->eax = regs.eax; - - out->ebp = regs.ebp; - out->eip = regs.eip; - out->cs = regs.xcs; - out->eflags = regs.eflags; - out->esp = regs.esp; - out->ss = regs.xss; - - out->float_save.control_word = fpregs.cwd; - out->float_save.status_word = fpregs.swd; - out->float_save.tag_word = fpregs.twd; - out->float_save.error_offset = fpregs.fip; - out->float_save.error_selector = fpregs.fcs; - out->float_save.data_offset = fpregs.foo; - out->float_save.data_selector = fpregs.fos; - - // 8 registers * 10 bytes per register. - my_memcpy(out->float_save.register_area, fpregs.st_space, 10 * 8); - - // This matches the Intel fpsave format. - U16(out->extended_registers + 0, fpregs.cwd); - U16(out->extended_registers + 2, fpregs.swd); - U16(out->extended_registers + 4, fpregs.twd); - U16(out->extended_registers + 6, fpxregs.fop); - U32(out->extended_registers + 8, fpxregs.fip); - U16(out->extended_registers + 12, fpxregs.fcs); - U32(out->extended_registers + 16, fpregs.foo); - U16(out->extended_registers + 20, fpregs.fos); - U32(out->extended_registers + 24, fpxregs.mxcsr); - - my_memcpy(out->extended_registers + 32, &fpxregs.st_space, 128); - my_memcpy(out->extended_registers + 160, &fpxregs.xmm_space, 128); -} - -#elif defined(__x86_64) - -uintptr_t ThreadInfo::GetInstructionPointer() const { - return regs.rip; -} - -void ThreadInfo::FillCPUContext(RawContextCPU* out) const { - out->context_flags = MD_CONTEXT_AMD64_FULL | - MD_CONTEXT_AMD64_SEGMENTS; - - out->cs = regs.cs; - - out->ds = regs.ds; - out->es = regs.es; - out->fs = regs.fs; - out->gs = regs.gs; - - out->ss = regs.ss; - out->eflags = regs.eflags; - - out->dr0 = dregs[0]; - out->dr1 = dregs[1]; - out->dr2 = dregs[2]; - out->dr3 = dregs[3]; - // 4 and 5 deliberatly omitted because they aren't included in the minidump - // format. - out->dr6 = dregs[6]; - out->dr7 = dregs[7]; - - out->rax = regs.rax; - out->rcx = regs.rcx; - out->rdx = regs.rdx; - out->rbx = regs.rbx; - - out->rsp = regs.rsp; - - out->rbp = regs.rbp; - out->rsi = regs.rsi; - out->rdi = regs.rdi; - out->r8 = regs.r8; - out->r9 = regs.r9; - out->r10 = regs.r10; - out->r11 = regs.r11; - out->r12 = regs.r12; - out->r13 = regs.r13; - out->r14 = regs.r14; - out->r15 = regs.r15; - - out->rip = regs.rip; - - out->flt_save.control_word = fpregs.cwd; - out->flt_save.status_word = fpregs.swd; - out->flt_save.tag_word = fpregs.ftw; - out->flt_save.error_opcode = fpregs.fop; - out->flt_save.error_offset = fpregs.rip; - out->flt_save.error_selector = 0; // We don't have this. - out->flt_save.data_offset = fpregs.rdp; - out->flt_save.data_selector = 0; // We don't have this. - out->flt_save.mx_csr = fpregs.mxcsr; - out->flt_save.mx_csr_mask = fpregs.mxcr_mask; - - my_memcpy(&out->flt_save.float_registers, &fpregs.st_space, 8 * 16); - my_memcpy(&out->flt_save.xmm_registers, &fpregs.xmm_space, 16 * 16); -} - -#elif defined(__ARM_EABI__) - -uintptr_t ThreadInfo::GetInstructionPointer() const { - return regs.uregs[15]; -} - -void ThreadInfo::FillCPUContext(RawContextCPU* out) const { - out->context_flags = MD_CONTEXT_ARM_FULL; - - for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i) - out->iregs[i] = regs.uregs[i]; - // No CPSR register in ThreadInfo(it's not accessible via ptrace) - out->cpsr = 0; -#if !defined(__ANDROID__) - out->float_save.fpscr = fpregs.fpsr | - (static_cast(fpregs.fpcr) << 32); - // TODO: sort this out, actually collect floating point registers - my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs)); - my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra)); -#endif -} - -#elif defined(__aarch64__) - -uintptr_t ThreadInfo::GetInstructionPointer() const { - return regs.pc; -} - -void ThreadInfo::FillCPUContext(RawContextCPU* out) const { - out->context_flags = MD_CONTEXT_ARM64_FULL; - - out->cpsr = static_cast(regs.pstate); - for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i) - out->iregs[i] = regs.regs[i]; - out->iregs[MD_CONTEXT_ARM64_REG_SP] = regs.sp; - out->iregs[MD_CONTEXT_ARM64_REG_PC] = regs.pc; - - out->float_save.fpsr = fpregs.fpsr; - out->float_save.fpcr = fpregs.fpcr; - my_memcpy(&out->float_save.regs, &fpregs.vregs, - MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16); -} - -#elif defined(__mips__) - -uintptr_t ThreadInfo::GetInstructionPointer() const { - return mcontext.pc; -} - -void ThreadInfo::FillCPUContext(RawContextCPU* out) const { -#if _MIPS_SIM == _ABI64 - out->context_flags = MD_CONTEXT_MIPS64_FULL; -#elif _MIPS_SIM == _ABIO32 - out->context_flags = MD_CONTEXT_MIPS_FULL; -#else -# error "This mips ABI is currently not supported (n32)" -#endif - - for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i) - out->iregs[i] = mcontext.gregs[i]; - - out->mdhi = mcontext.mdhi; - out->mdlo = mcontext.mdlo; - out->dsp_control = mcontext.dsp; - - out->hi[0] = mcontext.hi1; - out->lo[0] = mcontext.lo1; - out->hi[1] = mcontext.hi2; - out->lo[1] = mcontext.lo2; - out->hi[2] = mcontext.hi3; - out->lo[2] = mcontext.lo3; - - out->epc = mcontext.pc; - out->badvaddr = 0; // Not stored in mcontext - out->status = 0; // Not stored in mcontext - out->cause = 0; // Not stored in mcontext - - for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) - out->float_save.regs[i] = mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs; - - out->float_save.fpcsr = mcontext.fpc_csr; -#if _MIPS_SIM == _ABIO32 - out->float_save.fir = mcontext.fpc_eir; -#endif -} -#endif // __mips__ - -void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) { - assert(gp_regs || size); -#if defined(__mips__) - if (gp_regs) - *gp_regs = mcontext.gregs; - if (size) - *size = sizeof(mcontext.gregs); -#else - if (gp_regs) - *gp_regs = ®s; - if (size) - *size = sizeof(regs); -#endif -} - -void ThreadInfo::GetFloatingPointRegisters(void** fp_regs, size_t* size) { - assert(fp_regs || size); -#if defined(__mips__) - if (fp_regs) - *fp_regs = &mcontext.fpregs; - if (size) - *size = sizeof(mcontext.fpregs); -#else - if (fp_regs) - *fp_regs = &fpregs; - if (size) - *size = sizeof(fpregs); -#endif -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.h b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.h deleted file mode 100644 index 99093d2e0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/thread_info.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_ -#define CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_ - -#include -#include - -#include "client/linux/dump_writer_common/raw_context_cpu.h" -#include "common/memory.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -#if defined(__i386) || defined(__x86_64) -typedef __typeof__(((struct user*) 0)->u_debugreg[0]) debugreg_t; -#endif - -// We produce one of these structures for each thread in the crashed process. -struct ThreadInfo { - pid_t tgid; // thread group id - pid_t ppid; // parent process - - uintptr_t stack_pointer; // thread stack pointer - - -#if defined(__i386) || defined(__x86_64) - user_regs_struct regs; - user_fpregs_struct fpregs; - static const unsigned kNumDebugRegisters = 8; - debugreg_t dregs[8]; -#if defined(__i386) - user_fpxregs_struct fpxregs; -#endif // defined(__i386) - -#elif defined(__ARM_EABI__) - // Mimicking how strace does this(see syscall.c, search for GETREGS) - struct user_regs regs; - struct user_fpregs fpregs; -#elif defined(__aarch64__) - // Use the structures defined in - struct user_regs_struct regs; - struct user_fpsimd_struct fpregs; -#elif defined(__mips__) - // Use the structure defined in . - mcontext_t mcontext; -#endif - - // Returns the instruction pointer (platform-dependent impl.). - uintptr_t GetInstructionPointer() const; - - // Fills a RawContextCPU using the context in the ThreadInfo object. - void FillCPUContext(RawContextCPU* out) const; - - // Returns the pointer and size of general purpose register area. - void GetGeneralPurposeRegisters(void** gp_regs, size_t* size); - - // Returns the pointer and size of float point register area. - void GetFloatingPointRegisters(void** fp_regs, size_t* size); -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_DUMP_WRITER_COMMON_THREAD_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.cc deleted file mode 100644 index 93b4d9f85..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.cc +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/linux/dump_writer_common/ucontext_reader.h" - -#include "common/linux/linux_libc_support.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Minidump defines register structures which are different from the raw -// structures which we get from the kernel. These are platform specific -// functions to juggle the ucontext and user structures into minidump format. - -#if defined(__i386__) - -uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) { - return uc->uc_mcontext.gregs[REG_ESP]; -} - -uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) { - return uc->uc_mcontext.gregs[REG_EIP]; -} - -void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext_t *uc, - const struct _libc_fpstate* fp) { - const greg_t* regs = uc->uc_mcontext.gregs; - - out->context_flags = MD_CONTEXT_X86_FULL | - MD_CONTEXT_X86_FLOATING_POINT; - - out->gs = regs[REG_GS]; - out->fs = regs[REG_FS]; - out->es = regs[REG_ES]; - out->ds = regs[REG_DS]; - - out->edi = regs[REG_EDI]; - out->esi = regs[REG_ESI]; - out->ebx = regs[REG_EBX]; - out->edx = regs[REG_EDX]; - out->ecx = regs[REG_ECX]; - out->eax = regs[REG_EAX]; - - out->ebp = regs[REG_EBP]; - out->eip = regs[REG_EIP]; - out->cs = regs[REG_CS]; - out->eflags = regs[REG_EFL]; - out->esp = regs[REG_UESP]; - out->ss = regs[REG_SS]; - - out->float_save.control_word = fp->cw; - out->float_save.status_word = fp->sw; - out->float_save.tag_word = fp->tag; - out->float_save.error_offset = fp->ipoff; - out->float_save.error_selector = fp->cssel; - out->float_save.data_offset = fp->dataoff; - out->float_save.data_selector = fp->datasel; - - // 8 registers * 10 bytes per register. - my_memcpy(out->float_save.register_area, fp->_st, 10 * 8); -} - -#elif defined(__x86_64) - -uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) { - return uc->uc_mcontext.gregs[REG_RSP]; -} - -uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) { - return uc->uc_mcontext.gregs[REG_RIP]; -} - -void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext_t *uc, - const struct _libc_fpstate* fpregs) { - const greg_t* regs = uc->uc_mcontext.gregs; - - out->context_flags = MD_CONTEXT_AMD64_FULL; - - out->cs = regs[REG_CSGSFS] & 0xffff; - - out->fs = (regs[REG_CSGSFS] >> 32) & 0xffff; - out->gs = (regs[REG_CSGSFS] >> 16) & 0xffff; - - out->eflags = regs[REG_EFL]; - - out->rax = regs[REG_RAX]; - out->rcx = regs[REG_RCX]; - out->rdx = regs[REG_RDX]; - out->rbx = regs[REG_RBX]; - - out->rsp = regs[REG_RSP]; - out->rbp = regs[REG_RBP]; - out->rsi = regs[REG_RSI]; - out->rdi = regs[REG_RDI]; - out->r8 = regs[REG_R8]; - out->r9 = regs[REG_R9]; - out->r10 = regs[REG_R10]; - out->r11 = regs[REG_R11]; - out->r12 = regs[REG_R12]; - out->r13 = regs[REG_R13]; - out->r14 = regs[REG_R14]; - out->r15 = regs[REG_R15]; - - out->rip = regs[REG_RIP]; - - out->flt_save.control_word = fpregs->cwd; - out->flt_save.status_word = fpregs->swd; - out->flt_save.tag_word = fpregs->ftw; - out->flt_save.error_opcode = fpregs->fop; - out->flt_save.error_offset = fpregs->rip; - out->flt_save.data_offset = fpregs->rdp; - out->flt_save.error_selector = 0; // We don't have this. - out->flt_save.data_selector = 0; // We don't have this. - out->flt_save.mx_csr = fpregs->mxcsr; - out->flt_save.mx_csr_mask = fpregs->mxcr_mask; - my_memcpy(&out->flt_save.float_registers, &fpregs->_st, 8 * 16); - my_memcpy(&out->flt_save.xmm_registers, &fpregs->_xmm, 16 * 16); -} - -#elif defined(__ARM_EABI__) - -uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) { - return uc->uc_mcontext.arm_sp; -} - -uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) { - return uc->uc_mcontext.arm_pc; -} - -void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext_t *uc) { - out->context_flags = MD_CONTEXT_ARM_FULL; - - out->iregs[0] = uc->uc_mcontext.arm_r0; - out->iregs[1] = uc->uc_mcontext.arm_r1; - out->iregs[2] = uc->uc_mcontext.arm_r2; - out->iregs[3] = uc->uc_mcontext.arm_r3; - out->iregs[4] = uc->uc_mcontext.arm_r4; - out->iregs[5] = uc->uc_mcontext.arm_r5; - out->iregs[6] = uc->uc_mcontext.arm_r6; - out->iregs[7] = uc->uc_mcontext.arm_r7; - out->iregs[8] = uc->uc_mcontext.arm_r8; - out->iregs[9] = uc->uc_mcontext.arm_r9; - out->iregs[10] = uc->uc_mcontext.arm_r10; - - out->iregs[11] = uc->uc_mcontext.arm_fp; - out->iregs[12] = uc->uc_mcontext.arm_ip; - out->iregs[13] = uc->uc_mcontext.arm_sp; - out->iregs[14] = uc->uc_mcontext.arm_lr; - out->iregs[15] = uc->uc_mcontext.arm_pc; - - out->cpsr = uc->uc_mcontext.arm_cpsr; - - // TODO: fix this after fixing ExceptionHandler - out->float_save.fpscr = 0; - my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs)); - my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra)); -} - -#elif defined(__aarch64__) - -uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) { - return uc->uc_mcontext.sp; -} - -uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) { - return uc->uc_mcontext.pc; -} - -void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext_t *uc, - const struct fpsimd_context* fpregs) { - out->context_flags = MD_CONTEXT_ARM64_FULL; - - out->cpsr = static_cast(uc->uc_mcontext.pstate); - for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i) - out->iregs[i] = uc->uc_mcontext.regs[i]; - out->iregs[MD_CONTEXT_ARM64_REG_SP] = uc->uc_mcontext.sp; - out->iregs[MD_CONTEXT_ARM64_REG_PC] = uc->uc_mcontext.pc; - - out->float_save.fpsr = fpregs->fpsr; - out->float_save.fpcr = fpregs->fpcr; - my_memcpy(&out->float_save.regs, &fpregs->vregs, - MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16); -} - -#elif defined(__mips__) - -uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) { - return uc->uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]; -} - -uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) { - return uc->uc_mcontext.pc; -} - -void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext_t *uc) { -#if _MIPS_SIM == _ABI64 - out->context_flags = MD_CONTEXT_MIPS64_FULL; -#elif _MIPS_SIM == _ABIO32 - out->context_flags = MD_CONTEXT_MIPS_FULL; -#else -#error "This mips ABI is currently not supported (n32)" -#endif - - for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i) - out->iregs[i] = uc->uc_mcontext.gregs[i]; - - out->mdhi = uc->uc_mcontext.mdhi; - out->mdlo = uc->uc_mcontext.mdlo; - - out->hi[0] = uc->uc_mcontext.hi1; - out->hi[1] = uc->uc_mcontext.hi2; - out->hi[2] = uc->uc_mcontext.hi3; - out->lo[0] = uc->uc_mcontext.lo1; - out->lo[1] = uc->uc_mcontext.lo2; - out->lo[2] = uc->uc_mcontext.lo3; - out->dsp_control = uc->uc_mcontext.dsp; - - out->epc = uc->uc_mcontext.pc; - out->badvaddr = 0; // Not reported in signal context. - out->status = 0; // Not reported in signal context. - out->cause = 0; // Not reported in signal context. - - for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) - out->float_save.regs[i] = uc->uc_mcontext.fpregs.fp_r.fp_dregs[i]; - - out->float_save.fpcsr = uc->uc_mcontext.fpc_csr; -#if _MIPS_SIM == _ABIO32 - out->float_save.fir = uc->uc_mcontext.fpc_eir; // Unused. -#endif -} -#endif - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.h b/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.h deleted file mode 100644 index 2369a9ad3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/dump_writer_common/ucontext_reader.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H -#define CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H - -#include -#include - -#include "client/linux/dump_writer_common/raw_context_cpu.h" -#include "common/memory.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Wraps platform-dependent implementations of accessors to ucontext structs. -struct UContextReader { - static uintptr_t GetStackPointer(const ucontext_t* uc); - - static uintptr_t GetInstructionPointer(const ucontext_t* uc); - - // Juggle a arch-specific ucontext into a minidump format - // out: the minidump structure - // info: the collection of register structures. -#if defined(__i386__) || defined(__x86_64) - static void FillCPUContext(RawContextCPU *out, const ucontext_t *uc, - const struct _libc_fpstate* fp); -#elif defined(__aarch64__) - static void FillCPUContext(RawContextCPU *out, const ucontext_t *uc, - const struct fpsimd_context* fpregs); -#else - static void FillCPUContext(RawContextCPU *out, const ucontext_t *uc); -#endif -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_DUMP_WRITER_COMMON_UCONTEXT_READER_H diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc deleted file mode 100644 index 288e0bb69..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc +++ /dev/null @@ -1,789 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The ExceptionHandler object installs signal handlers for a number of -// signals. We rely on the signal handler running on the thread which crashed -// in order to identify it. This is true of the synchronous signals (SEGV etc), -// but not true of ABRT. Thus, if you send ABRT to yourself in a program which -// uses ExceptionHandler, you need to use tgkill to direct it to the current -// thread. -// -// The signal flow looks like this: -// -// SignalHandler (uses a global stack of ExceptionHandler objects to find -// | one to handle the signal. If the first rejects it, try -// | the second etc...) -// V -// HandleSignal ----------------------------| (clones a new process which -// | | shares an address space with -// (wait for cloned | the crashed process. This -// process) | allows us to ptrace the crashed -// | | process) -// V V -// (set signal handler to ThreadEntry (static function to bounce -// SIG_DFL and rethrow, | back into the object) -// killing the crashed | -// process) V -// DoDump (writes minidump) -// | -// V -// sys_exit -// - -// This code is a little fragmented. Different functions of the ExceptionHandler -// class run in a number of different contexts. Some of them run in a normal -// context and are easy to code, others run in a compromised context and the -// restrictions at the top of minidump_writer.cc apply: no libc and use the -// alternative malloc. Each function should have comment above it detailing the -// context which it runs in. - -#include "client/linux/handler/exception_handler.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "common/basictypes.h" -#include "common/linux/linux_libc_support.h" -#include "common/memory.h" -#include "client/linux/log/log.h" -#include "client/linux/microdump_writer/microdump_writer.h" -#include "client/linux/minidump_writer/linux_dumper.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "common/linux/eintr_wrapper.h" -#include "third_party/lss/linux_syscall_support.h" - -#if defined(__ANDROID__) -#include "linux/sched.h" -#endif - -#ifndef PR_SET_PTRACER -#define PR_SET_PTRACER 0x59616d61 -#endif - -// A wrapper for the tgkill syscall: send a signal to a specific thread. -static int tgkill(pid_t tgid, pid_t tid, int sig) { - return syscall(__NR_tgkill, tgid, tid, sig); - return 0; -} - -namespace google_breakpad { - -namespace { -// The list of signals which we consider to be crashes. The default action for -// all these signals must be Core (see man 7 signal) because we rethrow the -// signal after handling it and expect that it'll be fatal. -const int kExceptionSignals[] = { - SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGTRAP -}; -const int kNumHandledSignals = - sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]); -struct sigaction old_handlers[kNumHandledSignals]; -bool handlers_installed = false; - -// InstallAlternateStackLocked will store the newly installed stack in new_stack -// and (if it exists) the previously installed stack in old_stack. -stack_t old_stack; -stack_t new_stack; -bool stack_installed = false; - -// Create an alternative stack to run the signal handlers on. This is done since -// the signal might have been caused by a stack overflow. -// Runs before crashing: normal context. -void InstallAlternateStackLocked() { - if (stack_installed) - return; - - memset(&old_stack, 0, sizeof(old_stack)); - memset(&new_stack, 0, sizeof(new_stack)); - - // SIGSTKSZ may be too small to prevent the signal handlers from overrunning - // the alternative stack. Ensure that the size of the alternative stack is - // large enough. - static const unsigned kSigStackSize = std::max(16384, SIGSTKSZ); - - // Only set an alternative stack if there isn't already one, or if the current - // one is too small. - if (sys_sigaltstack(NULL, &old_stack) == -1 || !old_stack.ss_sp || - old_stack.ss_size < kSigStackSize) { - new_stack.ss_sp = calloc(1, kSigStackSize); - new_stack.ss_size = kSigStackSize; - - if (sys_sigaltstack(&new_stack, NULL) == -1) { - free(new_stack.ss_sp); - return; - } - stack_installed = true; - } -} - -// Runs before crashing: normal context. -void RestoreAlternateStackLocked() { - if (!stack_installed) - return; - - stack_t current_stack; - if (sys_sigaltstack(NULL, ¤t_stack) == -1) - return; - - // Only restore the old_stack if the current alternative stack is the one - // installed by the call to InstallAlternateStackLocked. - if (current_stack.ss_sp == new_stack.ss_sp) { - if (old_stack.ss_sp) { - if (sys_sigaltstack(&old_stack, NULL) == -1) - return; - } else { - stack_t disable_stack; - disable_stack.ss_flags = SS_DISABLE; - if (sys_sigaltstack(&disable_stack, NULL) == -1) - return; - } - } - - free(new_stack.ss_sp); - stack_installed = false; -} - -void InstallDefaultHandler(int sig) { -#if defined(__ANDROID__) - // Android L+ expose signal and sigaction symbols that override the system - // ones. There is a bug in these functions where a request to set the handler - // to SIG_DFL is ignored. In that case, an infinite loop is entered as the - // signal is repeatedly sent to breakpad's signal handler. - // To work around this, directly call the system's sigaction. - struct kernel_sigaction sa; - memset(&sa, 0, sizeof(sa)); - sys_sigemptyset(&sa.sa_mask); - sa.sa_handler_ = SIG_DFL; - sa.sa_flags = SA_RESTART; - sys_rt_sigaction(sig, &sa, NULL, sizeof(kernel_sigset_t)); -#else - signal(sig, SIG_DFL); -#endif -} - -// The global exception handler stack. This is needed because there may exist -// multiple ExceptionHandler instances in a process. Each will have itself -// registered in this stack. -std::vector* g_handler_stack_ = NULL; -pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER; - -// sizeof(CrashContext) can be too big w.r.t the size of alternatate stack -// for SignalHandler(). Keep the crash context as a .bss field. Exception -// handlers are serialized by the |g_handler_stack_mutex_| and at most one at a -// time can use |g_crash_context_|. -ExceptionHandler::CrashContext g_crash_context_; - -} // namespace - -// Runs before crashing: normal context. -ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - bool install_handler, - const int server_fd) - : filter_(filter), - callback_(callback), - callback_context_(callback_context), - minidump_descriptor_(descriptor), - crash_handler_(NULL) { - if (server_fd >= 0) - crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd)); - - if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() && - !minidump_descriptor_.IsMicrodumpOnConsole()) - minidump_descriptor_.UpdatePath(); - -#if defined(__ANDROID__) - if (minidump_descriptor_.IsMicrodumpOnConsole()) - logger::initializeCrashLogWriter(); -#endif - - pthread_mutex_lock(&g_handler_stack_mutex_); - - // Pre-fault the crash context struct. This is to avoid failing due to OOM - // if handling an exception when the process ran out of virtual memory. - memset(&g_crash_context_, 0, sizeof(g_crash_context_)); - - if (!g_handler_stack_) - g_handler_stack_ = new std::vector; - if (install_handler) { - InstallAlternateStackLocked(); - InstallHandlersLocked(); - } - g_handler_stack_->push_back(this); - pthread_mutex_unlock(&g_handler_stack_mutex_); -} - -// Runs before crashing: normal context. -ExceptionHandler::~ExceptionHandler() { - pthread_mutex_lock(&g_handler_stack_mutex_); - std::vector::iterator handler = - std::find(g_handler_stack_->begin(), g_handler_stack_->end(), this); - g_handler_stack_->erase(handler); - if (g_handler_stack_->empty()) { - delete g_handler_stack_; - g_handler_stack_ = NULL; - RestoreAlternateStackLocked(); - RestoreHandlersLocked(); - } - pthread_mutex_unlock(&g_handler_stack_mutex_); -} - -// Runs before crashing: normal context. -// static -bool ExceptionHandler::InstallHandlersLocked() { - if (handlers_installed) - return false; - - // Fail if unable to store all the old handlers. - for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], NULL, &old_handlers[i]) == -1) - return false; - } - - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - - // Mask all exception signals when we're handling one of them. - for (int i = 0; i < kNumHandledSignals; ++i) - sigaddset(&sa.sa_mask, kExceptionSignals[i]); - - sa.sa_sigaction = SignalHandler; - sa.sa_flags = SA_ONSTACK | SA_SIGINFO; - - for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], &sa, NULL) == -1) { - // At this point it is impractical to back out changes, and so failure to - // install a signal is intentionally ignored. - } - } - handlers_installed = true; - return true; -} - -// This function runs in a compromised context: see the top of the file. -// Runs on the crashing thread. -// static -void ExceptionHandler::RestoreHandlersLocked() { - if (!handlers_installed) - return; - - for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) { - InstallDefaultHandler(kExceptionSignals[i]); - } - } - handlers_installed = false; -} - -// void ExceptionHandler::set_crash_handler(HandlerCallback callback) { -// crash_handler_ = callback; -// } - -// This function runs in a compromised context: see the top of the file. -// Runs on the crashing thread. -// static -void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) { - // All the exception signals are blocked at this point. - pthread_mutex_lock(&g_handler_stack_mutex_); - - // Sometimes, Breakpad runs inside a process where some other buggy code - // saves and restores signal handlers temporarily with 'signal' - // instead of 'sigaction'. This loses the SA_SIGINFO flag associated - // with this function. As a consequence, the values of 'info' and 'uc' - // become totally bogus, generally inducing a crash. - // - // The following code tries to detect this case. When it does, it - // resets the signal handlers with sigaction + SA_SIGINFO and returns. - // This forces the signal to be thrown again, but this time the kernel - // will call the function with the right arguments. - struct sigaction cur_handler; - if (sigaction(sig, NULL, &cur_handler) == 0 && - (cur_handler.sa_flags & SA_SIGINFO) == 0) { - // Reset signal handler with the right flags. - sigemptyset(&cur_handler.sa_mask); - sigaddset(&cur_handler.sa_mask, sig); - - cur_handler.sa_sigaction = SignalHandler; - cur_handler.sa_flags = SA_ONSTACK | SA_SIGINFO; - - if (sigaction(sig, &cur_handler, NULL) == -1) { - // When resetting the handler fails, try to reset the - // default one to avoid an infinite loop here. - InstallDefaultHandler(sig); - } - pthread_mutex_unlock(&g_handler_stack_mutex_); - return; - } - - bool handled = false; - for (int i = g_handler_stack_->size() - 1; !handled && i >= 0; --i) { - handled = (*g_handler_stack_)[i]->HandleSignal(sig, info, uc); - } - - // Upon returning from this signal handler, sig will become unmasked and then - // it will be retriggered. If one of the ExceptionHandlers handled it - // successfully, restore the default handler. Otherwise, restore the - // previously installed handler. Then, when the signal is retriggered, it will - // be delivered to the appropriate handler. - if (handled) { - InstallDefaultHandler(sig); - } else { - RestoreHandlersLocked(); - } - - pthread_mutex_unlock(&g_handler_stack_mutex_); - - // info->si_code <= 0 iff SI_FROMUSER (SI_FROMKERNEL otherwise). - if (info->si_code <= 0 || sig == SIGABRT) { - // This signal was triggered by somebody sending us the signal with kill(). - // In order to retrigger it, we have to queue a new signal by calling - // kill() ourselves. The special case (si_pid == 0 && sig == SIGABRT) is - // due to the kernel sending a SIGABRT from a user request via SysRQ. - if (tgkill(getpid(), syscall(__NR_gettid), sig) < 0) { - // If we failed to kill ourselves (e.g. because a sandbox disallows us - // to do so), we instead resort to terminating our process. This will - // result in an incorrect exit code. - _exit(1); - } - } else { - // This was a synchronous signal triggered by a hard fault (e.g. SIGSEGV). - // No need to reissue the signal. It will automatically trigger again, - // when we return from the signal handler. - } -} - -struct ThreadArgument { - pid_t pid; // the crashing process - const MinidumpDescriptor* minidump_descriptor; - ExceptionHandler* handler; - const void* context; // a CrashContext structure - size_t context_size; -}; - -// This is the entry function for the cloned process. We are in a compromised -// context here: see the top of the file. -// static -int ExceptionHandler::ThreadEntry(void *arg) { - const ThreadArgument *thread_arg = reinterpret_cast(arg); - - // Block here until the crashing process unblocks us when - // we're allowed to use ptrace - thread_arg->handler->WaitForContinueSignal(); - - return thread_arg->handler->DoDump(thread_arg->pid, thread_arg->context, - thread_arg->context_size) == false; -} - -// This function runs in a compromised context: see the top of the file. -// Runs on the crashing thread. -bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) { - if (filter_ && !filter_(callback_context_)) - return false; - - // Allow ourselves to be dumped if the signal is trusted. - bool signal_trusted = info->si_code > 0; - bool signal_pid_trusted = info->si_code == SI_USER || - info->si_code == SI_TKILL; - if (signal_trusted || (signal_pid_trusted && info->si_pid == getpid())) { - sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); - } - - // Fill in all the holes in the struct to make Valgrind happy. - memset(&g_crash_context_, 0, sizeof(g_crash_context_)); - memcpy(&g_crash_context_.siginfo, info, sizeof(siginfo_t)); - memcpy(&g_crash_context_.context, uc, sizeof(ucontext_t)); -#if defined(__aarch64__) - ucontext_t* uc_ptr = (ucontext_t*)uc; - struct fpsimd_context* fp_ptr = - (struct fpsimd_context*)&uc_ptr->uc_mcontext.__reserved; - if (fp_ptr->head.magic == FPSIMD_MAGIC) { - memcpy(&g_crash_context_.float_state, fp_ptr, - sizeof(g_crash_context_.float_state)); - } -#elif !defined(__ARM_EABI__) && !defined(__mips__) - // FP state is not part of user ABI on ARM Linux. - // In case of MIPS Linux FP state is already part of ucontext_t - // and 'float_state' is not a member of CrashContext. - ucontext_t* uc_ptr = (ucontext_t*)uc; - if (uc_ptr->uc_mcontext.fpregs) { - memcpy(&g_crash_context_.float_state, uc_ptr->uc_mcontext.fpregs, - sizeof(g_crash_context_.float_state)); - } -#endif - g_crash_context_.tid = syscall(__NR_gettid); - if (crash_handler_ != NULL) { - if (crash_handler_(&g_crash_context_, sizeof(g_crash_context_), - callback_context_)) { - return true; - } - } - return GenerateDump(&g_crash_context_); -} - -// This is a public interface to HandleSignal that allows the client to -// generate a crash dump. This function may run in a compromised context. -bool ExceptionHandler::SimulateSignalDelivery(int sig) { - siginfo_t siginfo = {}; - // Mimic a trusted signal to allow tracing the process (see - // ExceptionHandler::HandleSignal(). - siginfo.si_code = SI_USER; - siginfo.si_pid = getpid(); - ucontext_t context; - getcontext(&context); - return HandleSignal(sig, &siginfo, &context); -} - -// This function may run in a compromised context: see the top of the file. -bool ExceptionHandler::GenerateDump(CrashContext *context) { - if (IsOutOfProcess()) - return crash_generation_client_->RequestDump(context, sizeof(*context)); - - // Allocating too much stack isn't a problem, and better to err on the side - // of caution than smash it into random locations. - static const unsigned kChildStackSize = 16000; - PageAllocator allocator; - uint8_t* stack = reinterpret_cast(allocator.Alloc(kChildStackSize)); - if (!stack) - return false; - // clone() needs the top-most address. (scrub just to be safe) - stack += kChildStackSize; - my_memset(stack - 16, 0, 16); - - ThreadArgument thread_arg; - thread_arg.handler = this; - thread_arg.minidump_descriptor = &minidump_descriptor_; - thread_arg.pid = getpid(); - thread_arg.context = context; - thread_arg.context_size = sizeof(*context); - - // We need to explicitly enable ptrace of parent processes on some - // kernels, but we need to know the PID of the cloned process before we - // can do this. Create a pipe here which we can use to block the - // cloned process after creating it, until we have explicitly enabled ptrace - if (sys_pipe(fdes) == -1) { - // Creating the pipe failed. We'll log an error but carry on anyway, - // as we'll probably still get a useful crash report. All that will happen - // is the write() and read() calls will fail with EBADF - static const char no_pipe_msg[] = "ExceptionHandler::GenerateDump " - "sys_pipe failed:"; - logger::write(no_pipe_msg, sizeof(no_pipe_msg) - 1); - logger::write(strerror(errno), strlen(strerror(errno))); - logger::write("\n", 1); - - // Ensure fdes[0] and fdes[1] are invalid file descriptors. - fdes[0] = fdes[1] = -1; - } - - const pid_t child = sys_clone( - ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED, - &thread_arg, NULL, NULL, NULL); - if (child == -1) { - sys_close(fdes[0]); - sys_close(fdes[1]); - return false; - } - - if (child != 0) { - static const char clonedMsg[] = - "ExceptionHandler::GenerateDump cloned child "; - char pidMsg[32]; - - unsigned int pidLen = my_uint_len(child); - my_uitos(pidMsg, child, pidLen); - - logger::write(clonedMsg, my_strlen(clonedMsg)); - logger::write(pidMsg, pidLen); - logger::write("\n", 1); - } else { - static const char childMsg[] = - "ExceptionHandler::GenerateDump I'm the child\n"; - logger::write(childMsg, my_strlen(childMsg)); - } - - // Allow the child to ptrace us - sys_prctl(PR_SET_PTRACER, child, 0, 0, 0); - SendContinueSignalToChild(); - int status; - const int r = HANDLE_EINTR(sys_waitpid(child, &status, __WALL)); - - sys_close(fdes[0]); - sys_close(fdes[1]); - - if (r == -1) { - static const char msg[] = "ExceptionHandler::GenerateDump waitpid failed:"; - logger::write(msg, sizeof(msg) - 1); - logger::write(strerror(errno), strlen(strerror(errno))); - logger::write("\n", 1); - } - - bool success = r != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0; - if (callback_) - success = callback_(minidump_descriptor_, callback_context_, success); - return success; -} - -// This function runs in a compromised context: see the top of the file. -void ExceptionHandler::SendContinueSignalToChild() { - static const char okToContinueMessage = 'a'; - int r; - r = HANDLE_EINTR(sys_write(fdes[1], &okToContinueMessage, sizeof(char))); - if (r == -1) { - static const char msg[] = "ExceptionHandler::SendContinueSignalToChild " - "sys_write failed:"; - logger::write(msg, sizeof(msg) - 1); - logger::write(strerror(errno), strlen(strerror(errno))); - logger::write("\n", 1); - } - - const char* msg = "ExceptionHandler::SendContinueSignalToChild sent continue signal to child\n"; - logger::write(msg, my_strlen(msg)); -} - -// This function runs in a compromised context: see the top of the file. -// Runs on the cloned process. -void ExceptionHandler::WaitForContinueSignal() { - int r; - char receivedMessage; - - const char* waitMsg = "ExceptionHandler::WaitForContinueSignal waiting for continue signal...\n"; - logger::write(waitMsg, my_strlen(waitMsg)); - - r = HANDLE_EINTR(sys_read(fdes[0], &receivedMessage, sizeof(char))); - if (r == -1) { - static const char msg[] = "ExceptionHandler::WaitForContinueSignal " - "sys_read failed:"; - logger::write(msg, sizeof(msg) - 1); - logger::write(strerror(errno), strlen(strerror(errno))); - logger::write("\n", 1); - } -} - -// This function runs in a compromised context: see the top of the file. -// Runs on the cloned process. -bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context, - size_t context_size) { - if (minidump_descriptor_.IsMicrodumpOnConsole()) { - return google_breakpad::WriteMicrodump( - crashing_process, - context, - context_size, - mapping_list_, - *minidump_descriptor_.microdump_extra_info()); - } - if (minidump_descriptor_.IsFD()) { - return google_breakpad::WriteMinidump(minidump_descriptor_.fd(), - minidump_descriptor_.size_limit(), - crashing_process, - context, - context_size, - mapping_list_, - app_memory_list_); - } - return google_breakpad::WriteMinidump(minidump_descriptor_.path(), - minidump_descriptor_.size_limit(), - crashing_process, - context, - context_size, - mapping_list_, - app_memory_list_); -} - -// static -bool ExceptionHandler::WriteMinidump(const string& dump_path, - MinidumpCallback callback, - void* callback_context) { - MinidumpDescriptor descriptor(dump_path); - ExceptionHandler eh(descriptor, NULL, callback, callback_context, false, -1); - return eh.WriteMinidump(); -} - -// In order to making using EBP to calculate the desired value for ESP -// a valid operation, ensure that this function is compiled with a -// frame pointer using the following attribute. This attribute -// is supported on GCC but not on clang. -#if defined(__i386__) && defined(__GNUC__) && !defined(__clang__) -__attribute__((optimize("no-omit-frame-pointer"))) -#endif -bool ExceptionHandler::WriteMinidump() { - if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() && - !minidump_descriptor_.IsMicrodumpOnConsole()) { - // Update the path of the minidump so that this can be called multiple times - // and new files are created for each minidump. This is done before the - // generation happens, as clients may want to access the MinidumpDescriptor - // after this call to find the exact path to the minidump file. - minidump_descriptor_.UpdatePath(); - } else if (minidump_descriptor_.IsFD()) { - // Reposition the FD to its beginning and resize it to get rid of the - // previous minidump info. - lseek(minidump_descriptor_.fd(), 0, SEEK_SET); - ignore_result(ftruncate(minidump_descriptor_.fd(), 0)); - } - - // Allow this process to be dumped. - sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); - - CrashContext context; - int getcontext_result = getcontext(&context.context); - if (getcontext_result) - return false; - -#if defined(__i386__) - // In CPUFillFromUContext in minidumpwriter.cc the stack pointer is retrieved - // from REG_UESP instead of from REG_ESP. REG_UESP is the user stack pointer - // and it only makes sense when running in kernel mode with a different stack - // pointer. When WriteMiniDump is called during normal processing REG_UESP is - // zero which leads to bad minidump files. - if (!context.context.uc_mcontext.gregs[REG_UESP]) { - // If REG_UESP is set to REG_ESP then that includes the stack space for the - // CrashContext object in this function, which is about 128 KB. Since the - // Linux dumper only records 32 KB of stack this would mean that nothing - // useful would be recorded. A better option is to set REG_UESP to REG_EBP, - // perhaps with a small negative offset in case there is any code that - // objects to them being equal. - context.context.uc_mcontext.gregs[REG_UESP] = - context.context.uc_mcontext.gregs[REG_EBP] - 16; - // The stack saving is based off of REG_ESP so it must be set to match the - // new REG_UESP. - context.context.uc_mcontext.gregs[REG_ESP] = - context.context.uc_mcontext.gregs[REG_UESP]; - } -#endif - -#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__) - // FPU state is not part of ARM EABI ucontext_t. - memcpy(&context.float_state, context.context.uc_mcontext.fpregs, - sizeof(context.float_state)); -#endif - context.tid = sys_gettid(); - - // Add an exception stream to the minidump for better reporting. - memset(&context.siginfo, 0, sizeof(context.siginfo)); - context.siginfo.si_signo = MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED; -#if defined(__i386__) - context.siginfo.si_addr = - reinterpret_cast(context.context.uc_mcontext.gregs[REG_EIP]); -#elif defined(__x86_64__) - context.siginfo.si_addr = - reinterpret_cast(context.context.uc_mcontext.gregs[REG_RIP]); -#elif defined(__arm__) - context.siginfo.si_addr = - reinterpret_cast(context.context.uc_mcontext.arm_pc); -#elif defined(__aarch64__) - context.siginfo.si_addr = - reinterpret_cast(context.context.uc_mcontext.pc); -#elif defined(__mips__) - context.siginfo.si_addr = - reinterpret_cast(context.context.uc_mcontext.pc); -#else -#error "This code has not been ported to your platform yet." -#endif - - return GenerateDump(&context); -} - -void ExceptionHandler::AddMappingInfo(const string& name, - const uint8_t identifier[sizeof(MDGUID)], - uintptr_t start_address, - size_t mapping_size, - size_t file_offset) { - MappingInfo info; - info.start_addr = start_address; - info.size = mapping_size; - info.offset = file_offset; - strncpy(info.name, name.c_str(), sizeof(info.name) - 1); - info.name[sizeof(info.name) - 1] = '\0'; - - MappingEntry mapping; - mapping.first = info; - memcpy(mapping.second, identifier, sizeof(MDGUID)); - mapping_list_.push_back(mapping); -} - -void ExceptionHandler::RegisterAppMemory(void* ptr, size_t length) { - AppMemoryList::iterator iter = - std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr); - if (iter != app_memory_list_.end()) { - // Don't allow registering the same pointer twice. - return; - } - - AppMemory app_memory; - app_memory.ptr = ptr; - app_memory.length = length; - app_memory_list_.push_back(app_memory); -} - -void ExceptionHandler::UnregisterAppMemory(void* ptr) { - AppMemoryList::iterator iter = - std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr); - if (iter != app_memory_list_.end()) { - app_memory_list_.erase(iter); - } -} - -// static -bool ExceptionHandler::WriteMinidumpForChild(pid_t child, - pid_t child_blamed_thread, - const string& dump_path, - MinidumpCallback callback, - void* callback_context) { - // This function is not run in a compromised context. - MinidumpDescriptor descriptor(dump_path); - descriptor.UpdatePath(); - if (!google_breakpad::WriteMinidump(descriptor.path(), - child, - child_blamed_thread)) - return false; - - return callback ? callback(descriptor, callback_context, true) : true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h deleted file mode 100644 index 846df772f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ -#define CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ - -#include -#include -#include -#include - -#include - -#include "client/linux/crash_generation/crash_generation_client.h" -#include "client/linux/handler/minidump_descriptor.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// ExceptionHandler -// -// ExceptionHandler can write a minidump file when an exception occurs, -// or when WriteMinidump() is called explicitly by your program. -// -// To have the exception handler write minidumps when an uncaught exception -// (crash) occurs, you should create an instance early in the execution -// of your program, and keep it around for the entire time you want to -// have crash handling active (typically, until shutdown). -// (NOTE): There should be only be one this kind of exception handler -// object per process. -// -// If you want to write minidumps without installing the exception handler, -// you can create an ExceptionHandler with install_handler set to false, -// then call WriteMinidump. You can also use this technique if you want to -// use different minidump callbacks for different call sites. -// -// In either case, a callback function is called when a minidump is written, -// which receives the full path or file descriptor of the minidump. The -// caller can collect and write additional application state to that minidump, -// and launch an external crash-reporting application. -// -// Caller should try to make the callbacks as crash-friendly as possible, -// it should avoid use heap memory allocation as much as possible. - -class ExceptionHandler { - public: - // A callback function to run before Breakpad performs any substantial - // processing of an exception. A FilterCallback is called before writing - // a minidump. |context| is the parameter supplied by the user as - // callback_context when the handler was created. - // - // If a FilterCallback returns true, Breakpad will continue processing, - // attempting to write a minidump. If a FilterCallback returns false, - // Breakpad will immediately report the exception as unhandled without - // writing a minidump, allowing another handler the opportunity to handle it. - typedef bool (*FilterCallback)(void *context); - - // A callback function to run after the minidump has been written. - // |descriptor| contains the file descriptor or file path containing the - // minidump. |context| is the parameter supplied by the user as - // callback_context when the handler was created. |succeeded| indicates - // whether a minidump file was successfully written. - // - // If an exception occurred and the callback returns true, Breakpad will - // treat the exception as fully-handled, suppressing any other handlers from - // being notified of the exception. If the callback returns false, Breakpad - // will treat the exception as unhandled, and allow another handler to handle - // it. If there are no other handlers, Breakpad will report the exception to - // the system as unhandled, allowing a debugger or native crash dialog the - // opportunity to handle the exception. Most callback implementations - // should normally return the value of |succeeded|, or when they wish to - // not report an exception of handled, false. Callbacks will rarely want to - // return true directly (unless |succeeded| is true). - typedef bool (*MinidumpCallback)(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded); - - // In certain cases, a user may wish to handle the generation of the minidump - // themselves. In this case, they can install a handler callback which is - // called when a crash has occurred. If this function returns true, no other - // processing of occurs and the process will shortly be crashed. If this - // returns false, the normal processing continues. - typedef bool (*HandlerCallback)(const void* crash_context, - size_t crash_context_size, - void* context); - - // Creates a new ExceptionHandler instance to handle writing minidumps. - // Before writing a minidump, the optional |filter| callback will be called. - // Its return value determines whether or not Breakpad should write a - // minidump. The minidump content will be written to the file path or file - // descriptor from |descriptor|, and the optional |callback| is called after - // writing the dump file, as described above. - // If install_handler is true, then a minidump will be written whenever - // an unhandled exception occurs. If it is false, minidumps will only - // be written when WriteMinidump is called. - // If |server_fd| is valid, the minidump is generated out-of-process. If it - // is -1, in-process generation will always be used. - ExceptionHandler(const MinidumpDescriptor& descriptor, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - bool install_handler, - const int server_fd); - ~ExceptionHandler(); - - const MinidumpDescriptor& minidump_descriptor() const { - return minidump_descriptor_; - } - - void set_minidump_descriptor(const MinidumpDescriptor& descriptor) { - minidump_descriptor_ = descriptor; - } - - void set_crash_handler(HandlerCallback callback) { - crash_handler_ = callback; - } - - void set_crash_generation_client(CrashGenerationClient* client) { - crash_generation_client_.reset(client); - } - - // Writes a minidump immediately. This can be used to capture the execution - // state independently of a crash. - // Returns true on success. - // If the ExceptionHandler has been created with a path, a new file is - // generated for each minidump. The file path can be retrieved in the - // MinidumpDescriptor passed to the MinidumpCallback or by accessing the - // MinidumpDescriptor directly from the ExceptionHandler (with - // minidump_descriptor()). - // If the ExceptionHandler has been created with a file descriptor, the file - // descriptor is repositioned to its beginning and the previous generated - // minidump is overwritten. - // Note that this method is not supposed to be called from a compromised - // context as it uses the heap. - bool WriteMinidump(); - - // Convenience form of WriteMinidump which does not require an - // ExceptionHandler instance. - static bool WriteMinidump(const string& dump_path, - MinidumpCallback callback, - void* callback_context); - - // Write a minidump of |child| immediately. This can be used to - // capture the execution state of |child| independently of a crash. - // Pass a meaningful |child_blamed_thread| to make that thread in - // the child process the one from which a crash signature is - // extracted. - // - // WARNING: the return of this function *must* happen before - // the code that will eventually reap |child| executes. - // Otherwise there's a pernicious race condition in which |child| - // exits, is reaped, another process created with its pid, then that - // new process dumped. - static bool WriteMinidumpForChild(pid_t child, - pid_t child_blamed_thread, - const string& dump_path, - MinidumpCallback callback, - void* callback_context); - - // This structure is passed to minidump_writer.h:WriteMinidump via an opaque - // blob. It shouldn't be needed in any user code. - struct CrashContext { - siginfo_t siginfo; - pid_t tid; // the crashing thread. - ucontext_t context; -#if !defined(__ARM_EABI__) && !defined(__mips__) - // #ifdef this out because FP state is not part of user ABI for Linux ARM. - // In case of MIPS Linux FP state is already part of struct - // ucontext so 'float_state' is not required. - fpstate_t float_state; -#endif - }; - - // Returns whether out-of-process dump generation is used or not. - bool IsOutOfProcess() const { - return crash_generation_client_.get() != NULL; - } - - // Add information about a memory mapping. This can be used if - // a custom library loader is used that maps things in a way - // that the linux dumper can't handle by reading the maps file. - void AddMappingInfo(const string& name, - const uint8_t identifier[sizeof(MDGUID)], - uintptr_t start_address, - size_t mapping_size, - size_t file_offset); - - // Register a block of memory of length bytes starting at address ptr - // to be copied to the minidump when a crash happens. - void RegisterAppMemory(void* ptr, size_t length); - - // Unregister a block of memory that was registered with RegisterAppMemory. - void UnregisterAppMemory(void* ptr); - - // Force signal handling for the specified signal. - bool SimulateSignalDelivery(int sig); - - // Report a crash signal from an SA_SIGINFO signal handler. - bool HandleSignal(int sig, siginfo_t* info, void* uc); - - private: - // Save the old signal handlers and install new ones. - static bool InstallHandlersLocked(); - // Restore the old signal handlers. - static void RestoreHandlersLocked(); - - void PreresolveSymbols(); - bool GenerateDump(CrashContext *context); - void SendContinueSignalToChild(); - void WaitForContinueSignal(); - - static void SignalHandler(int sig, siginfo_t* info, void* uc); - static int ThreadEntry(void* arg); - bool DoDump(pid_t crashing_process, const void* context, - size_t context_size); - - const FilterCallback filter_; - const MinidumpCallback callback_; - void* const callback_context_; - - scoped_ptr crash_generation_client_; - - MinidumpDescriptor minidump_descriptor_; - - // Must be volatile. The compiler is unaware of the code which runs in - // the signal handler which reads this variable. Without volatile the - // compiler is free to optimise away writes to this variable which it - // believes are never read. - volatile HandlerCallback crash_handler_; - - // We need to explicitly enable ptrace of parent processes on some - // kernels, but we need to know the PID of the cloned process before we - // can do this. We create a pipe which we can use to block the - // cloned process after creating it, until we have explicitly enabled - // ptrace. This is used to store the file descriptors for the pipe - int fdes[2]; - - // Callers can add extra info about mappings for cases where the - // dumper code cannot extract enough information from /proc//maps. - MappingList mapping_list_; - - // Callers can request additional memory regions to be included in - // the dump. - AppMemoryList app_memory_list_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_unittest.cc deleted file mode 100644 index 17d84cf7b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_unittest.cc +++ /dev/null @@ -1,1179 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__mips__) -#include -#endif - -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/ignore_ret.h" -#include "common/linux/linux_libc_support.h" -#include "common/tests/auto_tempdir.h" -#include "common/using_std_string.h" -#include "third_party/lss/linux_syscall_support.h" -#include "google_breakpad/processor/minidump.h" - -using namespace google_breakpad; - -namespace { - -// Flush the instruction cache for a given memory range. -// Only required on ARM and mips. -void FlushInstructionCache(const char* memory, uint32_t memory_size) { -#if defined(__arm__) - long begin = reinterpret_cast(memory); - long end = begin + static_cast(memory_size); -# if defined(__ANDROID__) - // Provided by Android's - cacheflush(begin, end, 0); -# elif defined(__linux__) - // GLibc/ARM doesn't provide a wrapper for it, do a direct syscall. -# ifndef __ARM_NR_cacheflush -# define __ARM_NR_cacheflush 0xf0002 -# endif - syscall(__ARM_NR_cacheflush, begin, end, 0); -# else -# error "Your operating system is not supported yet" -# endif -#elif defined(__mips__) -# if defined(__ANDROID__) - // Provided by Android's - long begin = reinterpret_cast(memory); - long end = begin + static_cast(memory_size); -#if _MIPS_SIM == _ABIO32 - cacheflush(begin, end, 0); -#else - syscall(__NR_cacheflush, begin, end, ICACHE); -#endif -# elif defined(__linux__) - // See http://www.linux-mips.org/wiki/Cacheflush_Syscall. - cacheflush(const_cast(memory), memory_size, ICACHE); -# else -# error "Your operating system is not supported yet" -# endif -#endif -} - -void sigchld_handler(int signo) { } - -int CreateTMPFile(const string& dir, string* path) { - string file = dir + "/exception-handler-unittest.XXXXXX"; - const char* c_file = file.c_str(); - // Copy that string, mkstemp needs a C string it can modify. - char* c_path = strdup(c_file); - const int fd = mkstemp(c_path); - if (fd >= 0) - *path = c_path; - free(c_path); - return fd; -} - -class ExceptionHandlerTest : public ::testing::Test { - protected: - void SetUp() { - // We need to be able to wait for children, so SIGCHLD cannot be SIG_IGN. - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sigchld_handler; - ASSERT_NE(sigaction(SIGCHLD, &sa, &old_action), -1); - } - - void TearDown() { - sigaction(SIGCHLD, &old_action, NULL); - } - - struct sigaction old_action; -}; - - -void WaitForProcessToTerminate(pid_t process_id, int expected_status) { - int status; - ASSERT_NE(HANDLE_EINTR(waitpid(process_id, &status, 0)), -1); - ASSERT_TRUE(WIFSIGNALED(status)); - ASSERT_EQ(expected_status, WTERMSIG(status)); -} - -// Reads the minidump path sent over the pipe |fd| and sets it in |path|. -void ReadMinidumpPathFromPipe(int fd, string* path) { - struct pollfd pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - const int r = HANDLE_EINTR(poll(&pfd, 1, 0)); - ASSERT_EQ(1, r); - ASSERT_TRUE(pfd.revents & POLLIN); - - int32_t len; - ASSERT_EQ(static_cast(sizeof(len)), read(fd, &len, sizeof(len))); - ASSERT_LT(len, 2048); - char* filename = static_cast(malloc(len + 1)); - ASSERT_EQ(len, read(fd, filename, len)); - filename[len] = 0; - close(fd); - *path = filename; - free(filename); -} - -} // namespace - -TEST(ExceptionHandlerTest, SimpleWithPath) { - AutoTempDir temp_dir; - ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); - EXPECT_EQ(temp_dir.path(), handler.minidump_descriptor().directory()); - string temp_subdir = temp_dir.path() + "/subdir"; - handler.set_minidump_descriptor(MinidumpDescriptor(temp_subdir)); - EXPECT_EQ(temp_subdir, handler.minidump_descriptor().directory()); -} - -TEST(ExceptionHandlerTest, SimpleWithFD) { - AutoTempDir temp_dir; - string path; - const int fd = CreateTMPFile(temp_dir.path(), &path); - ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, true, -1); - close(fd); -} - -static bool DoneCallback(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded) { - if (!succeeded) - return false; - - if (!descriptor.IsFD()) { - int fd = reinterpret_cast(context); - uint32_t len = 0; - len = my_strlen(descriptor.path()); - IGNORE_RET(HANDLE_EINTR(sys_write(fd, &len, sizeof(len)))); - IGNORE_RET(HANDLE_EINTR(sys_write(fd, descriptor.path(), len))); - } - return true; -} - -#ifndef ADDRESS_SANITIZER - -// This is a replacement for "*reinterpret_cast(NULL) = 0;" -// It is needed because GCC is allowed to assume that the program will -// not execute any undefined behavior (UB) operation. Further, when GCC -// observes that UB statement is reached, it can assume that all statements -// leading to the UB one are never executed either, and can completely -// optimize them out. In the case of ExceptionHandlerTest::ExternalDumper, -// GCC-4.9 optimized out the entire set up of ExceptionHandler, causing -// test failure. -volatile int *p_null; // external linkage, so GCC can't tell that it - // remains NULL. Volatile just for a good measure. -static void DoNullPointerDereference() { - *p_null = 1; -} - -void ChildCrash(bool use_fd) { - AutoTempDir temp_dir; - int fds[2] = {0}; - int minidump_fd = -1; - string minidump_path; - if (use_fd) { - minidump_fd = CreateTMPFile(temp_dir.path(), &minidump_path); - } else { - ASSERT_NE(pipe(fds), -1); - } - - const pid_t child = fork(); - if (child == 0) { - { - google_breakpad::scoped_ptr handler; - if (use_fd) { - handler.reset(new ExceptionHandler(MinidumpDescriptor(minidump_fd), - NULL, NULL, NULL, true, -1)); - } else { - close(fds[0]); // Close the reading end. - void* fd_param = reinterpret_cast(fds[1]); - handler.reset(new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), - NULL, DoneCallback, fd_param, - true, -1)); - } - // Crash with the exception handler in scope. - DoNullPointerDereference(); - } - } - if (!use_fd) - close(fds[1]); // Close the writting end. - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); - - if (!use_fd) - ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path)); - - struct stat st; - ASSERT_EQ(0, stat(minidump_path.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - unlink(minidump_path.c_str()); -} - -TEST(ExceptionHandlerTest, ChildCrashWithPath) { - ASSERT_NO_FATAL_FAILURE(ChildCrash(false)); -} - -TEST(ExceptionHandlerTest, ChildCrashWithFD) { - ASSERT_NO_FATAL_FAILURE(ChildCrash(true)); -} - -static bool DoneCallbackReturnFalse(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded) { - return false; -} - -static bool DoneCallbackReturnTrue(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded) { - return true; -} - -static bool DoneCallbackRaiseSIGKILL(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded) { - raise(SIGKILL); - return true; -} - -static bool FilterCallbackReturnFalse(void* context) { - return false; -} - -static bool FilterCallbackReturnTrue(void* context) { - return true; -} - -// SIGKILL cannot be blocked and a handler cannot be installed for it. In the -// following tests, if the child dies with signal SIGKILL, then the signal was -// redelivered to this handler. If the child dies with SIGSEGV then it wasn't. -static void RaiseSIGKILL(int sig) { - raise(SIGKILL); -} - -static bool InstallRaiseSIGKILL() { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = RaiseSIGKILL; - return sigaction(SIGSEGV, &sa, NULL) != -1; -} - -static void CrashWithCallbacks(ExceptionHandler::FilterCallback filter, - ExceptionHandler::MinidumpCallback done, - string path) { - ExceptionHandler handler( - MinidumpDescriptor(path), filter, done, NULL, true, -1); - // Crash with the exception handler in scope. - DoNullPointerDereference(); -} - -TEST(ExceptionHandlerTest, RedeliveryOnFilterCallbackFalse) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); - } - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -TEST(ExceptionHandlerTest, RedeliveryOnDoneCallbackFalse) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path()); - } - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -TEST(ExceptionHandlerTest, NoRedeliveryOnDoneCallbackTrue) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(NULL, DoneCallbackReturnTrue, temp_dir.path()); - } - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); -} - -TEST(ExceptionHandlerTest, NoRedeliveryOnFilterCallbackTrue) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(FilterCallbackReturnTrue, NULL, temp_dir.path()); - } - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); -} - -TEST(ExceptionHandlerTest, RedeliveryToDefaultHandler) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); - } - - // As RaiseSIGKILL wasn't installed, the redelivery should just kill the child - // with SIGSEGV. - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); -} - -// Check that saving and restoring the signal handler with 'signal' -// instead of 'sigaction' doesn't make the Breakpad signal handler -// crash. See comments in ExceptionHandler::SignalHandler for full -// details. -TEST(ExceptionHandlerTest, RedeliveryOnBadSignalHandlerFlag) { - AutoTempDir temp_dir; - const pid_t child = fork(); - if (child == 0) { - // Install the RaiseSIGKILL handler for SIGSEGV. - ASSERT_TRUE(InstallRaiseSIGKILL()); - - // Create a new exception handler, this installs a new SIGSEGV - // handler, after saving the old one. - ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallbackReturnFalse, NULL, true, -1); - - // Install the default SIGSEGV handler, saving the current one. - // Then re-install the current one with 'signal', this loses the - // SA_SIGINFO flag associated with the Breakpad handler. - sighandler_t old_handler = signal(SIGSEGV, SIG_DFL); - ASSERT_NE(reinterpret_cast(old_handler), - reinterpret_cast(SIG_ERR)); - ASSERT_NE(reinterpret_cast(signal(SIGSEGV, old_handler)), - reinterpret_cast(SIG_ERR)); - - // Crash with the exception handler in scope. - DoNullPointerDereference(); - } - // SIGKILL means Breakpad's signal handler didn't crash. - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -TEST(ExceptionHandlerTest, StackedHandlersDeliveredToTop) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, - NULL, - NULL, - true, - -1); - CrashWithCallbacks(NULL, DoneCallbackRaiseSIGKILL, temp_dir.path()); - } - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -TEST(ExceptionHandlerTest, StackedHandlersNotDeliveredToBottom) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, - DoneCallbackRaiseSIGKILL, - NULL, - true, - -1); - CrashWithCallbacks(NULL, NULL, temp_dir.path()); - } - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); -} - -TEST(ExceptionHandlerTest, StackedHandlersFilteredToBottom) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, - DoneCallbackRaiseSIGKILL, - NULL, - true, - -1); - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); - } - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) { - AutoTempDir temp_dir; - - const pid_t child = fork(); - if (child == 0) { - ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, - DoneCallbackRaiseSIGKILL, - NULL, - true, - -1); - CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path()); - } - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); -} - -#endif // !ADDRESS_SANITIZER - -const unsigned char kIllegalInstruction[] = { -#if defined(__mips__) - // mfc2 zero,Impl - usually illegal in userspace. - 0x48, 0x00, 0x00, 0x48 -#else - // This crashes with SIGILL on x86/x86-64/arm. - 0xff, 0xff, 0xff, 0xff -#endif -}; - -// Test that memory around the instruction pointer is written -// to the dump as a MinidumpMemoryRegion. -TEST(ExceptionHandlerTest, InstructionPointerMemory) { - AutoTempDir temp_dir; - int fds[2]; - ASSERT_NE(pipe(fds), -1); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = kMemorySize / 2; - - const pid_t child = fork(); - if (child == 0) { - close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallback, reinterpret_cast(fds[1]), - true, -1); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them in the middle - // of the block of memory, because the minidump should contain 128 - // bytes on either side of the instruction pointer. - memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction)); - FlushInstructionCache(memory, kMemorySize); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - } - close(fds[1]); - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL)); - - string minidump_path; - ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path)); - - struct stat st; - ASSERT_EQ(0, stat(minidump_path.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_path); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT(0U, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kOffset]; - uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(kIllegalInstruction)]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction, - sizeof(kIllegalInstruction)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction), - suffix_bytes, sizeof(suffix_bytes)) == 0); - - unlink(minidump_path.c_str()); -} - -// Test that the memory region around the instruction pointer is -// bounded correctly on the low end. -TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { - AutoTempDir temp_dir; - int fds[2]; - ASSERT_NE(pipe(fds), -1); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = 0; - - const pid_t child = fork(); - if (child == 0) { - close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallback, reinterpret_cast(fds[1]), - true, -1); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them in the middle - // of the block of memory, because the minidump should contain 128 - // bytes on either side of the instruction pointer. - memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction)); - FlushInstructionCache(memory, kMemorySize); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - } - close(fds[1]); - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL)); - - string minidump_path; - ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path)); - - struct stat st; - ASSERT_EQ(0, stat(minidump_path.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_path); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT(0U, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize / 2, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t suffix_bytes[kMemorySize / 2 - sizeof(kIllegalInstruction)]; - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction, - sizeof(kIllegalInstruction)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction), - suffix_bytes, sizeof(suffix_bytes)) == 0); - unlink(minidump_path.c_str()); -} - -// Test that the memory region around the instruction pointer is -// bounded correctly on the high end. -TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { - AutoTempDir temp_dir; - int fds[2]; - ASSERT_NE(pipe(fds), -1); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - // Use 4k here because the OS will hand out a single page even - // if a smaller size is requested, and this test wants to - // test the upper bound of the memory range. - const uint32_t kMemorySize = 4096; // bytes - const int kOffset = kMemorySize - sizeof(kIllegalInstruction); - - const pid_t child = fork(); - if (child == 0) { - close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallback, reinterpret_cast(fds[1]), - true, -1); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them in the middle - // of the block of memory, because the minidump should contain 128 - // bytes on either side of the instruction pointer. - memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction)); - FlushInstructionCache(memory, kMemorySize); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - } - close(fds[1]); - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL)); - - string minidump_path; - ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path)); - - struct stat st; - ASSERT_EQ(0, stat(minidump_path.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - // Read the minidump. Locate the exception record and the memory list, and - // then ensure that there is a memory region in the memory list that covers - // the instruction pointer from the exception record. - Minidump minidump(minidump_path); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT(0U, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - const size_t kPrefixSize = 128; // bytes - EXPECT_EQ(kPrefixSize + sizeof(kIllegalInstruction), region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kPrefixSize]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0); - EXPECT_TRUE(memcmp(bytes + kPrefixSize, - kIllegalInstruction, sizeof(kIllegalInstruction)) == 0); - - unlink(minidump_path.c_str()); -} - -#ifndef ADDRESS_SANITIZER - -// Ensure that an extra memory block doesn't get added when the instruction -// pointer is not in mapped memory. -TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { - AutoTempDir temp_dir; - int fds[2]; - ASSERT_NE(pipe(fds), -1); - - const pid_t child = fork(); - if (child == 0) { - close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallback, reinterpret_cast(fds[1]), - true, -1); - // Try calling a NULL pointer. - typedef void (*void_function)(void); - // Volatile markings are needed to keep Clang from generating invalid - // opcodes. See http://crbug.com/498354 for details. - volatile void_function memory_function = - reinterpret_cast(NULL); - memory_function(); - // not reached - exit(1); - } - close(fds[1]); - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); - - string minidump_path; - ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path)); - - struct stat st; - ASSERT_EQ(0, stat(minidump_path.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_path); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_EQ(static_cast(1), memory_list->region_count()); - - unlink(minidump_path.c_str()); -} - -#endif // !ADDRESS_SANITIZER - -// Test that anonymous memory maps can be annotated with names and IDs. -TEST(ExceptionHandlerTest, ModuleInfo) { - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = sysconf(_SC_PAGESIZE); - const char* kMemoryName = "a fake module"; - const uint8_t kModuleGUID[sizeof(MDGUID)] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - }; - const string module_identifier = "33221100554477668899AABBCCDDEEFF0"; - - // Get some memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - AutoTempDir temp_dir; - ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); - - // Add info about the anonymous memory mapping. - handler.AddMappingInfo(kMemoryName, - kModuleGUID, - kMemoryAddress, - kMemorySize, - 0); - ASSERT_TRUE(handler.WriteMinidump()); - - const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor(); - // Read the minidump. Load the module list, and ensure that the mmap'ed - // |memory| is listed with the given module name and debug ID. - Minidump minidump(minidump_desc.path()); - ASSERT_TRUE(minidump.Read()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* module = - module_list->GetModuleForAddress(kMemoryAddress); - ASSERT_TRUE(module); - - EXPECT_EQ(kMemoryAddress, module->base_address()); - EXPECT_EQ(kMemorySize, module->size()); - EXPECT_EQ(kMemoryName, module->code_file()); - EXPECT_EQ(module_identifier, module->debug_identifier()); - - unlink(minidump_desc.path()); -} - -#ifndef ADDRESS_SANITIZER - -static const unsigned kControlMsgSize = - CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); - -static bool -CrashHandler(const void* crash_context, size_t crash_context_size, - void* context) { - const int fd = (intptr_t) context; - int fds[2]; - if (pipe(fds) == -1) { - // There doesn't seem to be any way to reliably handle - // this failure without the parent process hanging - // At least make sure that this process doesn't access - // unexpected file descriptors - fds[0] = -1; - fds[1] = -1; - } - struct kernel_msghdr msg = {0}; - struct kernel_iovec iov; - iov.iov_base = const_cast(crash_context); - iov.iov_len = crash_context_size; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - char cmsg[kControlMsgSize]; - memset(cmsg, 0, kControlMsgSize); - msg.msg_control = cmsg; - msg.msg_controllen = sizeof(cmsg); - - struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); - hdr->cmsg_level = SOL_SOCKET; - hdr->cmsg_type = SCM_RIGHTS; - hdr->cmsg_len = CMSG_LEN(sizeof(int)); - *((int*) CMSG_DATA(hdr)) = fds[1]; - hdr = CMSG_NXTHDR((struct msghdr*) &msg, hdr); - hdr->cmsg_level = SOL_SOCKET; - hdr->cmsg_type = SCM_CREDENTIALS; - hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred)); - struct ucred *cred = reinterpret_cast(CMSG_DATA(hdr)); - cred->uid = getuid(); - cred->gid = getgid(); - cred->pid = getpid(); - - ssize_t ret = HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)); - sys_close(fds[1]); - if (ret <= 0) - return false; - - char b; - IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1))); - - return true; -} - -TEST(ExceptionHandlerTest, ExternalDumper) { - int fds[2]; - ASSERT_NE(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds), -1); - static const int on = 1; - setsockopt(fds[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor("/tmp1"), NULL, NULL, - reinterpret_cast(fds[1]), true, -1); - handler.set_crash_handler(CrashHandler); - DoNullPointerDereference(); - } - close(fds[1]); - struct msghdr msg = {0}; - struct iovec iov; - static const unsigned kCrashContextSize = - sizeof(ExceptionHandler::CrashContext); - char context[kCrashContextSize]; - char control[kControlMsgSize]; - iov.iov_base = context; - iov.iov_len = kCrashContextSize; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = control; - msg.msg_controllen = kControlMsgSize; - - const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0)); - ASSERT_EQ(static_cast(kCrashContextSize), n); - ASSERT_EQ(kControlMsgSize, msg.msg_controllen); - ASSERT_EQ(static_cast<__typeof__(msg.msg_flags)>(0), msg.msg_flags); - ASSERT_EQ(0, close(fds[0])); - - pid_t crashing_pid = -1; - int signal_fd = -1; - for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; - hdr = CMSG_NXTHDR(&msg, hdr)) { - if (hdr->cmsg_level != SOL_SOCKET) - continue; - if (hdr->cmsg_type == SCM_RIGHTS) { - const unsigned len = hdr->cmsg_len - - (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr); - ASSERT_EQ(sizeof(int), len); - signal_fd = *(reinterpret_cast(CMSG_DATA(hdr))); - } else if (hdr->cmsg_type == SCM_CREDENTIALS) { - const struct ucred *cred = - reinterpret_cast(CMSG_DATA(hdr)); - crashing_pid = cred->pid; - } - } - - ASSERT_NE(crashing_pid, -1); - ASSERT_NE(signal_fd, -1); - - AutoTempDir temp_dir; - string templ = temp_dir.path() + "/exception-handler-unittest"; - ASSERT_TRUE(WriteMinidump(templ.c_str(), crashing_pid, context, - kCrashContextSize)); - static const char b = 0; - ASSERT_EQ(1, (HANDLE_EINTR(write(signal_fd, &b, 1)))); - ASSERT_EQ(0, close(signal_fd)); - - ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); - - struct stat st; - ASSERT_EQ(0, stat(templ.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - unlink(templ.c_str()); -} - -#endif // !ADDRESS_SANITIZER - -TEST(ExceptionHandlerTest, WriteMinidumpExceptionStream) { - AutoTempDir temp_dir; - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, - NULL, false, -1); - ASSERT_TRUE(handler.WriteMinidump()); - - string minidump_path = handler.minidump_descriptor().path(); - - // Read the minidump and check the exception stream. - Minidump minidump(minidump_path); - ASSERT_TRUE(minidump.Read()); - MinidumpException* exception = minidump.GetException(); - ASSERT_TRUE(exception); - const MDRawExceptionStream* raw = exception->exception(); - ASSERT_TRUE(raw); - EXPECT_EQ(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED, - raw->exception_record.exception_code); -} - -TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithFD) { - AutoTempDir temp_dir; - string path; - const int fd = CreateTMPFile(temp_dir.path(), &path); - ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, false, -1); - ASSERT_TRUE(handler.WriteMinidump()); - // Check by the size of the data written to the FD that a minidump was - // generated. - off_t size = lseek(fd, 0, SEEK_CUR); - ASSERT_GT(size, 0); - - // Generate another minidump. - ASSERT_TRUE(handler.WriteMinidump()); - size = lseek(fd, 0, SEEK_CUR); - ASSERT_GT(size, 0); -} - -TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithPath) { - AutoTempDir temp_dir; - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, - NULL, false, -1); - ASSERT_TRUE(handler.WriteMinidump()); - - const MinidumpDescriptor& minidump_1 = handler.minidump_descriptor(); - struct stat st; - ASSERT_EQ(0, stat(minidump_1.path(), &st)); - ASSERT_GT(st.st_size, 0); - string minidump_1_path(minidump_1.path()); - // Check it is a valid minidump. - Minidump minidump1(minidump_1_path); - ASSERT_TRUE(minidump1.Read()); - unlink(minidump_1.path()); - - // Generate another minidump, it should go to a different file. - ASSERT_TRUE(handler.WriteMinidump()); - const MinidumpDescriptor& minidump_2 = handler.minidump_descriptor(); - ASSERT_EQ(0, stat(minidump_2.path(), &st)); - ASSERT_GT(st.st_size, 0); - string minidump_2_path(minidump_2.path()); - // Check it is a valid minidump. - Minidump minidump2(minidump_2_path); - ASSERT_TRUE(minidump2.Read()); - unlink(minidump_2.path()); - - // 2 distinct files should be produced. - ASSERT_STRNE(minidump_1_path.c_str(), minidump_2_path.c_str()); -} - -// Test that an additional memory region can be added to the minidump. -TEST(ExceptionHandlerTest, AdditionalMemory) { - const uint32_t kMemorySize = sysconf(_SC_PAGESIZE); - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - AutoTempDir temp_dir; - ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); - - // Add the memory region to the list of memory to be included. - handler.RegisterAppMemory(memory, kMemorySize); - handler.WriteMinidump(); - - const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor(); - - // Read the minidump. Ensure that the memory region is present - Minidump minidump(minidump_desc.path()); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemoryAddress, region->GetBase()); - EXPECT_EQ(kMemorySize, region->GetSize()); - - // Verify memory contents. - EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize)); - - delete[] memory; -} - -// Test that a memory region that was previously registered -// can be unregistered. -TEST(ExceptionHandlerTest, AdditionalMemoryRemove) { - const uint32_t kMemorySize = sysconf(_SC_PAGESIZE); - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - AutoTempDir temp_dir; - ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); - - // Add the memory region to the list of memory to be included. - handler.RegisterAppMemory(memory, kMemorySize); - - // ...and then remove it - handler.UnregisterAppMemory(memory); - handler.WriteMinidump(); - - const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor(); - - // Read the minidump. Ensure that the memory region is not present. - Minidump minidump(minidump_desc.path()); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - EXPECT_FALSE(region); - - delete[] memory; -} - -static bool SimpleCallback(const MinidumpDescriptor& descriptor, - void* context, - bool succeeded) { - string* filename = reinterpret_cast(context); - *filename = descriptor.path(); - return true; -} - -TEST(ExceptionHandlerTest, WriteMinidumpForChild) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - HANDLE_EINTR(read(fds[0], &b, sizeof(b))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - AutoTempDir temp_dir; - string minidump_filename; - ASSERT_TRUE( - ExceptionHandler::WriteMinidumpForChild(child, child, - temp_dir.path(), SimpleCallback, - (void*)&minidump_filename)); - - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - // Check that the crashing thread is the main thread of |child| - MinidumpException* exception = minidump.GetException(); - ASSERT_TRUE(exception); - uint32_t thread_id; - ASSERT_TRUE(exception->GetThreadID(&thread_id)); - EXPECT_EQ(child, static_cast(thread_id)); - - const MDRawExceptionStream* raw = exception->exception(); - ASSERT_TRUE(raw); - EXPECT_EQ(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED, - raw->exception_record.exception_code); - - close(fds[1]); - unlink(minidump_filename.c_str()); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/microdump_extra_info.h b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/microdump_extra_info.h deleted file mode 100644 index bf01f0c7b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/microdump_extra_info.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_HANDLER_MICRODUMP_EXTRA_INFO_H_ -#define CLIENT_LINUX_HANDLER_MICRODUMP_EXTRA_INFO_H_ - -namespace google_breakpad { - -struct MicrodumpExtraInfo { - // Strings pointed to by this struct are not copied, and are - // expected to remain valid for the lifetime of the process. - const char* build_fingerprint; - const char* product_info; - const char* gpu_fingerprint; - const char* process_type; - - MicrodumpExtraInfo() - : build_fingerprint(NULL), - product_info(NULL), - gpu_fingerprint(NULL), - process_type(NULL) {} -}; - -} - -#endif // CLIENT_LINUX_HANDLER_MICRODUMP_EXTRA_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.cc deleted file mode 100644 index ce09153dd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include "client/linux/handler/minidump_descriptor.h" - -#include "common/linux/guid_creator.h" - -namespace google_breakpad { - -//static -const MinidumpDescriptor::MicrodumpOnConsole - MinidumpDescriptor::kMicrodumpOnConsole = {}; - -MinidumpDescriptor::MinidumpDescriptor(const MinidumpDescriptor& descriptor) - : mode_(descriptor.mode_), - fd_(descriptor.fd_), - directory_(descriptor.directory_), - c_path_(NULL), - size_limit_(descriptor.size_limit_), - microdump_extra_info_(descriptor.microdump_extra_info_) { - // The copy constructor is not allowed to be called on a MinidumpDescriptor - // with a valid path_, as getting its c_path_ would require the heap which - // can cause problems in compromised environments. - assert(descriptor.path_.empty()); -} - -MinidumpDescriptor& MinidumpDescriptor::operator=( - const MinidumpDescriptor& descriptor) { - assert(descriptor.path_.empty()); - - mode_ = descriptor.mode_; - fd_ = descriptor.fd_; - directory_ = descriptor.directory_; - path_.clear(); - if (c_path_) { - // This descriptor already had a path set, so generate a new one. - c_path_ = NULL; - UpdatePath(); - } - size_limit_ = descriptor.size_limit_; - microdump_extra_info_ = descriptor.microdump_extra_info_; - return *this; -} - -void MinidumpDescriptor::UpdatePath() { - assert(mode_ == kWriteMinidumpToFile && !directory_.empty()); - - GUID guid; - char guid_str[kGUIDStringLength + 1]; - if (!CreateGUID(&guid) || !GUIDToString(&guid, guid_str, sizeof(guid_str))) { - assert(false); - } - - path_.clear(); - path_ = directory_ + "/" + guid_str + ".dmp"; - c_path_ = path_.c_str(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.h b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.h deleted file mode 100644 index 782a60a4e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_descriptor.h +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ -#define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ - -#include -#include - -#include - -#include "client/linux/handler/microdump_extra_info.h" -#include "common/using_std_string.h" - -// This class describes how a crash dump should be generated, either: -// - Writing a full minidump to a file in a given directory (the actual path, -// inside the directory, is determined by this class). -// - Writing a full minidump to a given fd. -// - Writing a reduced microdump to the console (logcat on Android). -namespace google_breakpad { - -class MinidumpDescriptor { - public: - struct MicrodumpOnConsole {}; - static const MicrodumpOnConsole kMicrodumpOnConsole; - - MinidumpDescriptor() - : mode_(kUninitialized), - fd_(-1), - size_limit_(-1) {} - - explicit MinidumpDescriptor(const string& directory) - : mode_(kWriteMinidumpToFile), - fd_(-1), - directory_(directory), - c_path_(NULL), - size_limit_(-1) { - assert(!directory.empty()); - } - - explicit MinidumpDescriptor(int fd) - : mode_(kWriteMinidumpToFd), - fd_(fd), - c_path_(NULL), - size_limit_(-1) { - assert(fd != -1); - } - - explicit MinidumpDescriptor(const MicrodumpOnConsole&) - : mode_(kWriteMicrodumpToConsole), - fd_(-1), - size_limit_(-1) {} - - explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor); - MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor); - - static MinidumpDescriptor getMicrodumpDescriptor(); - - bool IsFD() const { return mode_ == kWriteMinidumpToFd; } - - int fd() const { return fd_; } - - string directory() const { return directory_; } - - const char* path() const { return c_path_; } - - bool IsMicrodumpOnConsole() const { - return mode_ == kWriteMicrodumpToConsole; - } - - // Updates the path so it is unique. - // Should be called from a normal context: this methods uses the heap. - void UpdatePath(); - - off_t size_limit() const { return size_limit_; } - void set_size_limit(off_t limit) { size_limit_ = limit; } - - MicrodumpExtraInfo* microdump_extra_info() { - assert(IsMicrodumpOnConsole()); - return µdump_extra_info_; - }; - - private: - enum DumpMode { - kUninitialized = 0, - kWriteMinidumpToFile, - kWriteMinidumpToFd, - kWriteMicrodumpToConsole - }; - - // Specifies the dump mode (see DumpMode). - DumpMode mode_; - - // The file descriptor where the minidump is generated. - int fd_; - - // The directory where the minidump should be generated. - string directory_; - - // The full path to the generated minidump. - string path_; - - // The C string of |path_|. Precomputed so it can be access from a compromised - // context. - const char* c_path_; - - off_t size_limit_; - - // The extra microdump data (e.g. product name/version, build - // fingerprint, gpu fingerprint) that should be appended to the dump - // (microdump only). Microdumps don't have the ability of appending - // extra metadata after the dump is generated (as opposite to - // minidumps MIME fields), therefore the extra data must be provided - // upfront. Any memory pointed to by members of the - // MicrodumpExtraInfo struct must be valid for the lifetime of the - // process (read: the caller has to guarantee that it is stored in - // global static storage.) - MicrodumpExtraInfo microdump_extra_info_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.cc deleted file mode 100644 index fc23aa6d5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/linux/log/log.h" - -#if defined(__ANDROID__) -#include -#include -#else -#include "third_party/lss/linux_syscall_support.h" -#endif - -namespace logger { - -#if defined(__ANDROID__) -namespace { - -// __android_log_buf_write() is not exported in the NDK and is being used by -// dynamic runtime linking. Its declaration is taken from Android's -// system/core/include/log/log.h. -using AndroidLogBufferWriteFunc = int (*)(int bufID, int prio, const char *tag, - const char *text); -const int kAndroidCrashLogId = 4; // From LOG_ID_CRASH in log.h. -const char kAndroidLogTag[] = "google-breakpad"; - -bool g_crash_log_initialized = false; -AndroidLogBufferWriteFunc g_android_log_buf_write = nullptr; - -} // namespace - -void initializeCrashLogWriter() { - if (g_crash_log_initialized) - return; - g_android_log_buf_write = reinterpret_cast( - dlsym(RTLD_DEFAULT, "__android_log_buf_write")); - g_crash_log_initialized = true; -} - -int writeToCrashLog(const char* buf) { - // Try writing to the crash log ring buffer. If not available, fall back to - // the standard log buffer. - if (g_android_log_buf_write) { - return g_android_log_buf_write(kAndroidCrashLogId, ANDROID_LOG_FATAL, - kAndroidLogTag, buf); - } - return __android_log_write(ANDROID_LOG_FATAL, kAndroidLogTag, buf); -} -#endif - -int write(const char* buf, size_t nbytes) { -#if defined(__ANDROID__) - return __android_log_write(ANDROID_LOG_WARN, kAndroidLogTag, buf); -#else - return sys_write(2, buf, nbytes); -#endif -} - -} // namespace logger diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.h b/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.h deleted file mode 100644 index f94bbd5fb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/log/log.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_LOG_LOG_H_ -#define CLIENT_LINUX_LOG_LOG_H_ - -#include - -namespace logger { - -int write(const char* buf, size_t nbytes); - -// In the case of Android the log can be written to the default system log -// (default behavior of write() above, or to the crash log (see -// writeToCrashLog() below). -#if defined(__ANDROID__) - -// The logger must be initialized in a non-compromised context. -void initializeCrashLogWriter(); - -// Once initialized, writeToCrashLog is safe to use in a compromised context, -// even if the initialization failed, in which case this will silently fall -// back on write(). -int writeToCrashLog(const char* buf); -#endif - -} // namespace logger - -#endif // CLIENT_LINUX_LOG_LOG_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.cc deleted file mode 100644 index a508667a0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.cc +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This translation unit generates microdumps into the console (logcat on -// Android). See crbug.com/410294 for more info and design docs. - -#include "client/linux/microdump_writer/microdump_writer.h" - -#include - -#include - -#include "client/linux/dump_writer_common/thread_info.h" -#include "client/linux/dump_writer_common/ucontext_reader.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/handler/microdump_extra_info.h" -#include "client/linux/log/log.h" -#include "client/linux/minidump_writer/linux_ptrace_dumper.h" -#include "common/linux/file_id.h" -#include "common/linux/linux_libc_support.h" -#include "common/memory.h" - -namespace { - -using google_breakpad::auto_wasteful_vector; -using google_breakpad::ExceptionHandler; -using google_breakpad::kDefaultBuildIdSize; -using google_breakpad::LinuxDumper; -using google_breakpad::LinuxPtraceDumper; -using google_breakpad::MappingInfo; -using google_breakpad::MappingList; -using google_breakpad::MicrodumpExtraInfo; -using google_breakpad::RawContextCPU; -using google_breakpad::ThreadInfo; -using google_breakpad::UContextReader; - -const size_t kLineBufferSize = 2048; - -#if !defined(__LP64__) -// The following are only used by DumpFreeSpace, so need to be compiled -// in conditionally in the same way. - -template -Dst saturated_cast(Src src) { - if (src >= std::numeric_limits::max()) - return std::numeric_limits::max(); - if (src <= std::numeric_limits::min()) - return std::numeric_limits::min(); - return static_cast(src); -} - -int Log2Floor(uint64_t n) { - // Copied from chromium src/base/bits.h - if (n == 0) - return -1; - int log = 0; - uint64_t value = n; - for (int i = 5; i >= 0; --i) { - int shift = (1 << i); - uint64_t x = value >> shift; - if (x != 0) { - value = x; - log += shift; - } - } - assert(value == 1u); - return log; -} - -bool MappingsAreAdjacent(const MappingInfo& a, const MappingInfo& b) { - // Because of load biasing, we can end up with a situation where two - // mappings actually overlap. So we will define adjacency to also include a - // b start address that lies within a's address range (including starting - // immediately after a). - // Because load biasing only ever moves the start address backwards, the end - // address should still increase. - return a.start_addr <= b.start_addr && a.start_addr + a.size >= b.start_addr; -} - -bool MappingLessThan(const MappingInfo* a, const MappingInfo* b) { - // Return true if mapping a is before mapping b. - // For the same reason (load biasing) we compare end addresses, which - unlike - // start addresses - will not have been modified. - return a->start_addr + a->size < b->start_addr + b->size; -} - -size_t NextOrderedMapping( - const google_breakpad::wasteful_vector& mappings, - size_t curr) { - // Find the mapping that directly follows mappings[curr]. - // If no such mapping exists, return |invalid| to indicate this. - const size_t invalid = std::numeric_limits::max(); - size_t best = invalid; - for (size_t next = 0; next < mappings.size(); ++next) { - if (MappingLessThan(mappings[curr], mappings[next]) && - (best == invalid || MappingLessThan(mappings[next], mappings[best]))) { - best = next; - } - } - return best; -} - -#endif // !__LP64__ - -class MicrodumpWriter { - public: - MicrodumpWriter(const ExceptionHandler::CrashContext* context, - const MappingList& mappings, - const MicrodumpExtraInfo& microdump_extra_info, - LinuxDumper* dumper) - : ucontext_(context ? &context->context : NULL), -#if !defined(__ARM_EABI__) && !defined(__mips__) - float_state_(context ? &context->float_state : NULL), -#endif - dumper_(dumper), - mapping_list_(mappings), - microdump_extra_info_(microdump_extra_info), - log_line_(NULL) { - log_line_ = reinterpret_cast(Alloc(kLineBufferSize)); - if (log_line_) - log_line_[0] = '\0'; // Clear out the log line buffer. - } - - ~MicrodumpWriter() { dumper_->ThreadsResume(); } - - bool Init() { - // In the exceptional case where the system was out of memory and there - // wasn't even room to allocate the line buffer, bail out. There is nothing - // useful we can possibly achieve without the ability to Log. At least let's - // try to not crash. - if (!dumper_->Init() || !log_line_) - return false; - return dumper_->ThreadsSuspend() && dumper_->LateInit(); - } - - bool Dump() { - bool success; - LogLine("-----BEGIN BREAKPAD MICRODUMP-----"); - DumpProductInformation(); - DumpOSInformation(); - DumpProcessType(); - DumpGPUInformation(); -#if !defined(__LP64__) - DumpFreeSpace(); -#endif - success = DumpCrashingThread(); - if (success) - success = DumpMappings(); - LogLine("-----END BREAKPAD MICRODUMP-----"); - dumper_->ThreadsResume(); - return success; - } - - private: - // Writes one line to the system log. - void LogLine(const char* msg) { -#if defined(__ANDROID__) - logger::writeToCrashLog(msg); -#else - logger::write(msg, my_strlen(msg)); - logger::write("\n", 1); -#endif - } - - // Stages the given string in the current line buffer. - void LogAppend(const char* str) { - my_strlcat(log_line_, str, kLineBufferSize); - } - - // As above (required to take precedence over template specialization below). - void LogAppend(char* str) { - LogAppend(const_cast(str)); - } - - // Stages the hex repr. of the given int type in the current line buffer. - template - void LogAppend(T value) { - // Make enough room to hex encode the largest int type + NUL. - static const char HEX[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; - char hexstr[sizeof(T) * 2 + 1]; - for (int i = sizeof(T) * 2 - 1; i >= 0; --i, value >>= 4) - hexstr[i] = HEX[static_cast(value) & 0x0F]; - hexstr[sizeof(T) * 2] = '\0'; - LogAppend(hexstr); - } - - // Stages the buffer content hex-encoded in the current line buffer. - void LogAppend(const void* buf, size_t length) { - const uint8_t* ptr = reinterpret_cast(buf); - for (size_t i = 0; i < length; ++i, ++ptr) - LogAppend(*ptr); - } - - // Writes out the current line buffer on the system log. - void LogCommitLine() { - LogLine(log_line_); - my_strlcpy(log_line_, "", kLineBufferSize); - } - - void DumpProductInformation() { - LogAppend("V "); - if (microdump_extra_info_.product_info) { - LogAppend(microdump_extra_info_.product_info); - } else { - LogAppend("UNKNOWN:0.0.0.0"); - } - LogCommitLine(); - } - - void DumpProcessType() { - LogAppend("P "); - if (microdump_extra_info_.process_type) { - LogAppend(microdump_extra_info_.process_type); - } else { - LogAppend("UNKNOWN"); - } - LogCommitLine(); - } - - void DumpOSInformation() { - const uint8_t n_cpus = static_cast(sysconf(_SC_NPROCESSORS_CONF)); - -#if defined(__ANDROID__) - const char kOSId[] = "A"; -#else - const char kOSId[] = "L"; -#endif - -// Dump the runtime architecture. On multiarch devices it might not match the -// hw architecture (the one returned by uname()), for instance in the case of -// a 32-bit app running on a aarch64 device. -#if defined(__aarch64__) - const char kArch[] = "arm64"; -#elif defined(__ARMEL__) - const char kArch[] = "arm"; -#elif defined(__x86_64__) - const char kArch[] = "x86_64"; -#elif defined(__i386__) - const char kArch[] = "x86"; -#elif defined(__mips__) -# if _MIPS_SIM == _ABIO32 - const char kArch[] = "mips"; -# elif _MIPS_SIM == _ABI64 - const char kArch[] = "mips64"; -# else -# error "This mips ABI is currently not supported (n32)" -#endif -#else -#error "This code has not been ported to your platform yet" -#endif - - LogAppend("O "); - LogAppend(kOSId); - LogAppend(" "); - LogAppend(kArch); - LogAppend(" "); - LogAppend(n_cpus); - LogAppend(" "); - - // Dump the HW architecture (e.g., armv7l, aarch64). - struct utsname uts; - const bool has_uts_info = (uname(&uts) == 0); - const char* hwArch = has_uts_info ? uts.machine : "unknown_hw_arch"; - LogAppend(hwArch); - LogAppend(" "); - - // If the client has attached a build fingerprint to the MinidumpDescriptor - // use that one. Otherwise try to get some basic info from uname(). - if (microdump_extra_info_.build_fingerprint) { - LogAppend(microdump_extra_info_.build_fingerprint); - } else if (has_uts_info) { - LogAppend(uts.release); - LogAppend(" "); - LogAppend(uts.version); - } else { - LogAppend("no build fingerprint available"); - } - LogCommitLine(); - } - - void DumpGPUInformation() { - LogAppend("G "); - if (microdump_extra_info_.gpu_fingerprint) { - LogAppend(microdump_extra_info_.gpu_fingerprint); - } else { - LogAppend("UNKNOWN"); - } - LogCommitLine(); - } - - bool DumpThreadStack(uint32_t thread_id, - uintptr_t stack_pointer, - int max_stack_len, - uint8_t** stack_copy) { - *stack_copy = NULL; - const void* stack; - size_t stack_len; - - if (!dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) { - // The stack pointer might not be available. In this case we don't hard - // fail, just produce a (almost useless) microdump w/o a stack section. - return true; - } - - LogAppend("S 0 "); - LogAppend(stack_pointer); - LogAppend(" "); - LogAppend(reinterpret_cast(stack)); - LogAppend(" "); - LogAppend(stack_len); - LogCommitLine(); - - if (max_stack_len >= 0 && - stack_len > static_cast(max_stack_len)) { - stack_len = max_stack_len; - } - - *stack_copy = reinterpret_cast(Alloc(stack_len)); - dumper_->CopyFromProcess(*stack_copy, thread_id, stack, stack_len); - - // Dump the content of the stack, splicing it into chunks which size is - // compatible with the max logcat line size (see LOGGER_ENTRY_MAX_PAYLOAD). - const size_t STACK_DUMP_CHUNK_SIZE = 384; - for (size_t stack_off = 0; stack_off < stack_len; - stack_off += STACK_DUMP_CHUNK_SIZE) { - LogAppend("S "); - LogAppend(reinterpret_cast(stack) + stack_off); - LogAppend(" "); - LogAppend(*stack_copy + stack_off, - std::min(STACK_DUMP_CHUNK_SIZE, stack_len - stack_off)); - LogCommitLine(); - } - return true; - } - - // Write information about the crashing thread. - bool DumpCrashingThread() { - const unsigned num_threads = dumper_->threads().size(); - - for (unsigned i = 0; i < num_threads; ++i) { - MDRawThread thread; - my_memset(&thread, 0, sizeof(thread)); - thread.thread_id = dumper_->threads()[i]; - - // Dump only the crashing thread. - if (static_cast(thread.thread_id) != dumper_->crash_thread()) - continue; - - assert(ucontext_); - assert(!dumper_->IsPostMortem()); - - uint8_t* stack_copy; - const uintptr_t stack_ptr = UContextReader::GetStackPointer(ucontext_); - if (!DumpThreadStack(thread.thread_id, stack_ptr, -1, &stack_copy)) - return false; - - RawContextCPU cpu; - my_memset(&cpu, 0, sizeof(RawContextCPU)); -#if !defined(__ARM_EABI__) && !defined(__mips__) - UContextReader::FillCPUContext(&cpu, ucontext_, float_state_); -#else - UContextReader::FillCPUContext(&cpu, ucontext_); -#endif - DumpCPUState(&cpu); - } - return true; - } - - void DumpCPUState(RawContextCPU* cpu) { - LogAppend("C "); - LogAppend(cpu, sizeof(*cpu)); - LogCommitLine(); - } - - // If there is caller-provided information about this mapping - // in the mapping_list_ list, return true. Otherwise, return false. - bool HaveMappingInfo(const MappingInfo& mapping) { - for (MappingList::const_iterator iter = mapping_list_.begin(); - iter != mapping_list_.end(); - ++iter) { - // Ignore any mappings that are wholly contained within - // mappings in the mapping_info_ list. - if (mapping.start_addr >= iter->first.start_addr && - (mapping.start_addr + mapping.size) <= - (iter->first.start_addr + iter->first.size)) { - return true; - } - } - return false; - } - - // Dump information about the provided |mapping|. If |identifier| is non-NULL, - // use it instead of calculating a file ID from the mapping. - void DumpModule(const MappingInfo& mapping, - bool member, - unsigned int mapping_id, - const uint8_t* identifier) { - - auto_wasteful_vector identifier_bytes( - dumper_->allocator()); - - if (identifier) { - // GUID was provided by caller. - identifier_bytes.insert(identifier_bytes.end(), - identifier, - identifier + sizeof(MDGUID)); - } else { - dumper_->ElfFileIdentifierForMapping( - mapping, - member, - mapping_id, - identifier_bytes); - } - - // Copy as many bytes of |identifier| as will fit into a MDGUID - MDGUID module_identifier = {0}; - memcpy(&module_identifier, &identifier_bytes[0], - std::min(sizeof(MDGUID), identifier_bytes.size())); - - char file_name[NAME_MAX]; - char file_path[NAME_MAX]; - dumper_->GetMappingEffectiveNameAndPath( - mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); - - LogAppend("M "); - LogAppend(static_cast(mapping.start_addr)); - LogAppend(" "); - LogAppend(mapping.offset); - LogAppend(" "); - LogAppend(mapping.size); - LogAppend(" "); - LogAppend(module_identifier.data1); - LogAppend(module_identifier.data2); - LogAppend(module_identifier.data3); - LogAppend(module_identifier.data4[0]); - LogAppend(module_identifier.data4[1]); - LogAppend(module_identifier.data4[2]); - LogAppend(module_identifier.data4[3]); - LogAppend(module_identifier.data4[4]); - LogAppend(module_identifier.data4[5]); - LogAppend(module_identifier.data4[6]); - LogAppend(module_identifier.data4[7]); - LogAppend("0 "); // Age is always 0 on Linux. - LogAppend(file_name); - LogCommitLine(); - } - -#if !defined(__LP64__) - void DumpFreeSpace() { - const google_breakpad::wasteful_vector& mappings = - dumper_->mappings(); - if (mappings.size() == 0) return; - - // This is complicated by the fact that mappings is not in order. It should - // be mostly in order, however the mapping that contains the entry point for - // the process is always at the front of the vector. - - static const int HBITS = sizeof(size_t) * 8; - size_t hole_histogram[HBITS]; - my_memset(hole_histogram, 0, sizeof(hole_histogram)); - - // Find the lowest address mapping. - size_t curr = 0; - for (size_t i = 1; i < mappings.size(); ++i) { - if (mappings[i]->start_addr < mappings[curr]->start_addr) curr = i; - } - - uintptr_t lo_addr = mappings[curr]->start_addr; - - size_t hole_cnt = 0; - size_t hole_max = 0; - size_t hole_sum = 0; - - while (true) { - // Skip to the end of an adjacent run of mappings. This is an optimization - // for the fact that mappings is mostly sorted. - while (curr != mappings.size() - 1 && - MappingsAreAdjacent(*mappings[curr], *mappings[curr + 1])) { - ++curr; - } - - size_t next = NextOrderedMapping(mappings, curr); - if (next == std::numeric_limits::max()) - break; - - uintptr_t hole_lo = mappings[curr]->start_addr + mappings[curr]->size; - uintptr_t hole_hi = mappings[next]->start_addr; - - if (hole_hi > hole_lo) { - size_t hole_sz = hole_hi - hole_lo; - hole_sum += hole_sz; - hole_max = std::max(hole_sz, hole_max); - ++hole_cnt; - ++hole_histogram[Log2Floor(hole_sz)]; - } - curr = next; - } - - uintptr_t hi_addr = mappings[curr]->start_addr + mappings[curr]->size; - - LogAppend("H "); - LogAppend(lo_addr); - LogAppend(" "); - LogAppend(hi_addr); - LogAppend(" "); - LogAppend(saturated_cast(hole_cnt)); - LogAppend(" "); - LogAppend(hole_max); - LogAppend(" "); - LogAppend(hole_sum); - for (unsigned int i = 0; i < HBITS; ++i) { - if (!hole_histogram[i]) continue; - LogAppend(" "); - LogAppend(saturated_cast(i)); - LogAppend(":"); - LogAppend(saturated_cast(hole_histogram[i])); - } - LogCommitLine(); - } -#endif - - // Write information about the mappings in effect. - bool DumpMappings() { - // First write all the mappings from the dumper - for (unsigned i = 0; i < dumper_->mappings().size(); ++i) { - const MappingInfo& mapping = *dumper_->mappings()[i]; - if (mapping.name[0] == 0 || // only want modules with filenames. - !mapping.exec || // only want executable mappings. - mapping.size < 4096 || // too small to get a signature for. - HaveMappingInfo(mapping)) { - continue; - } - - DumpModule(mapping, true, i, NULL); - } - // Next write all the mappings provided by the caller - for (MappingList::const_iterator iter = mapping_list_.begin(); - iter != mapping_list_.end(); - ++iter) { - DumpModule(iter->first, false, 0, iter->second); - } - return true; - } - - void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); } - - const ucontext_t* const ucontext_; -#if !defined(__ARM_EABI__) && !defined(__mips__) - const google_breakpad::fpstate_t* const float_state_; -#endif - LinuxDumper* dumper_; - const MappingList& mapping_list_; - const MicrodumpExtraInfo microdump_extra_info_; - char* log_line_; -}; -} // namespace - -namespace google_breakpad { - -bool WriteMicrodump(pid_t crashing_process, - const void* blob, - size_t blob_size, - const MappingList& mappings, - const MicrodumpExtraInfo& microdump_extra_info) { - LinuxPtraceDumper dumper(crashing_process); - const ExceptionHandler::CrashContext* context = NULL; - if (blob) { - if (blob_size != sizeof(ExceptionHandler::CrashContext)) - return false; - context = reinterpret_cast(blob); - dumper.set_crash_address( - reinterpret_cast(context->siginfo.si_addr)); - dumper.set_crash_signal(context->siginfo.si_signo); - dumper.set_crash_thread(context->tid); - } - MicrodumpWriter writer(context, mappings, microdump_extra_info, &dumper); - if (!writer.Init()) - return false; - return writer.Dump(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.h b/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.h deleted file mode 100644 index 7c742761d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ - -#include -#include - -#include "client/linux/dump_writer_common/mapping_info.h" - -namespace google_breakpad { - -struct MicrodumpExtraInfo; - -// Writes a microdump (a reduced dump containing only the state of the crashing -// thread) on the console (logcat on Android). These functions do not malloc nor -// use libc functions which may. Thus, it can be used in contexts where the -// state of the heap may be corrupt. -// Args: -// crashing_process: the pid of the crashing process. This must be trusted. -// blob: a blob of data from the crashing process. See exception_handler.h -// blob_size: the length of |blob| in bytes. -// mappings: a list of additional mappings provided by the application. -// build_fingerprint: a (optional) C string which determines the OS -// build fingerprint (e.g., aosp/occam/mako:5.1.1/LMY47W/1234:eng/dev-keys). -// product_info: a (optional) C string which determines the product name and -// version (e.g., WebView:42.0.2311.136). -// -// Returns true iff successful. -bool WriteMicrodump(pid_t crashing_process, - const void* blob, - size_t blob_size, - const MappingList& mappings, - const MicrodumpExtraInfo& microdump_extra_info); - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer_unittest.cc deleted file mode 100644 index 58a731188..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/microdump_writer/microdump_writer_unittest.cc +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/handler/microdump_extra_info.h" -#include "client/linux/microdump_writer/microdump_writer.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/ignore_ret.h" -#include "common/scoped_ptr.h" -#include "common/tests/auto_tempdir.h" -#include "common/using_std_string.h" - -using namespace google_breakpad; - -namespace { - -typedef testing::Test MicrodumpWriterTest; - -MicrodumpExtraInfo MakeMicrodumpExtraInfo( - const char* build_fingerprint, - const char* product_info, - const char* gpu_fingerprint) { - MicrodumpExtraInfo info; - info.build_fingerprint = build_fingerprint; - info.product_info = product_info; - info.gpu_fingerprint = gpu_fingerprint; - return info; -} - -void CrashAndGetMicrodump( - const MappingList& mappings, - const MicrodumpExtraInfo& microdump_extra_info, - scoped_array* buf) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - AutoTempDir temp_dir; - string stderr_file = temp_dir.path() + "/stderr.log"; - int err_fd = open(stderr_file.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - ASSERT_NE(-1, err_fd); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - - // Set a non-zero tid to avoid tripping asserts. - context.tid = child; - - // Redirect temporarily stderr to the stderr.log file. - int save_err = dup(STDERR_FILENO); - ASSERT_NE(-1, save_err); - ASSERT_NE(-1, dup2(err_fd, STDERR_FILENO)); - - ASSERT_TRUE(WriteMicrodump(child, &context, sizeof(context), mappings, - microdump_extra_info)); - - // Revert stderr back to the console. - dup2(save_err, STDERR_FILENO); - close(save_err); - - // Read back the stderr file and check for the microdump marker. - fsync(err_fd); - lseek(err_fd, 0, SEEK_SET); - const size_t kBufSize = 64 * 1024; - buf->reset(new char[kBufSize]); - ASSERT_GT(read(err_fd, buf->get(), kBufSize), 0); - - close(err_fd); - close(fds[1]); - - ASSERT_NE(static_cast(0), strstr( - buf->get(), "-----BEGIN BREAKPAD MICRODUMP-----")); - ASSERT_NE(static_cast(0), strstr( - buf->get(), "-----END BREAKPAD MICRODUMP-----")); -} - -void CheckMicrodumpContents(const string& microdump_content, - const MicrodumpExtraInfo& expected_info) { - std::istringstream iss(microdump_content); - bool did_find_os_info = false; - bool did_find_product_info = false; - bool did_find_gpu_info = false; - for (string line; std::getline(iss, line);) { - if (line.find("O ") == 0) { - std::istringstream os_info_tokens(line); - string token; - os_info_tokens.ignore(2); // Ignore the "O " preamble. - // Check the OS descriptor char (L=Linux, A=Android). - os_info_tokens >> token; - ASSERT_TRUE(token == "L" || token == "A"); - - os_info_tokens >> token; // HW architecture. - os_info_tokens >> token; // Number of cpus. - for (size_t i = 0; i < token.size(); ++i) - ASSERT_TRUE(isxdigit(token[i])); - os_info_tokens >> token; // SW architecture. - - // Check that the build fingerprint is in the right place. - os_info_tokens >> token; - if (expected_info.build_fingerprint) - ASSERT_EQ(expected_info.build_fingerprint, token); - did_find_os_info = true; - } else if (line.find("V ") == 0) { - if (expected_info.product_info) - ASSERT_EQ(string("V ") + expected_info.product_info, line); - did_find_product_info = true; - } else if (line.find("G ") == 0) { - if (expected_info.gpu_fingerprint) - ASSERT_EQ(string("G ") + expected_info.gpu_fingerprint, line); - did_find_gpu_info = true; - } - } - ASSERT_TRUE(did_find_os_info); - ASSERT_TRUE(did_find_product_info); - ASSERT_TRUE(did_find_gpu_info); -} - -void CheckMicrodumpContents(const string& microdump_content, - const string& expected_fingerprint, - const string& expected_product_info, - const string& expected_gpu_fingerprint) { - CheckMicrodumpContents( - microdump_content, - MakeMicrodumpExtraInfo(expected_fingerprint.c_str(), - expected_product_info.c_str(), - expected_gpu_fingerprint.c_str())); -} - -TEST(MicrodumpWriterTest, BasicWithMappings) { - // Push some extra mapping to check the MappingList logic. - const uint32_t memory_size = sysconf(_SC_PAGESIZE); - const char* kMemoryName = "libfoo.so"; - const uint8_t kModuleGUID[sizeof(MDGUID)] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - }; - - MappingInfo info; - info.start_addr = memory_size; - info.size = memory_size; - info.offset = 42; - strcpy(info.name, kMemoryName); - - MappingList mappings; - MappingEntry mapping; - mapping.first = info; - memcpy(mapping.second, kModuleGUID, sizeof(MDGUID)); - mappings.push_back(mapping); - - scoped_array buf; - CrashAndGetMicrodump(mappings, MicrodumpExtraInfo(), &buf); - -#ifdef __LP64__ - ASSERT_NE(static_cast(0), strstr( - buf.get(), "M 0000000000001000 000000000000002A 0000000000001000 " - "33221100554477668899AABBCCDDEEFF0 libfoo.so")); -#else - ASSERT_NE(static_cast(0), strstr( - buf.get(), "M 00001000 0000002A 00001000 " - "33221100554477668899AABBCCDDEEFF0 libfoo.so")); -#endif - - // In absence of a product info in the minidump, the writer should just write - // an unknown marker. - ASSERT_NE(static_cast(0), strstr( - buf.get(), "V UNKNOWN:0.0.0.0")); -} - -// Ensure that the product info and build fingerprint metadata show up in the -// final microdump if present. -TEST(MicrodumpWriterTest, BuildFingerprintAndProductInfo) { - const char kProductInfo[] = "MockProduct:42.0.2311.99"; - const char kBuildFingerprint[] = - "aosp/occam/mako:5.1.1/LMY47W/12345678:userdegbug/dev-keys"; - const char kGPUFingerprint[] = - "Qualcomm;Adreno (TM) 330;OpenGL ES 3.0 V@104.0 AU@ (GIT@Id3510ff6dc)"; - const MicrodumpExtraInfo kMicrodumpExtraInfo( - MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, kGPUFingerprint)); - scoped_array buf; - MappingList no_mappings; - - CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfo, &buf); - CheckMicrodumpContents(string(buf.get()), kMicrodumpExtraInfo); -} - -TEST(MicrodumpWriterTest, NoProductInfo) { - const char kBuildFingerprint[] = "foobar"; - const char kGPUFingerprint[] = "bazqux"; - scoped_array buf; - MappingList no_mappings; - - const MicrodumpExtraInfo kMicrodumpExtraInfoNoProductInfo( - MakeMicrodumpExtraInfo(kBuildFingerprint, NULL, kGPUFingerprint)); - - CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoProductInfo, &buf); - CheckMicrodumpContents(string(buf.get()), kBuildFingerprint, - "UNKNOWN:0.0.0.0", kGPUFingerprint); -} - -TEST(MicrodumpWriterTest, NoGPUInfo) { - const char kProductInfo[] = "bazqux"; - const char kBuildFingerprint[] = "foobar"; - scoped_array buf; - MappingList no_mappings; - - const MicrodumpExtraInfo kMicrodumpExtraInfoNoGPUInfo( - MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, NULL)); - - CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoGPUInfo, &buf); - CheckMicrodumpContents(string(buf.get()), kBuildFingerprint, - kProductInfo, "UNKNOWN"); -} -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set.h deleted file mode 100644 index 1cca9aa5a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_CPU_SET_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_CPU_SET_H_ - -#include -#include -#include - -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -// Helper class used to model a set of CPUs, as read from sysfs -// files like /sys/devices/system/cpu/present -// See See http://www.kernel.org/doc/Documentation/cputopology.txt -class CpuSet { -public: - // The maximum number of supported CPUs. - static const size_t kMaxCpus = 1024; - - CpuSet() { - my_memset(mask_, 0, sizeof(mask_)); - } - - // Parse a sysfs file to extract the corresponding CPU set. - bool ParseSysFile(int fd) { - char buffer[512]; - int ret = sys_read(fd, buffer, sizeof(buffer)-1); - if (ret < 0) - return false; - - buffer[ret] = '\0'; - - // Expected format: comma-separated list of items, where each - // item can be a decimal integer, or two decimal integers separated - // by a dash. - // E.g.: - // 0 - // 0,1,2,3 - // 0-3 - // 1,10-23 - const char* p = buffer; - const char* p_end = p + ret; - while (p < p_end) { - // Skip leading space, if any - while (p < p_end && my_isspace(*p)) - p++; - - // Find start and size of current item. - const char* item = p; - size_t item_len = static_cast(p_end - p); - const char* item_next = - static_cast(my_memchr(p, ',', item_len)); - if (item_next != NULL) { - p = item_next + 1; - item_len = static_cast(item_next - item); - } else { - p = p_end; - item_next = p_end; - } - - // Ignore trailing spaces. - while (item_next > item && my_isspace(item_next[-1])) - item_next--; - - // skip empty items. - if (item_next == item) - continue; - - // read first decimal value. - uintptr_t start = 0; - const char* next = my_read_decimal_ptr(&start, item); - uintptr_t end = start; - if (*next == '-') - my_read_decimal_ptr(&end, next+1); - - while (start <= end) - SetBit(start++); - } - return true; - } - - // Intersect this CPU set with another one. - void IntersectWith(const CpuSet& other) { - for (size_t nn = 0; nn < kMaskWordCount; ++nn) - mask_[nn] &= other.mask_[nn]; - } - - // Return the number of CPUs in this set. - int GetCount() { - int result = 0; - for (size_t nn = 0; nn < kMaskWordCount; ++nn) { - result += __builtin_popcount(mask_[nn]); - } - return result; - } - -private: - void SetBit(uintptr_t index) { - size_t nn = static_cast(index); - if (nn < kMaxCpus) - mask_[nn / kMaskWordBits] |= (1U << (nn % kMaskWordBits)); - } - - typedef uint32_t MaskWordType; - static const size_t kMaskWordBits = 8*sizeof(MaskWordType); - static const size_t kMaskWordCount = - (kMaxCpus + kMaskWordBits - 1) / kMaskWordBits; - - MaskWordType mask_[kMaskWordCount]; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_CPU_SET_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set_unittest.cc deleted file mode 100644 index e2274bd17..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/cpu_set_unittest.cc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/minidump_writer/cpu_set.h" -#include "common/linux/tests/auto_testfile.h" - -using namespace google_breakpad; - -namespace { - -typedef testing::Test CpuSetTest; - -// Helper class to write test text file to a temporary file and return -// its file descriptor. -class ScopedTestFile : public AutoTestFile { -public: - explicit ScopedTestFile(const char* text) - : AutoTestFile("cpu_set", text) { - } -}; - -} - -TEST(CpuSetTest, EmptyCount) { - CpuSet set; - ASSERT_EQ(0, set.GetCount()); -} - -TEST(CpuSetTest, OneCpu) { - ScopedTestFile file("10"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(1, set.GetCount()); -} - -TEST(CpuSetTest, OneCpuTerminated) { - ScopedTestFile file("10\n"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(1, set.GetCount()); -} - -TEST(CpuSetTest, TwoCpusWithComma) { - ScopedTestFile file("1,10"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(2, set.GetCount()); -} - -TEST(CpuSetTest, TwoCpusWithRange) { - ScopedTestFile file("1-2"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(2, set.GetCount()); -} - -TEST(CpuSetTest, TenCpusWithRange) { - ScopedTestFile file("9-18"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(10, set.GetCount()); -} - -TEST(CpuSetTest, MultiItems) { - ScopedTestFile file("0, 2-4, 128"); - ASSERT_TRUE(file.IsOk()); - - CpuSet set; - ASSERT_TRUE(set.ParseSysFile(file.GetFd())); - ASSERT_EQ(5, set.GetCount()); -} - -TEST(CpuSetTest, IntersectWith) { - ScopedTestFile file1("9-19"); - ASSERT_TRUE(file1.IsOk()); - CpuSet set1; - ASSERT_TRUE(set1.ParseSysFile(file1.GetFd())); - ASSERT_EQ(11, set1.GetCount()); - - ScopedTestFile file2("16-24"); - ASSERT_TRUE(file2.IsOk()); - CpuSet set2; - ASSERT_TRUE(set2.ParseSysFile(file2.GetFd())); - ASSERT_EQ(9, set2.GetCount()); - - set1.IntersectWith(set2); - ASSERT_EQ(4, set1.GetCount()); - ASSERT_EQ(9, set2.GetCount()); -} - -TEST(CpuSetTest, SelfIntersection) { - ScopedTestFile file1("9-19"); - ASSERT_TRUE(file1.IsOk()); - CpuSet set1; - ASSERT_TRUE(set1.ParseSysFile(file1.GetFd())); - ASSERT_EQ(11, set1.GetCount()); - - set1.IntersectWith(set1); - ASSERT_EQ(11, set1.GetCount()); -} - -TEST(CpuSetTest, EmptyIntersection) { - ScopedTestFile file1("0-19"); - ASSERT_TRUE(file1.IsOk()); - CpuSet set1; - ASSERT_TRUE(set1.ParseSysFile(file1.GetFd())); - ASSERT_EQ(20, set1.GetCount()); - - ScopedTestFile file2("20-39"); - ASSERT_TRUE(file2.IsOk()); - CpuSet set2; - ASSERT_TRUE(set2.ParseSysFile(file2.GetFd())); - ASSERT_EQ(20, set2.GetCount()); - - set1.IntersectWith(set2); - ASSERT_EQ(0, set1.GetCount()); - - ASSERT_EQ(20, set2.GetCount()); -} - diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader.h deleted file mode 100644 index a4bde1803..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_DIRECTORY_READER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_DIRECTORY_READER_H_ - -#include -#include -#include -#include -#include -#include - -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -// A class for enumerating a directory without using diropen/readdir or other -// functions which may allocate memory. -class DirectoryReader { - public: - DirectoryReader(int fd) - : fd_(fd), - buf_used_(0) { - } - - // Return the next entry from the directory - // name: (output) the NUL terminated entry name - // - // Returns true iff successful (false on EOF). - // - // After calling this, one must call |PopEntry| otherwise you'll get the same - // entry over and over. - bool GetNextEntry(const char** name) { - struct kernel_dirent* const dent = - reinterpret_cast(buf_); - - if (buf_used_ == 0) { - // need to read more entries. - const int n = sys_getdents(fd_, dent, sizeof(buf_)); - if (n < 0) { - return false; - } else if (n == 0) { - hit_eof_ = true; - } else { - buf_used_ += n; - } - } - - if (buf_used_ == 0 && hit_eof_) - return false; - - assert(buf_used_ > 0); - - *name = dent->d_name; - return true; - } - - void PopEntry() { - if (!buf_used_) - return; - - const struct kernel_dirent* const dent = - reinterpret_cast(buf_); - - buf_used_ -= dent->d_reclen; - my_memmove(buf_, buf_ + dent->d_reclen, buf_used_); - } - - private: - const int fd_; - bool hit_eof_; - unsigned buf_used_; - uint8_t buf_[sizeof(struct kernel_dirent) + NAME_MAX + 1]; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_DIRECTORY_READER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader_unittest.cc deleted file mode 100644 index 326f9e36b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader_unittest.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include - -#include -#include -#include - -#include "client/linux/minidump_writer/directory_reader.h" -#include "common/using_std_string.h" -#include "breakpad_googletest_includes.h" - -using namespace google_breakpad; - -namespace { -typedef testing::Test DirectoryReaderTest; -} - -TEST(DirectoryReaderTest, CompareResults) { - std::set dent_set; - - DIR *const dir = opendir("/proc/self"); - ASSERT_TRUE(dir != NULL); - - struct dirent* dent; - while ((dent = readdir(dir))) - dent_set.insert(dent->d_name); - - closedir(dir); - - const int fd = open("/proc/self", O_DIRECTORY | O_RDONLY); - ASSERT_GE(fd, 0); - - DirectoryReader dir_reader(fd); - unsigned seen = 0; - - const char* name; - while (dir_reader.GetNextEntry(&name)) { - ASSERT_TRUE(dent_set.find(name) != dent_set.end()); - seen++; - dir_reader.PopEntry(); - } - - ASSERT_TRUE(dent_set.find("status") != dent_set.end()); - ASSERT_TRUE(dent_set.find("stat") != dent_set.end()); - ASSERT_TRUE(dent_set.find("cmdline") != dent_set.end()); - - ASSERT_EQ(dent_set.size(), seen); - close(fd); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader.h deleted file mode 100644 index 779cfeb60..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINE_READER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_LINE_READER_H_ - -#include -#include -#include - -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -// A class for reading a file, line by line, without using fopen/fgets or other -// functions which may allocate memory. -class LineReader { - public: - LineReader(int fd) - : fd_(fd), - hit_eof_(false), - buf_used_(0) { - } - - // The maximum length of a line. - static const size_t kMaxLineLen = 512; - - // Return the next line from the file. - // line: (output) a pointer to the start of the line. The line is NUL - // terminated. - // len: (output) the length of the line (not inc the NUL byte) - // - // Returns true iff successful (false on EOF). - // - // One must call |PopLine| after this function, otherwise you'll continue to - // get the same line over and over. - bool GetNextLine(const char **line, unsigned *len) { - for (;;) { - if (buf_used_ == 0 && hit_eof_) - return false; - - for (unsigned i = 0; i < buf_used_; ++i) { - if (buf_[i] == '\n' || buf_[i] == 0) { - buf_[i] = 0; - *len = i; - *line = buf_; - return true; - } - } - - if (buf_used_ == sizeof(buf_)) { - // we scanned the whole buffer and didn't find an end-of-line marker. - // This line is too long to process. - return false; - } - - // We didn't find any end-of-line terminators in the buffer. However, if - // this is the last line in the file it might not have one: - if (hit_eof_) { - assert(buf_used_); - // There's room for the NUL because of the buf_used_ == sizeof(buf_) - // check above. - buf_[buf_used_] = 0; - *len = buf_used_; - buf_used_ += 1; // since we appended the NUL. - *line = buf_; - return true; - } - - // Otherwise, we should pull in more data from the file - const ssize_t n = sys_read(fd_, buf_ + buf_used_, - sizeof(buf_) - buf_used_); - if (n < 0) { - return false; - } else if (n == 0) { - hit_eof_ = true; - } else { - buf_used_ += n; - } - - // At this point, we have either set the hit_eof_ flag, or we have more - // data to process... - } - } - - void PopLine(unsigned len) { - // len doesn't include the NUL byte at the end. - - assert(buf_used_ >= len + 1); - buf_used_ -= len + 1; - my_memmove(buf_, buf_ + len + 1, buf_used_); - } - - private: - const int fd_; - - bool hit_eof_; - unsigned buf_used_; - char buf_[kMaxLineLen]; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_LINE_READER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader_unittest.cc deleted file mode 100644 index 29686f04a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader_unittest.cc +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -#include "client/linux/minidump_writer/line_reader.h" -#include "breakpad_googletest_includes.h" -#include "common/linux/tests/auto_testfile.h" - -using namespace google_breakpad; - -namespace { - -typedef testing::Test LineReaderTest; - -class ScopedTestFile : public AutoTestFile { -public: - explicit ScopedTestFile(const char* text) - : AutoTestFile("line_reader", text) { - } - - ScopedTestFile(const char* text, size_t text_len) - : AutoTestFile("line_reader", text, text_len) { - } -}; - -} - -TEST(LineReaderTest, EmptyFile) { - ScopedTestFile file(""); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} - -TEST(LineReaderTest, OneLineTerminated) { - ScopedTestFile file("a\n"); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned int len; - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned int)1, len); - ASSERT_EQ('a', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} - -TEST(LineReaderTest, OneLine) { - ScopedTestFile file("a"); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned)1, len); - ASSERT_EQ('a', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} - -TEST(LineReaderTest, TwoLinesTerminated) { - ScopedTestFile file("a\nb\n"); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned)1, len); - ASSERT_EQ('a', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned)1, len); - ASSERT_EQ('b', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} - -TEST(LineReaderTest, TwoLines) { - ScopedTestFile file("a\nb"); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned)1, len); - ASSERT_EQ('a', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ((unsigned)1, len); - ASSERT_EQ('b', line[0]); - ASSERT_EQ('\0', line[1]); - reader.PopLine(len); - - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} - -TEST(LineReaderTest, MaxLength) { - char l[LineReader::kMaxLineLen-1]; - memset(l, 'a', sizeof(l)); - ScopedTestFile file(l, sizeof(l)); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_TRUE(reader.GetNextLine(&line, &len)); - ASSERT_EQ(sizeof(l), len); - ASSERT_TRUE(memcmp(l, line, sizeof(l)) == 0); - ASSERT_EQ('\0', line[len]); -} - -TEST(LineReaderTest, TooLong) { - // Note: this writes kMaxLineLen 'a' chars in the test file. - char l[LineReader::kMaxLineLen]; - memset(l, 'a', sizeof(l)); - ScopedTestFile file(l, sizeof(l)); - ASSERT_TRUE(file.IsOk()); - LineReader reader(file.GetFd()); - - const char *line; - unsigned len; - ASSERT_FALSE(reader.GetNextLine(&line, &len)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc deleted file mode 100644 index 622f05069..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_core_dumper.cc: Implement google_breakpad::LinuxCoreDumper. -// See linux_core_dumper.h for details. - -#include "client/linux/minidump_writer/linux_core_dumper.h" - -#include -#include -#include -#include -#include -#include -#if defined(__mips__) && defined(__ANDROID__) -// To get register definitions. -#include -#endif - -#include "common/linux/linux_libc_support.h" - -namespace google_breakpad { - -LinuxCoreDumper::LinuxCoreDumper(pid_t pid, - const char* core_path, - const char* procfs_path, - const char* root_prefix) - : LinuxDumper(pid, root_prefix), - core_path_(core_path), - procfs_path_(procfs_path), - thread_infos_(&allocator_, 8) { - assert(core_path_); -} - -bool LinuxCoreDumper::BuildProcPath(char* path, pid_t pid, - const char* node) const { - if (!path || !node) - return false; - - size_t node_len = my_strlen(node); - if (node_len == 0) - return false; - - size_t procfs_path_len = my_strlen(procfs_path_); - size_t total_length = procfs_path_len + 1 + node_len; - if (total_length >= NAME_MAX) - return false; - - memcpy(path, procfs_path_, procfs_path_len); - path[procfs_path_len] = '/'; - memcpy(path + procfs_path_len + 1, node, node_len); - path[total_length] = '\0'; - return true; -} - -bool LinuxCoreDumper::CopyFromProcess(void* dest, pid_t child, - const void* src, size_t length) { - ElfCoreDump::Addr virtual_address = reinterpret_cast(src); - // TODO(benchan): Investigate whether the data to be copied could span - // across multiple segments in the core dump file. ElfCoreDump::CopyData - // and this method do not handle that case yet. - if (!core_.CopyData(dest, virtual_address, length)) { - // If the data segment is not found in the core dump, fill the result - // with marker characters. - memset(dest, 0xab, length); - return false; - } - return true; -} - -bool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) { - if (index >= thread_infos_.size()) - return false; - - *info = thread_infos_[index]; - const uint8_t* stack_pointer; -#if defined(__i386) - memcpy(&stack_pointer, &info->regs.esp, sizeof(info->regs.esp)); -#elif defined(__x86_64) - memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp)); -#elif defined(__ARM_EABI__) - memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp)); -#elif defined(__aarch64__) - memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp)); -#elif defined(__mips__) - stack_pointer = - reinterpret_cast(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]); -#else -#error "This code hasn't been ported to your platform yet." -#endif - info->stack_pointer = reinterpret_cast(stack_pointer); - return true; -} - -bool LinuxCoreDumper::IsPostMortem() const { - return true; -} - -bool LinuxCoreDumper::ThreadsSuspend() { - return true; -} - -bool LinuxCoreDumper::ThreadsResume() { - return true; -} - -bool LinuxCoreDumper::EnumerateThreads() { - if (!mapped_core_file_.Map(core_path_, 0)) { - fprintf(stderr, "Could not map core dump file into memory\n"); - return false; - } - - core_.SetContent(mapped_core_file_.content()); - if (!core_.IsValid()) { - fprintf(stderr, "Invalid core dump file\n"); - return false; - } - - ElfCoreDump::Note note = core_.GetFirstNote(); - if (!note.IsValid()) { - fprintf(stderr, "PT_NOTE section not found\n"); - return false; - } - - bool first_thread = true; - do { - ElfCoreDump::Word type = note.GetType(); - MemoryRange name = note.GetName(); - MemoryRange description = note.GetDescription(); - - if (type == 0 || name.IsEmpty() || description.IsEmpty()) { - fprintf(stderr, "Could not found a valid PT_NOTE.\n"); - return false; - } - - // Based on write_note_info() in linux/kernel/fs/binfmt_elf.c, notes are - // ordered as follows (NT_PRXFPREG and NT_386_TLS are i386 specific): - // Thread Name Type - // ------------------------------------------------------------------- - // 1st thread CORE NT_PRSTATUS - // process-wide CORE NT_PRPSINFO - // process-wide CORE NT_AUXV - // 1st thread CORE NT_FPREGSET - // 1st thread LINUX NT_PRXFPREG - // 1st thread LINUX NT_386_TLS - // - // 2nd thread CORE NT_PRSTATUS - // 2nd thread CORE NT_FPREGSET - // 2nd thread LINUX NT_PRXFPREG - // 2nd thread LINUX NT_386_TLS - // - // 3rd thread CORE NT_PRSTATUS - // 3rd thread CORE NT_FPREGSET - // 3rd thread LINUX NT_PRXFPREG - // 3rd thread LINUX NT_386_TLS - // - // The following code only works if notes are ordered as expected. - switch (type) { - case NT_PRSTATUS: { - if (description.length() != sizeof(elf_prstatus)) { - fprintf(stderr, "Found NT_PRSTATUS descriptor of unexpected size\n"); - return false; - } - - const elf_prstatus* status = - reinterpret_cast(description.data()); - pid_t pid = status->pr_pid; - ThreadInfo info; - memset(&info, 0, sizeof(ThreadInfo)); - info.tgid = status->pr_pgrp; - info.ppid = status->pr_ppid; -#if defined(__mips__) -#if defined(__ANDROID__) - for (int i = EF_R0; i <= EF_R31; i++) - info.mcontext.gregs[i - EF_R0] = status->pr_reg[i]; -#else // __ANDROID__ - for (int i = EF_REG0; i <= EF_REG31; i++) - info.mcontext.gregs[i - EF_REG0] = status->pr_reg[i]; -#endif // __ANDROID__ - info.mcontext.mdlo = status->pr_reg[EF_LO]; - info.mcontext.mdhi = status->pr_reg[EF_HI]; - info.mcontext.pc = status->pr_reg[EF_CP0_EPC]; -#else // __mips__ - memcpy(&info.regs, status->pr_reg, sizeof(info.regs)); -#endif // __mips__ - if (first_thread) { - crash_thread_ = pid; - crash_signal_ = status->pr_info.si_signo; - } - first_thread = false; - threads_.push_back(pid); - thread_infos_.push_back(info); - break; - } -#if defined(__i386) || defined(__x86_64) - case NT_FPREGSET: { - if (thread_infos_.empty()) - return false; - - ThreadInfo* info = &thread_infos_.back(); - if (description.length() != sizeof(info->fpregs)) { - fprintf(stderr, "Found NT_FPREGSET descriptor of unexpected size\n"); - return false; - } - - memcpy(&info->fpregs, description.data(), sizeof(info->fpregs)); - break; - } -#endif -#if defined(__i386) - case NT_PRXFPREG: { - if (thread_infos_.empty()) - return false; - - ThreadInfo* info = &thread_infos_.back(); - if (description.length() != sizeof(info->fpxregs)) { - fprintf(stderr, "Found NT_PRXFPREG descriptor of unexpected size\n"); - return false; - } - - memcpy(&info->fpxregs, description.data(), sizeof(info->fpxregs)); - break; - } -#endif - } - note = note.GetNextNote(); - } while (note.IsValid()); - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.h deleted file mode 100644 index 8a7c924b6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_core_dumper.h: Define the google_breakpad::LinuxCoreDumper -// class, which is derived from google_breakpad::LinuxDumper to extract -// information from a crashed process via its core dump and proc files. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_CORE_DUMPER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_CORE_DUMPER_H_ - -#include "client/linux/minidump_writer/linux_dumper.h" -#include "common/linux/elf_core_dump.h" -#include "common/linux/memory_mapped_file.h" - -namespace google_breakpad { - -class LinuxCoreDumper : public LinuxDumper { - public: - // Constructs a dumper for extracting information of a given process - // with a process ID of |pid| via its core dump file at |core_path| and - // its proc files at |procfs_path|. If |procfs_path| is a copy of - // /proc/, it should contain the following files: - // auxv, cmdline, environ, exe, maps, status - // See LinuxDumper for the purpose of |root_prefix|. - LinuxCoreDumper(pid_t pid, const char* core_path, const char* procfs_path, - const char* root_prefix = ""); - - // Implements LinuxDumper::BuildProcPath(). - // Builds a proc path for a certain pid for a node (/proc//). - // |path| is a character array of at least NAME_MAX bytes to return the - // result.|node| is the final node without any slashes. Return true on - // success. - // - // As this dumper performs a post-mortem dump and makes use of a copy - // of the proc files of the crashed process, this derived method does - // not actually make use of |pid| and always returns a subpath of - // |procfs_path_| regardless of whether |pid| corresponds to the main - // process or a thread of the process, i.e. assuming both the main process - // and its threads have the following proc files with the same content: - // auxv, cmdline, environ, exe, maps, status - virtual bool BuildProcPath(char* path, pid_t pid, const char* node) const; - - // Implements LinuxDumper::CopyFromProcess(). - // Copies content of |length| bytes from a given process |child|, - // starting from |src|, into |dest|. This method extracts the content - // the core dump and fills |dest| with a sequence of marker bytes - // if the expected data is not found in the core dump. Returns true if - // the expected data is found in the core dump. - virtual bool CopyFromProcess(void* dest, pid_t child, const void* src, - size_t length); - - // Implements LinuxDumper::GetThreadInfoByIndex(). - // Reads information about the |index|-th thread of |threads_|. - // Returns true on success. One must have called |ThreadsSuspend| first. - virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info); - - // Implements LinuxDumper::IsPostMortem(). - // Always returns true to indicate that this dumper performs a - // post-mortem dump of a crashed process via a core dump file. - virtual bool IsPostMortem() const; - - // Implements LinuxDumper::ThreadsSuspend(). - // As the dumper performs a post-mortem dump via a core dump file, - // there is no threads to suspend. This method does nothing and - // always returns true. - virtual bool ThreadsSuspend(); - - // Implements LinuxDumper::ThreadsResume(). - // As the dumper performs a post-mortem dump via a core dump file, - // there is no threads to resume. This method does nothing and - // always returns true. - virtual bool ThreadsResume(); - - protected: - // Implements LinuxDumper::EnumerateThreads(). - // Enumerates all threads of the given process into |threads_|. - virtual bool EnumerateThreads(); - - private: - // Path of the core dump file. - const char* core_path_; - - // Path of the directory containing the proc files of the given process, - // which is usually a copy of /proc/. - const char* procfs_path_; - - // Memory-mapped core dump file at |core_path_|. - MemoryMappedFile mapped_core_file_; - - // Content of the core dump file. - ElfCoreDump core_; - - // Thread info found in the core dump file. - wasteful_vector thread_infos_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_HANDLER_LINUX_CORE_DUMPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc deleted file mode 100644 index ae0c965b3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_core_dumper_unittest.cc: -// Unit tests for google_breakpad::LinuxCoreDumoer. - -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/minidump_writer/linux_core_dumper.h" -#include "common/linux/tests/crash_generator.h" -#include "common/using_std_string.h" - -using namespace google_breakpad; - -TEST(LinuxCoreDumperTest, GetMappingAbsolutePath) { - const LinuxCoreDumper dumper(getpid(), "core", "/tmp", "/mnt/root"); - const MappingInfo mapping = { 0, 0, 0, false, "/usr/lib/libc.so" }; - - char path[PATH_MAX]; - dumper.GetMappingAbsolutePath(mapping, path); - - EXPECT_STREQ("/mnt/root/usr/lib/libc.so", path); -} - -TEST(LinuxCoreDumperTest, BuildProcPath) { - const pid_t pid = getpid(); - const char procfs_path[] = "/procfs_copy"; - LinuxCoreDumper dumper(getpid(), "core_file", procfs_path); - - char maps_path[NAME_MAX] = ""; - char maps_path_expected[NAME_MAX]; - snprintf(maps_path_expected, sizeof(maps_path_expected), - "%s/maps", procfs_path); - EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps")); - EXPECT_STREQ(maps_path_expected, maps_path); - - EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, "")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL)); - - char long_node[NAME_MAX]; - size_t long_node_len = NAME_MAX - strlen(procfs_path) - 1; - memset(long_node, 'a', long_node_len); - long_node[long_node_len] = '\0'; - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, long_node)); -} - -TEST(LinuxCoreDumperTest, VerifyDumpWithMultipleThreads) { - CrashGenerator crash_generator; - if (!crash_generator.HasDefaultCorePattern()) { - fprintf(stderr, "LinuxCoreDumperTest.VerifyDumpWithMultipleThreads test " - "is skipped due to non-default core pattern\n"); - return; - } - - const unsigned kNumOfThreads = 3; - const unsigned kCrashThread = 1; - const int kCrashSignal = SIGABRT; - pid_t child_pid; - ASSERT_TRUE(crash_generator.CreateChildCrash(kNumOfThreads, kCrashThread, - kCrashSignal, &child_pid)); - - const string core_file = crash_generator.GetCoreFilePath(); - const string procfs_path = crash_generator.GetDirectoryOfProcFilesCopy(); - -#if defined(__ANDROID__) - struct stat st; - if (stat(core_file.c_str(), &st) != 0) { - fprintf(stderr, "LinuxCoreDumperTest.VerifyDumpWithMultipleThreads test is " - "skipped due to no core file being generated"); - return; - } -#endif - - LinuxCoreDumper dumper(child_pid, core_file.c_str(), procfs_path.c_str()); - - EXPECT_TRUE(dumper.Init()); - - EXPECT_TRUE(dumper.IsPostMortem()); - - // These are no-ops and should always return true. - EXPECT_TRUE(dumper.ThreadsSuspend()); - EXPECT_TRUE(dumper.ThreadsResume()); - - // LinuxCoreDumper cannot determine the crash address and thus it always - // sets the crash address to 0. - EXPECT_EQ(0U, dumper.crash_address()); - EXPECT_EQ(kCrashSignal, dumper.crash_signal()); - EXPECT_EQ(crash_generator.GetThreadId(kCrashThread), - dumper.crash_thread()); - - EXPECT_EQ(kNumOfThreads, dumper.threads().size()); - for (unsigned i = 0; i < kNumOfThreads; ++i) { - ThreadInfo info; - EXPECT_TRUE(dumper.GetThreadInfoByIndex(i, &info)); - const void* stack; - size_t stack_len; - EXPECT_TRUE(dumper.GetStackInfo(&stack, &stack_len, info.stack_pointer)); - EXPECT_EQ(getpid(), info.ppid); - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc deleted file mode 100644 index bdbdc6507..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc +++ /dev/null @@ -1,776 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_dumper.cc: Implement google_breakpad::LinuxDumper. -// See linux_dumper.h for details. - -// This code deals with the mechanics of getting information about a crashed -// process. Since this code may run in a compromised address space, the same -// rules apply as detailed at the top of minidump_writer.h: no libc calls and -// use the alternative allocator. - -#include "client/linux/minidump_writer/linux_dumper.h" - -#include -#include -#include -#include -#include -#include - -#include "client/linux/minidump_writer/line_reader.h" -#include "common/linux/elfutils.h" -#include "common/linux/file_id.h" -#include "common/linux/linux_libc_support.h" -#include "common/linux/memory_mapped_file.h" -#include "common/linux/safe_readlink.h" -#include "third_party/lss/linux_syscall_support.h" - -#if defined(__ANDROID__) - -// Android packed relocations definitions are not yet available from the -// NDK header files, so we have to provide them manually here. -#ifndef DT_LOOS -#define DT_LOOS 0x6000000d -#endif -#ifndef DT_ANDROID_REL -static const int DT_ANDROID_REL = DT_LOOS + 2; -#endif -#ifndef DT_ANDROID_RELA -static const int DT_ANDROID_RELA = DT_LOOS + 4; -#endif - -#endif // __ANDROID __ - -static const char kMappedFileUnsafePrefix[] = "/dev/"; -static const char kDeletedSuffix[] = " (deleted)"; -static const char kReservedFlags[] = " ---p"; - -inline static bool IsMappedFileOpenUnsafe( - const google_breakpad::MappingInfo& mapping) { - // It is unsafe to attempt to open a mapped file that lives under /dev, - // because the semantics of the open may be driver-specific so we'd risk - // hanging the crash dumper. And a file in /dev/ almost certainly has no - // ELF file identifier anyways. - return my_strncmp(mapping.name, - kMappedFileUnsafePrefix, - sizeof(kMappedFileUnsafePrefix) - 1) == 0; -} - -namespace google_breakpad { - -#if defined(__CHROMEOS__) - -namespace { - -// Recover memory mappings before writing dump on ChromeOS -// -// On Linux, breakpad relies on /proc/[pid]/maps to associate symbols from -// addresses. ChromeOS' hugepage implementation replaces some segments with -// anonymous private pages, which is a restriction of current implementation -// in Linux kernel at the time of writing. Thus, breakpad can no longer -// symbolize addresses from those text segments replaced with hugepages. -// -// This postprocess tries to recover the mappings. Because hugepages are always -// inserted in between some .text sections, it tries to infer the names and -// offsets of the segments, by looking at segments immediately precede and -// succeed them. -// -// For example, a text segment before hugepage optimization -// 02001000-03002000 r-xp /opt/google/chrome/chrome -// -// can be broken into -// 02001000-02200000 r-xp /opt/google/chrome/chrome -// 02200000-03000000 r-xp -// 03000000-03002000 r-xp /opt/google/chrome/chrome -// -// For more details, see: -// crbug.com/628040 ChromeOS' use of hugepages confuses crash symbolization - -// Copied from CrOS' hugepage implementation, which is unlikely to change. -// The hugepage size is 2M. -const unsigned int kHpageShift = 21; -const size_t kHpageSize = (1 << kHpageShift); -const size_t kHpageMask = (~(kHpageSize - 1)); - -// Find and merge anonymous r-xp segments with surrounding named segments. -// There are two cases: - -// Case 1: curr, next -// curr is anonymous -// curr is r-xp -// curr.size >= 2M -// curr.size is a multiple of 2M. -// next is backed by some file. -// curr and next are contiguous. -// offset(next) == sizeof(curr) -void TryRecoverMappings(MappingInfo *curr, MappingInfo *next) { - // Merged segments are marked with size = 0. - if (curr->size == 0 || next->size == 0) - return; - - if (curr->size >= kHpageSize && - curr->exec && - (curr->size & kHpageMask) == curr->size && - (curr->start_addr & kHpageMask) == curr->start_addr && - curr->name[0] == '\0' && - next->name[0] != '\0' && - curr->start_addr + curr->size == next->start_addr && - curr->size == next->offset) { - - // matched - my_strlcpy(curr->name, next->name, NAME_MAX); - if (next->exec) { - // (curr, next) - curr->size += next->size; - next->size = 0; - } - } -} - -// Case 2: prev, curr, next -// curr is anonymous -// curr is r-xp -// curr.size >= 2M -// curr.size is a multiple of 2M. -// next and prev are backed by the same file. -// prev, curr and next are contiguous. -// offset(next) == offset(prev) + sizeof(prev) + sizeof(curr) -void TryRecoverMappings(MappingInfo *prev, MappingInfo *curr, - MappingInfo *next) { - // Merged segments are marked with size = 0. - if (prev->size == 0 || curr->size == 0 || next->size == 0) - return; - - if (curr->size >= kHpageSize && - curr->exec && - (curr->size & kHpageMask) == curr->size && - (curr->start_addr & kHpageMask) == curr->start_addr && - curr->name[0] == '\0' && - next->name[0] != '\0' && - curr->start_addr + curr->size == next->start_addr && - prev->start_addr + prev->size == curr->start_addr && - my_strncmp(prev->name, next->name, NAME_MAX) == 0 && - next->offset == prev->offset + prev->size + curr->size) { - - // matched - my_strlcpy(curr->name, prev->name, NAME_MAX); - if (prev->exec) { - curr->offset = prev->offset; - curr->start_addr = prev->start_addr; - if (next->exec) { - // (prev, curr, next) - curr->size += prev->size + next->size; - prev->size = 0; - next->size = 0; - } else { - // (prev, curr), next - curr->size += prev->size; - prev->size = 0; - } - } else { - curr->offset = prev->offset + prev->size; - if (next->exec) { - // prev, (curr, next) - curr->size += next->size; - next->size = 0; - } else { - // prev, curr, next - } - } - } -} - -// mappings_ is sorted excepted for the first entry. -// This function tries to merge segemnts into the first entry, -// then check for other sorted entries. -// See LinuxDumper::EnumerateMappings(). -void CrOSPostProcessMappings(wasteful_vector& mappings) { - // Find the candidate "next" to first segment, which is the only one that - // could be out-of-order. - size_t l = 1; - size_t r = mappings.size(); - size_t next = mappings.size(); - while (l < r) { - int m = (l + r) / 2; - if (mappings[m]->start_addr > mappings[0]->start_addr) - r = next = m; - else - l = m + 1; - } - - // Try to merge segments into the first. - if (next < mappings.size()) { - TryRecoverMappings(mappings[0], mappings[next]); - if (next - 1 > 0) - TryRecoverMappings(mappings[next - 1], mappings[0], mappings[next]); - } - - // Iterate through normal, sorted cases. - // Normal case 1. - for (size_t i = 1; i < mappings.size() - 1; i++) - TryRecoverMappings(mappings[i], mappings[i + 1]); - - // Normal case 2. - for (size_t i = 1; i < mappings.size() - 2; i++) - TryRecoverMappings(mappings[i], mappings[i + 1], mappings[i + 2]); - - // Collect merged (size == 0) segments. - size_t f, e; - for (f = e = 0; e < mappings.size(); e++) - if (mappings[e]->size > 0) - mappings[f++] = mappings[e]; - mappings.resize(f); -} - -} // namespace -#endif // __CHROMEOS__ - -// All interesting auvx entry types are below AT_SYSINFO_EHDR -#define AT_MAX AT_SYSINFO_EHDR - -LinuxDumper::LinuxDumper(pid_t pid, const char* root_prefix) - : pid_(pid), - root_prefix_(root_prefix), - crash_address_(0), - crash_signal_(0), - crash_thread_(pid), - threads_(&allocator_, 8), - mappings_(&allocator_), - auxv_(&allocator_, AT_MAX + 1) { - assert(root_prefix_ && my_strlen(root_prefix_) < PATH_MAX); - // The passed-in size to the constructor (above) is only a hint. - // Must call .resize() to do actual initialization of the elements. - auxv_.resize(AT_MAX + 1); -} - -LinuxDumper::~LinuxDumper() { -} - -bool LinuxDumper::Init() { - return ReadAuxv() && EnumerateThreads() && EnumerateMappings(); -} - -bool LinuxDumper::LateInit() { -#if defined(__ANDROID__) - LatePostprocessMappings(); -#endif - -#if defined(__CHROMEOS__) - CrOSPostProcessMappings(mappings_); -#endif - - return true; -} - -bool -LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping, - bool member, - unsigned int mapping_id, - wasteful_vector& identifier) { - assert(!member || mapping_id < mappings_.size()); - if (IsMappedFileOpenUnsafe(mapping)) - return false; - - // Special-case linux-gate because it's not a real file. - if (my_strcmp(mapping.name, kLinuxGateLibraryName) == 0) { - void* linux_gate = NULL; - if (pid_ == sys_getpid()) { - linux_gate = reinterpret_cast(mapping.start_addr); - } else { - linux_gate = allocator_.Alloc(mapping.size); - CopyFromProcess(linux_gate, pid_, - reinterpret_cast(mapping.start_addr), - mapping.size); - } - return FileID::ElfFileIdentifierFromMappedFile(linux_gate, identifier); - } - - char filename[PATH_MAX]; - if (!GetMappingAbsolutePath(mapping, filename)) - return false; - bool filename_modified = HandleDeletedFileInMapping(filename); - - MemoryMappedFile mapped_file(filename, mapping.offset); - if (!mapped_file.data() || mapped_file.size() < SELFMAG) - return false; - - bool success = - FileID::ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier); - if (success && member && filename_modified) { - mappings_[mapping_id]->name[my_strlen(mapping.name) - - sizeof(kDeletedSuffix) + 1] = '\0'; - } - - return success; -} - -bool LinuxDumper::GetMappingAbsolutePath(const MappingInfo& mapping, - char path[PATH_MAX]) const { - return my_strlcpy(path, root_prefix_, PATH_MAX) < PATH_MAX && - my_strlcat(path, mapping.name, PATH_MAX) < PATH_MAX; -} - -namespace { -bool ElfFileSoNameFromMappedFile( - const void* elf_base, char* soname, size_t soname_size) { - if (!IsValidElf(elf_base)) { - // Not ELF - return false; - } - - const void* segment_start; - size_t segment_size; - int elf_class; - if (!FindElfSection(elf_base, ".dynamic", SHT_DYNAMIC, - &segment_start, &segment_size, &elf_class)) { - // No dynamic section - return false; - } - - const void* dynstr_start; - size_t dynstr_size; - if (!FindElfSection(elf_base, ".dynstr", SHT_STRTAB, - &dynstr_start, &dynstr_size, &elf_class)) { - // No dynstr section - return false; - } - - const ElfW(Dyn)* dynamic = static_cast(segment_start); - size_t dcount = segment_size / sizeof(ElfW(Dyn)); - for (const ElfW(Dyn)* dyn = dynamic; dyn < dynamic + dcount; ++dyn) { - if (dyn->d_tag == DT_SONAME) { - const char* dynstr = static_cast(dynstr_start); - if (dyn->d_un.d_val >= dynstr_size) { - // Beyond the end of the dynstr section - return false; - } - const char* str = dynstr + dyn->d_un.d_val; - const size_t maxsize = dynstr_size - dyn->d_un.d_val; - my_strlcpy(soname, str, maxsize < soname_size ? maxsize : soname_size); - return true; - } - } - - // Did not find SONAME - return false; -} - -// Find the shared object name (SONAME) by examining the ELF information -// for |mapping|. If the SONAME is found copy it into the passed buffer -// |soname| and return true. The size of the buffer is |soname_size|. -// The SONAME will be truncated if it is too long to fit in the buffer. -bool ElfFileSoName(const LinuxDumper& dumper, - const MappingInfo& mapping, char* soname, size_t soname_size) { - if (IsMappedFileOpenUnsafe(mapping)) { - // Not safe - return false; - } - - char filename[PATH_MAX]; - if (!dumper.GetMappingAbsolutePath(mapping, filename)) - return false; - - MemoryMappedFile mapped_file(filename, mapping.offset); - if (!mapped_file.data() || mapped_file.size() < SELFMAG) { - // mmap failed - return false; - } - - return ElfFileSoNameFromMappedFile(mapped_file.data(), soname, soname_size); -} - -} // namespace - - -void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping, - char* file_path, - size_t file_path_size, - char* file_name, - size_t file_name_size) { - my_strlcpy(file_path, mapping.name, file_path_size); - - // If an executable is mapped from a non-zero offset, this is likely because - // the executable was loaded directly from inside an archive file (e.g., an - // apk on Android). We try to find the name of the shared object (SONAME) by - // looking in the file for ELF sections. - bool mapped_from_archive = false; - if (mapping.exec && mapping.offset != 0) { - mapped_from_archive = - ElfFileSoName(*this, mapping, file_name, file_name_size); - } - - if (mapped_from_archive) { - // Some tools (e.g., stackwalk) extract the basename from the pathname. In - // this case, we append the file_name to the mapped archive path as follows: - // file_name := libname.so - // file_path := /path/to/ARCHIVE.APK/libname.so - if (my_strlen(file_path) + 1 + my_strlen(file_name) < file_path_size) { - my_strlcat(file_path, "/", file_path_size); - my_strlcat(file_path, file_name, file_path_size); - } - } else { - // Common case: - // file_path := /path/to/libname.so - // file_name := libname.so - const char* basename = my_strrchr(file_path, '/'); - basename = basename == NULL ? file_path : (basename + 1); - my_strlcpy(file_name, basename, file_name_size); - } -} - -bool LinuxDumper::ReadAuxv() { - char auxv_path[NAME_MAX]; - if (!BuildProcPath(auxv_path, pid_, "auxv")) { - return false; - } - - int fd = sys_open(auxv_path, O_RDONLY, 0); - if (fd < 0) { - return false; - } - - elf_aux_entry one_aux_entry; - bool res = false; - while (sys_read(fd, - &one_aux_entry, - sizeof(elf_aux_entry)) == sizeof(elf_aux_entry) && - one_aux_entry.a_type != AT_NULL) { - if (one_aux_entry.a_type <= AT_MAX) { - auxv_[one_aux_entry.a_type] = one_aux_entry.a_un.a_val; - res = true; - } - } - sys_close(fd); - return res; -} - -bool LinuxDumper::EnumerateMappings() { - char maps_path[NAME_MAX]; - if (!BuildProcPath(maps_path, pid_, "maps")) - return false; - - // linux_gate_loc is the beginning of the kernel's mapping of - // linux-gate.so in the process. It doesn't actually show up in the - // maps list as a filename, but it can be found using the AT_SYSINFO_EHDR - // aux vector entry, which gives the information necessary to special - // case its entry when creating the list of mappings. - // See http://www.trilithium.com/johan/2005/08/linux-gate/ for more - // information. - const void* linux_gate_loc = - reinterpret_cast(auxv_[AT_SYSINFO_EHDR]); - // Although the initial executable is usually the first mapping, it's not - // guaranteed (see http://crosbug.com/25355); therefore, try to use the - // actual entry point to find the mapping. - const void* entry_point_loc = reinterpret_cast(auxv_[AT_ENTRY]); - - const int fd = sys_open(maps_path, O_RDONLY, 0); - if (fd < 0) - return false; - LineReader* const line_reader = new(allocator_) LineReader(fd); - - const char* line; - unsigned line_len; - while (line_reader->GetNextLine(&line, &line_len)) { - uintptr_t start_addr, end_addr, offset; - - const char* i1 = my_read_hex_ptr(&start_addr, line); - if (*i1 == '-') { - const char* i2 = my_read_hex_ptr(&end_addr, i1 + 1); - if (*i2 == ' ') { - bool exec = (*(i2 + 3) == 'x'); - const char* i3 = my_read_hex_ptr(&offset, i2 + 6 /* skip ' rwxp ' */); - if (*i3 == ' ') { - const char* name = NULL; - // Only copy name if the name is a valid path name, or if - // it's the VDSO image. - if (((name = my_strchr(line, '/')) == NULL) && - linux_gate_loc && - reinterpret_cast(start_addr) == linux_gate_loc) { - name = kLinuxGateLibraryName; - offset = 0; - } - // Merge adjacent mappings with the same name into one module, - // assuming they're a single library mapped by the dynamic linker - if (name && !mappings_.empty()) { - MappingInfo* module = mappings_.back(); - if ((start_addr == module->start_addr + module->size) && - (my_strlen(name) == my_strlen(module->name)) && - (my_strncmp(name, module->name, my_strlen(name)) == 0)) { - module->size = end_addr - module->start_addr; - line_reader->PopLine(line_len); - continue; - } - } - // Also merge mappings that result from address ranges that the - // linker reserved but which a loaded library did not use. These - // appear as an anonymous private mapping with no access flags set - // and which directly follow an executable mapping. - if (!name && !mappings_.empty()) { - MappingInfo* module = mappings_.back(); - if ((start_addr == module->start_addr + module->size) && - module->exec && - module->name[0] == '/' && - offset == 0 && my_strncmp(i2, - kReservedFlags, - sizeof(kReservedFlags) - 1) == 0) { - module->size = end_addr - module->start_addr; - line_reader->PopLine(line_len); - continue; - } - } - MappingInfo* const module = new(allocator_) MappingInfo; - my_memset(module, 0, sizeof(MappingInfo)); - module->start_addr = start_addr; - module->size = end_addr - start_addr; - module->offset = offset; - module->exec = exec; - if (name != NULL) { - const unsigned l = my_strlen(name); - if (l < sizeof(module->name)) - my_memcpy(module->name, name, l); - } - // If this is the entry-point mapping, and it's not already the - // first one, then we need to make it be first. This is because - // the minidump format assumes the first module is the one that - // corresponds to the main executable (as codified in - // processor/minidump.cc:MinidumpModuleList::GetMainModule()). - if (entry_point_loc && - (entry_point_loc >= - reinterpret_cast(module->start_addr)) && - (entry_point_loc < - reinterpret_cast(module->start_addr+module->size)) && - !mappings_.empty()) { - // push the module onto the front of the list. - mappings_.resize(mappings_.size() + 1); - for (size_t idx = mappings_.size() - 1; idx > 0; idx--) - mappings_[idx] = mappings_[idx - 1]; - mappings_[0] = module; - } else { - mappings_.push_back(module); - } - } - } - } - line_reader->PopLine(line_len); - } - - sys_close(fd); - - return !mappings_.empty(); -} - -#if defined(__ANDROID__) - -bool LinuxDumper::GetLoadedElfHeader(uintptr_t start_addr, ElfW(Ehdr)* ehdr) { - CopyFromProcess(ehdr, pid_, - reinterpret_cast(start_addr), - sizeof(*ehdr)); - return my_memcmp(&ehdr->e_ident, ELFMAG, SELFMAG) == 0; -} - -void LinuxDumper::ParseLoadedElfProgramHeaders(ElfW(Ehdr)* ehdr, - uintptr_t start_addr, - uintptr_t* min_vaddr_ptr, - uintptr_t* dyn_vaddr_ptr, - size_t* dyn_count_ptr) { - uintptr_t phdr_addr = start_addr + ehdr->e_phoff; - - const uintptr_t max_addr = UINTPTR_MAX; - uintptr_t min_vaddr = max_addr; - uintptr_t dyn_vaddr = 0; - size_t dyn_count = 0; - - for (size_t i = 0; i < ehdr->e_phnum; ++i) { - ElfW(Phdr) phdr; - CopyFromProcess(&phdr, pid_, - reinterpret_cast(phdr_addr), - sizeof(phdr)); - if (phdr.p_type == PT_LOAD && phdr.p_vaddr < min_vaddr) { - min_vaddr = phdr.p_vaddr; - } - if (phdr.p_type == PT_DYNAMIC) { - dyn_vaddr = phdr.p_vaddr; - dyn_count = phdr.p_memsz / sizeof(ElfW(Dyn)); - } - phdr_addr += sizeof(phdr); - } - - *min_vaddr_ptr = min_vaddr; - *dyn_vaddr_ptr = dyn_vaddr; - *dyn_count_ptr = dyn_count; -} - -bool LinuxDumper::HasAndroidPackedRelocations(uintptr_t load_bias, - uintptr_t dyn_vaddr, - size_t dyn_count) { - uintptr_t dyn_addr = load_bias + dyn_vaddr; - for (size_t i = 0; i < dyn_count; ++i) { - ElfW(Dyn) dyn; - CopyFromProcess(&dyn, pid_, - reinterpret_cast(dyn_addr), - sizeof(dyn)); - if (dyn.d_tag == DT_ANDROID_REL || dyn.d_tag == DT_ANDROID_RELA) { - return true; - } - dyn_addr += sizeof(dyn); - } - return false; -} - -uintptr_t LinuxDumper::GetEffectiveLoadBias(ElfW(Ehdr)* ehdr, - uintptr_t start_addr) { - uintptr_t min_vaddr = 0; - uintptr_t dyn_vaddr = 0; - size_t dyn_count = 0; - ParseLoadedElfProgramHeaders(ehdr, start_addr, - &min_vaddr, &dyn_vaddr, &dyn_count); - // If |min_vaddr| is non-zero and we find Android packed relocation tags, - // return the effective load bias. - if (min_vaddr != 0) { - const uintptr_t load_bias = start_addr - min_vaddr; - if (HasAndroidPackedRelocations(load_bias, dyn_vaddr, dyn_count)) { - return load_bias; - } - } - // Either |min_vaddr| is zero, or it is non-zero but we did not find the - // expected Android packed relocations tags. - return start_addr; -} - -void LinuxDumper::LatePostprocessMappings() { - for (size_t i = 0; i < mappings_.size(); ++i) { - // Only consider exec mappings that indicate a file path was mapped, and - // where the ELF header indicates a mapped shared library. - MappingInfo* mapping = mappings_[i]; - if (!(mapping->exec && mapping->name[0] == '/')) { - continue; - } - ElfW(Ehdr) ehdr; - if (!GetLoadedElfHeader(mapping->start_addr, &ehdr)) { - continue; - } - if (ehdr.e_type == ET_DYN) { - // Compute the effective load bias for this mapped library, and update - // the mapping to hold that rather than |start_addr|, at the same time - // adjusting |size| to account for the change in |start_addr|. Where - // the library does not contain Android packed relocations, - // GetEffectiveLoadBias() returns |start_addr| and the mapping entry - // is not changed. - const uintptr_t load_bias = GetEffectiveLoadBias(&ehdr, - mapping->start_addr); - mapping->size += mapping->start_addr - load_bias; - mapping->start_addr = load_bias; - } - } -} - -#endif // __ANDROID__ - -// Get information about the stack, given the stack pointer. We don't try to -// walk the stack since we might not have all the information needed to do -// unwind. So we just grab, up to, 32k of stack. -bool LinuxDumper::GetStackInfo(const void** stack, size_t* stack_len, - uintptr_t int_stack_pointer) { - // Move the stack pointer to the bottom of the page that it's in. - const uintptr_t page_size = getpagesize(); - - uint8_t* const stack_pointer = - reinterpret_cast(int_stack_pointer & ~(page_size - 1)); - - // The number of bytes of stack which we try to capture. - static const ptrdiff_t kStackToCapture = 32 * 1024; - - const MappingInfo* mapping = FindMapping(stack_pointer); - if (!mapping) - return false; - const ptrdiff_t offset = stack_pointer - - reinterpret_cast(mapping->start_addr); - const ptrdiff_t distance_to_end = - static_cast(mapping->size) - offset; - *stack_len = distance_to_end > kStackToCapture ? - kStackToCapture : distance_to_end; - *stack = stack_pointer; - return true; -} - -// Find the mapping which the given memory address falls in. -const MappingInfo* LinuxDumper::FindMapping(const void* address) const { - const uintptr_t addr = (uintptr_t) address; - - for (size_t i = 0; i < mappings_.size(); ++i) { - const uintptr_t start = static_cast(mappings_[i]->start_addr); - if (addr >= start && addr - start < mappings_[i]->size) - return mappings_[i]; - } - - return NULL; -} - -bool LinuxDumper::HandleDeletedFileInMapping(char* path) const { - static const size_t kDeletedSuffixLen = sizeof(kDeletedSuffix) - 1; - - // Check for ' (deleted)' in |path|. - // |path| has to be at least as long as "/x (deleted)". - const size_t path_len = my_strlen(path); - if (path_len < kDeletedSuffixLen + 2) - return false; - if (my_strncmp(path + path_len - kDeletedSuffixLen, kDeletedSuffix, - kDeletedSuffixLen) != 0) { - return false; - } - - // Check |path| against the /proc/pid/exe 'symlink'. - char exe_link[NAME_MAX]; - if (!BuildProcPath(exe_link, pid_, "exe")) - return false; - MappingInfo new_mapping = {0}; - if (!SafeReadLink(exe_link, new_mapping.name)) - return false; - char new_path[PATH_MAX]; - if (!GetMappingAbsolutePath(new_mapping, new_path)) - return false; - if (my_strcmp(path, new_path) != 0) - return false; - - // Check to see if someone actually named their executable 'foo (deleted)'. - struct kernel_stat exe_stat; - struct kernel_stat new_path_stat; - if (sys_stat(exe_link, &exe_stat) == 0 && - sys_stat(new_path, &new_path_stat) == 0 && - exe_stat.st_dev == new_path_stat.st_dev && - exe_stat.st_ino == new_path_stat.st_ino) { - return false; - } - - my_memcpy(path, exe_link, NAME_MAX); - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h deleted file mode 100644 index c3c799267..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_dumper.h: Define the google_breakpad::LinuxDumper class, which -// is a base class for extracting information of a crashed process. It -// was originally a complete implementation using the ptrace API, but -// has been refactored to allow derived implementations supporting both -// ptrace and core dump. A portion of the original implementation is now -// in google_breakpad::LinuxPtraceDumper (see linux_ptrace_dumper.h for -// details). - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ - -#include -#if defined(__ANDROID__) -#include -#endif -#include -#include -#include -#include - -#include "client/linux/dump_writer_common/mapping_info.h" -#include "client/linux/dump_writer_common/thread_info.h" -#include "common/linux/file_id.h" -#include "common/memory.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Typedef for our parsing of the auxv variables in /proc/pid/auxv. -#if defined(__i386) || defined(__ARM_EABI__) || \ - (defined(__mips__) && _MIPS_SIM == _ABIO32) -typedef Elf32_auxv_t elf_aux_entry; -#elif defined(__x86_64) || defined(__aarch64__) || \ - (defined(__mips__) && _MIPS_SIM != _ABIO32) -typedef Elf64_auxv_t elf_aux_entry; -#endif - -typedef __typeof__(((elf_aux_entry*) 0)->a_un.a_val) elf_aux_val_t; - -// When we find the VDSO mapping in the process's address space, this -// is the name we use for it when writing it to the minidump. -// This should always be less than NAME_MAX! -const char kLinuxGateLibraryName[] = "linux-gate.so"; - -class LinuxDumper { - public: - // The |root_prefix| is prepended to mapping paths before opening them, which - // is useful if the crash originates from a chroot. - explicit LinuxDumper(pid_t pid, const char* root_prefix = ""); - - virtual ~LinuxDumper(); - - // Parse the data for |threads| and |mappings|. - virtual bool Init(); - - // Take any actions that could not be taken in Init(). LateInit() is - // called after all other caller's initialization is complete, and in - // particular after it has called ThreadsSuspend(), so that ptrace is - // available. - virtual bool LateInit(); - - // Return true if the dumper performs a post-mortem dump. - virtual bool IsPostMortem() const = 0; - - // Suspend/resume all threads in the given process. - virtual bool ThreadsSuspend() = 0; - virtual bool ThreadsResume() = 0; - - // Read information about the |index|-th thread of |threads_|. - // Returns true on success. One must have called |ThreadsSuspend| first. - virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info) = 0; - - // These are only valid after a call to |Init|. - const wasteful_vector &threads() { return threads_; } - const wasteful_vector &mappings() { return mappings_; } - const MappingInfo* FindMapping(const void* address) const; - const wasteful_vector& auxv() { return auxv_; } - - // Find a block of memory to take as the stack given the top of stack pointer. - // stack: (output) the lowest address in the memory area - // stack_len: (output) the length of the memory area - // stack_top: the current top of the stack - bool GetStackInfo(const void** stack, size_t* stack_len, uintptr_t stack_top); - - PageAllocator* allocator() { return &allocator_; } - - // Copy content of |length| bytes from a given process |child|, - // starting from |src|, into |dest|. Returns true on success. - virtual bool CopyFromProcess(void* dest, pid_t child, const void* src, - size_t length) = 0; - - // Builds a proc path for a certain pid for a node (/proc//). - // |path| is a character array of at least NAME_MAX bytes to return the - // result.|node| is the final node without any slashes. Returns true on - // success. - virtual bool BuildProcPath(char* path, pid_t pid, const char* node) const = 0; - - // Generate a File ID from the .text section of a mapped entry. - // If not a member, mapping_id is ignored. This method can also manipulate the - // |mapping|.name to truncate "(deleted)" from the file name if necessary. - bool ElfFileIdentifierForMapping(const MappingInfo& mapping, - bool member, - unsigned int mapping_id, - wasteful_vector& identifier); - - uintptr_t crash_address() const { return crash_address_; } - void set_crash_address(uintptr_t crash_address) { - crash_address_ = crash_address; - } - - int crash_signal() const { return crash_signal_; } - void set_crash_signal(int crash_signal) { crash_signal_ = crash_signal; } - - pid_t crash_thread() const { return crash_thread_; } - void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; } - - // Concatenates the |root_prefix_| and |mapping| path. Writes into |path| and - // returns true unless the string is too long. - bool GetMappingAbsolutePath(const MappingInfo& mapping, - char path[PATH_MAX]) const; - - // Extracts the effective path and file name of from |mapping|. In most cases - // the effective name/path are just the mapping's path and basename. In some - // other cases, however, a library can be mapped from an archive (e.g., when - // loading .so libs from an apk on Android) and this method is able to - // reconstruct the original file name. - void GetMappingEffectiveNameAndPath(const MappingInfo& mapping, - char* file_path, - size_t file_path_size, - char* file_name, - size_t file_name_size); - - protected: - bool ReadAuxv(); - - virtual bool EnumerateMappings(); - - virtual bool EnumerateThreads() = 0; - - // For the case where a running program has been deleted, it'll show up in - // /proc/pid/maps as "/path/to/program (deleted)". If this is the case, then - // see if '/path/to/program (deleted)' matches /proc/pid/exe and return - // /proc/pid/exe in |path| so ELF identifier generation works correctly. This - // also checks to see if '/path/to/program (deleted)' exists, so it does not - // get fooled by a poorly named binary. - // For programs that don't end with ' (deleted)', this is a no-op. - // This assumes |path| is a buffer with length NAME_MAX. - // Returns true if |path| is modified. - bool HandleDeletedFileInMapping(char* path) const; - - // ID of the crashed process. - const pid_t pid_; - - // Path of the root directory to which mapping paths are relative. - const char* const root_prefix_; - - // Virtual address at which the process crashed. - uintptr_t crash_address_; - - // Signal that terminated the crashed process. - int crash_signal_; - - // ID of the crashed thread. - pid_t crash_thread_; - - mutable PageAllocator allocator_; - - // IDs of all the threads. - wasteful_vector threads_; - - // Info from /proc//maps. - wasteful_vector mappings_; - - // Info from /proc//auxv - wasteful_vector auxv_; - -#if defined(__ANDROID__) - private: - // Android M and later support packed ELF relocations in shared libraries. - // Packing relocations changes the vaddr of the LOAD segments, such that - // the effective load bias is no longer the same as the start address of - // the memory mapping containing the executable parts of the library. The - // packing is applied to the stripped library run on the target, but not to - // any other library, and in particular not to the library used to generate - // breakpad symbols. As a result, we need to adjust the |start_addr| for - // any mapping that results from a shared library that contains Android - // packed relocations, so that it properly represents the effective library - // load bias. The following functions support this adjustment. - - // Check that a given mapping at |start_addr| is for an ELF shared library. - // If it is, place the ELF header in |ehdr| and return true. - // The first LOAD segment in an ELF shared library has offset zero, so the - // ELF file header is at the start of this map entry, and in already mapped - // memory. - bool GetLoadedElfHeader(uintptr_t start_addr, ElfW(Ehdr)* ehdr); - - // For the ELF file mapped at |start_addr|, iterate ELF program headers to - // find the min vaddr of all program header LOAD segments, the vaddr for - // the DYNAMIC segment, and a count of DYNAMIC entries. Return values in - // |min_vaddr_ptr|, |dyn_vaddr_ptr|, and |dyn_count_ptr|. - // The program header table is also in already mapped memory. - void ParseLoadedElfProgramHeaders(ElfW(Ehdr)* ehdr, - uintptr_t start_addr, - uintptr_t* min_vaddr_ptr, - uintptr_t* dyn_vaddr_ptr, - size_t* dyn_count_ptr); - - // Search the DYNAMIC tags for the ELF file with the given |load_bias|, and - // return true if the tags indicate that the file contains Android packed - // relocations. Dynamic tags are found at |dyn_vaddr| past the |load_bias|. - bool HasAndroidPackedRelocations(uintptr_t load_bias, - uintptr_t dyn_vaddr, - size_t dyn_count); - - // If the ELF file mapped at |start_addr| contained Android packed - // relocations, return the load bias that the system linker (or Chromium - // crazy linker) will have used. If the file did not contain Android - // packed relocations, returns |start_addr|, indicating that no adjustment - // is necessary. - // The effective load bias is |start_addr| adjusted downwards by the - // min vaddr in the library LOAD segments. - uintptr_t GetEffectiveLoadBias(ElfW(Ehdr)* ehdr, uintptr_t start_addr); - - // Called from LateInit(). Iterates |mappings_| and rewrites the |start_addr| - // field of any that represent ELF shared libraries with Android packed - // relocations, so that |start_addr| is the load bias that the system linker - // (or Chromium crazy linker) used. This value matches the addresses produced - // when the non-relocation-packed library is used for breakpad symbol - // generation. - void LatePostprocessMappings(); -#endif // __ANDROID__ -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc deleted file mode 100644 index 4ccb7201f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Helper program for the linux_dumper class, which creates a bunch of -// threads. The first word of each thread's stack is set to the thread -// id. - -#include -#include -#include -#include -#include -#include - -#include "common/scoped_ptr.h" -#include "third_party/lss/linux_syscall_support.h" - -#if defined(__ARM_EABI__) -#define TID_PTR_REGISTER "r3" -#elif defined(__aarch64__) -#define TID_PTR_REGISTER "x3" -#elif defined(__i386) -#define TID_PTR_REGISTER "ecx" -#elif defined(__x86_64) -#define TID_PTR_REGISTER "rcx" -#elif defined(__mips__) -#define TID_PTR_REGISTER "$1" -#else -#error This test has not been ported to this platform. -#endif - -void *thread_function(void *data) { - int pipefd = *static_cast(data); - volatile pid_t thread_id = syscall(__NR_gettid); - // Signal parent that a thread has started. - uint8_t byte = 1; - if (write(pipefd, &byte, sizeof(byte)) != sizeof(byte)) { - perror("ERROR: parent notification failed"); - return NULL; - } - register volatile pid_t *thread_id_ptr asm(TID_PTR_REGISTER) = &thread_id; - while (true) - asm volatile ("" : : "r" (thread_id_ptr)); - return NULL; -} - -int main(int argc, char *argv[]) { - if (argc < 3) { - fprintf(stderr, - "usage: linux_dumper_unittest_helper <# of threads>\n"); - return 1; - } - int pipefd = atoi(argv[1]); - int num_threads = atoi(argv[2]); - if (num_threads < 1) { - fprintf(stderr, "ERROR: number of threads is 0"); - return 1; - } - google_breakpad::scoped_array threads(new pthread_t[num_threads]); - pthread_attr_t thread_attributes; - pthread_attr_init(&thread_attributes); - pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_DETACHED); - for (int i = 1; i < num_threads; i++) { - pthread_create(&threads[i], &thread_attributes, &thread_function, &pipefd); - } - thread_function(&pipefd); - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.cc deleted file mode 100644 index c35e0e958..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_ptrace_dumper.cc: Implement google_breakpad::LinuxPtraceDumper. -// See linux_ptrace_dumper.h for detals. -// This class was originally splitted from google_breakpad::LinuxDumper. - -// This code deals with the mechanics of getting information about a crashed -// process. Since this code may run in a compromised address space, the same -// rules apply as detailed at the top of minidump_writer.h: no libc calls and -// use the alternative allocator. - -#include "client/linux/minidump_writer/linux_ptrace_dumper.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__i386) -#include -#endif - -#include "client/linux/minidump_writer/directory_reader.h" -#include "client/linux/minidump_writer/line_reader.h" -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" - -// Suspends a thread by attaching to it. -static bool SuspendThread(pid_t pid) { - // This may fail if the thread has just died or debugged. - errno = 0; - if (sys_ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 && - errno != 0) { - return false; - } - while (sys_waitpid(pid, NULL, __WALL) < 0) { - if (errno != EINTR) { - sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); - return false; - } - } -#if defined(__i386) || defined(__x86_64) - // On x86, the stack pointer is NULL or -1, when executing trusted code in - // the seccomp sandbox. Not only does this cause difficulties down the line - // when trying to dump the thread's stack, it also results in the minidumps - // containing information about the trusted threads. This information is - // generally completely meaningless and just pollutes the minidumps. - // We thus test the stack pointer and exclude any threads that are part of - // the seccomp sandbox's trusted code. - user_regs_struct regs; - if (sys_ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1 || -#if defined(__i386) - !regs.esp -#elif defined(__x86_64) - !regs.rsp -#endif - ) { - sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); - return false; - } -#endif - return true; -} - -// Resumes a thread by detaching from it. -static bool ResumeThread(pid_t pid) { - return sys_ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0; -} - -namespace google_breakpad { - -LinuxPtraceDumper::LinuxPtraceDumper(pid_t pid) - : LinuxDumper(pid), - threads_suspended_(false) { -} - -bool LinuxPtraceDumper::BuildProcPath(char* path, pid_t pid, - const char* node) const { - if (!path || !node || pid <= 0) - return false; - - size_t node_len = my_strlen(node); - if (node_len == 0) - return false; - - const unsigned pid_len = my_uint_len(pid); - const size_t total_length = 6 + pid_len + 1 + node_len; - if (total_length >= NAME_MAX) - return false; - - my_memcpy(path, "/proc/", 6); - my_uitos(path + 6, pid, pid_len); - path[6 + pid_len] = '/'; - my_memcpy(path + 6 + pid_len + 1, node, node_len); - path[total_length] = '\0'; - return true; -} - -bool LinuxPtraceDumper::CopyFromProcess(void* dest, pid_t child, - const void* src, size_t length) { - unsigned long tmp = 55; - size_t done = 0; - static const size_t word_size = sizeof(tmp); - uint8_t* const local = (uint8_t*) dest; - uint8_t* const remote = (uint8_t*) src; - - while (done < length) { - const size_t l = (length - done > word_size) ? word_size : (length - done); - if (sys_ptrace(PTRACE_PEEKDATA, child, remote + done, &tmp) == -1) { - tmp = 0; - } - my_memcpy(local + done, &tmp, l); - done += l; - } - return true; -} - -// Read thread info from /proc/$pid/status. -// Fill out the |tgid|, |ppid| and |pid| members of |info|. If unavailable, -// these members are set to -1. Returns true iff all three members are -// available. -bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) { - if (index >= threads_.size()) - return false; - - pid_t tid = threads_[index]; - - assert(info != NULL); - char status_path[NAME_MAX]; - if (!BuildProcPath(status_path, tid, "status")) - return false; - - const int fd = sys_open(status_path, O_RDONLY, 0); - if (fd < 0) - return false; - - LineReader* const line_reader = new(allocator_) LineReader(fd); - const char* line; - unsigned line_len; - - info->ppid = info->tgid = -1; - - while (line_reader->GetNextLine(&line, &line_len)) { - if (my_strncmp("Tgid:\t", line, 6) == 0) { - my_strtoui(&info->tgid, line + 6); - } else if (my_strncmp("PPid:\t", line, 6) == 0) { - my_strtoui(&info->ppid, line + 6); - } - - line_reader->PopLine(line_len); - } - sys_close(fd); - - if (info->ppid == -1 || info->tgid == -1) - return false; - -#ifdef PTRACE_GETREGSET - struct iovec io; - info->GetGeneralPurposeRegisters(&io.iov_base, &io.iov_len); - if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, (void*)&io) == -1) { - return false; - } - - info->GetFloatingPointRegisters(&io.iov_base, &io.iov_len); - if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) == -1) { - return false; - } -#else // PTRACE_GETREGSET - void* gp_addr; - info->GetGeneralPurposeRegisters(&gp_addr, NULL); - if (sys_ptrace(PTRACE_GETREGS, tid, NULL, gp_addr) == -1) { - return false; - } - -#if !(defined(__ANDROID__) && defined(__ARM_EABI__)) - // When running an arm build on an arm64 device, attempting to get the - // floating point registers fails. On Android, the floating point registers - // aren't written to the cpu context anyway, so just don't get them here. - // See http://crbug.com/508324 - void* fp_addr; - info->GetFloatingPointRegisters(&fp_addr, NULL); - if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) { - return false; - } -#endif -#endif // PTRACE_GETREGSET - -#if defined(__i386) -#if !defined(bit_FXSAVE) // e.g. Clang -#define bit_FXSAVE bit_FXSR -#endif - // Detect if the CPU supports the FXSAVE/FXRSTOR instructions - int eax, ebx, ecx, edx; - __cpuid(1, eax, ebx, ecx, edx); - if (edx & bit_FXSAVE) { - if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1) { - return false; - } - } else { - memset(&info->fpxregs, 0, sizeof(info->fpxregs)); - } -#endif // defined(__i386) - -#if defined(__i386) || defined(__x86_64) - for (unsigned i = 0; i < ThreadInfo::kNumDebugRegisters; ++i) { - if (sys_ptrace( - PTRACE_PEEKUSER, tid, - reinterpret_cast (offsetof(struct user, - u_debugreg[0]) + i * - sizeof(debugreg_t)), - &info->dregs[i]) == -1) { - return false; - } - } -#endif - -#if defined(__mips__) - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE), &info->mcontext.hi1); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE + 1), &info->mcontext.lo1); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE + 2), &info->mcontext.hi2); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE + 3), &info->mcontext.lo2); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE + 4), &info->mcontext.hi3); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_BASE + 5), &info->mcontext.lo3); - sys_ptrace(PTRACE_PEEKUSER, tid, - reinterpret_cast(DSP_CONTROL), &info->mcontext.dsp); -#endif - - const uint8_t* stack_pointer; -#if defined(__i386) - my_memcpy(&stack_pointer, &info->regs.esp, sizeof(info->regs.esp)); -#elif defined(__x86_64) - my_memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp)); -#elif defined(__ARM_EABI__) - my_memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp)); -#elif defined(__aarch64__) - my_memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp)); -#elif defined(__mips__) - stack_pointer = - reinterpret_cast(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]); -#else -#error "This code hasn't been ported to your platform yet." -#endif - info->stack_pointer = reinterpret_cast(stack_pointer); - - return true; -} - -bool LinuxPtraceDumper::IsPostMortem() const { - return false; -} - -bool LinuxPtraceDumper::ThreadsSuspend() { - if (threads_suspended_) - return true; - for (size_t i = 0; i < threads_.size(); ++i) { - if (!SuspendThread(threads_[i])) { - // If the thread either disappeared before we could attach to it, or if - // it was part of the seccomp sandbox's trusted code, it is OK to - // silently drop it from the minidump. - if (i < threads_.size() - 1) { - my_memmove(&threads_[i], &threads_[i + 1], - (threads_.size() - i - 1) * sizeof(threads_[i])); - } - threads_.resize(threads_.size() - 1); - --i; - } - } - threads_suspended_ = true; - return threads_.size() > 0; -} - -bool LinuxPtraceDumper::ThreadsResume() { - if (!threads_suspended_) - return false; - bool good = true; - for (size_t i = 0; i < threads_.size(); ++i) - good &= ResumeThread(threads_[i]); - threads_suspended_ = false; - return good; -} - -// Parse /proc/$pid/task to list all the threads of the process identified by -// pid. -bool LinuxPtraceDumper::EnumerateThreads() { - char task_path[NAME_MAX]; - if (!BuildProcPath(task_path, pid_, "task")) - return false; - - const int fd = sys_open(task_path, O_RDONLY | O_DIRECTORY, 0); - if (fd < 0) - return false; - DirectoryReader* dir_reader = new(allocator_) DirectoryReader(fd); - - // The directory may contain duplicate entries which we filter by assuming - // that they are consecutive. - int last_tid = -1; - const char* dent_name; - while (dir_reader->GetNextEntry(&dent_name)) { - if (my_strcmp(dent_name, ".") && - my_strcmp(dent_name, "..")) { - int tid = 0; - if (my_strtoui(&tid, dent_name) && - last_tid != tid) { - last_tid = tid; - threads_.push_back(tid); - } - } - dir_reader->PopEntry(); - } - - sys_close(fd); - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.h deleted file mode 100644 index 2ce834b0f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_ptrace_dumper.h: Define the google_breakpad::LinuxPtraceDumper -// class, which is derived from google_breakpad::LinuxDumper to extract -// information from a crashed process via ptrace. -// This class was originally splitted from google_breakpad::LinuxDumper. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_PTRACE_DUMPER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_PTRACE_DUMPER_H_ - -#include "client/linux/minidump_writer/linux_dumper.h" - -namespace google_breakpad { - -class LinuxPtraceDumper : public LinuxDumper { - public: - // Constructs a dumper for extracting information of a given process - // with a process ID of |pid|. - explicit LinuxPtraceDumper(pid_t pid); - - // Implements LinuxDumper::BuildProcPath(). - // Builds a proc path for a certain pid for a node (/proc//). - // |path| is a character array of at least NAME_MAX bytes to return the - // result. |node| is the final node without any slashes. Returns true on - // success. - virtual bool BuildProcPath(char* path, pid_t pid, const char* node) const; - - // Implements LinuxDumper::CopyFromProcess(). - // Copies content of |length| bytes from a given process |child|, - // starting from |src|, into |dest|. This method uses ptrace to extract - // the content from the target process. Always returns true. - virtual bool CopyFromProcess(void* dest, pid_t child, const void* src, - size_t length); - - // Implements LinuxDumper::GetThreadInfoByIndex(). - // Reads information about the |index|-th thread of |threads_|. - // Returns true on success. One must have called |ThreadsSuspend| first. - virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info); - - // Implements LinuxDumper::IsPostMortem(). - // Always returns false to indicate this dumper performs a dump of - // a crashed process via ptrace. - virtual bool IsPostMortem() const; - - // Implements LinuxDumper::ThreadsSuspend(). - // Suspends all threads in the given process. Returns true on success. - virtual bool ThreadsSuspend(); - - // Implements LinuxDumper::ThreadsResume(). - // Resumes all threads in the given process. Returns true on success. - virtual bool ThreadsResume(); - - protected: - // Implements LinuxDumper::EnumerateThreads(). - // Enumerates all threads of the given process into |threads_|. - virtual bool EnumerateThreads(); - - private: - // Set to true if all threads of the crashed process are suspended. - bool threads_suspended_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_HANDLER_LINUX_PTRACE_DUMPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc deleted file mode 100644 index be533e157..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc +++ /dev/null @@ -1,470 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// linux_ptrace_dumper_unittest.cc: -// Unit tests for google_breakpad::LinuxPtraceDumper. -// -// This file was renamed from linux_dumper_unittest.cc and modified due -// to LinuxDumper being splitted into two classes. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/minidump_writer/linux_ptrace_dumper.h" -#include "client/linux/minidump_writer/minidump_writer_unittest_utils.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/file_id.h" -#include "common/linux/ignore_ret.h" -#include "common/linux/safe_readlink.h" -#include "common/memory.h" -#include "common/using_std_string.h" - -#ifndef PR_SET_PTRACER -#define PR_SET_PTRACER 0x59616d61 -#endif - -using namespace google_breakpad; - -namespace { - -typedef wasteful_vector id_vector; -typedef testing::Test LinuxPtraceDumperTest; - -/* Fixture for running tests in a child process. */ -class LinuxPtraceDumperChildTest : public testing::Test { - protected: - virtual void SetUp() { - child_pid_ = fork(); -#ifndef __ANDROID__ - prctl(PR_SET_PTRACER, child_pid_); -#endif - } - - /* Gtest is calling TestBody from this class, which sets up a child - * process in which the RealTestBody virtual member is called. - * As such, TestBody is not supposed to be overridden in derived classes. - */ - virtual void TestBody() /* final */ { - if (child_pid_ == 0) { - // child process - RealTestBody(); - exit(HasFatalFailure() ? kFatalFailure : - (HasNonfatalFailure() ? kNonFatalFailure : 0)); - } - - ASSERT_TRUE(child_pid_ > 0); - int status; - waitpid(child_pid_, &status, 0); - if (WEXITSTATUS(status) == kFatalFailure) { - GTEST_FATAL_FAILURE_("Test failed in child process"); - } else if (WEXITSTATUS(status) == kNonFatalFailure) { - GTEST_NONFATAL_FAILURE_("Test failed in child process"); - } - } - - /* Gtest defines TestBody functions through its macros, but classes - * derived from this one need to define RealTestBody instead. - * This is achieved by defining a TestBody macro further below. - */ - virtual void RealTestBody() = 0; - - id_vector make_vector() { - return id_vector(&allocator, kDefaultBuildIdSize); - } - - private: - static const int kFatalFailure = 1; - static const int kNonFatalFailure = 2; - - pid_t child_pid_; - PageAllocator allocator; -}; - -} // namespace - -/* Replace TestBody declarations within TEST*() with RealTestBody - * declarations */ -#define TestBody RealTestBody - -TEST_F(LinuxPtraceDumperChildTest, Setup) { - LinuxPtraceDumper dumper(getppid()); -} - -TEST_F(LinuxPtraceDumperChildTest, FindMappings) { - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - - ASSERT_TRUE(dumper.FindMapping(reinterpret_cast(getpid))); - ASSERT_TRUE(dumper.FindMapping(reinterpret_cast(printf))); - ASSERT_FALSE(dumper.FindMapping(NULL)); -} - -TEST_F(LinuxPtraceDumperChildTest, ThreadList) { - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - - ASSERT_GE(dumper.threads().size(), (size_t)1); - bool found = false; - for (size_t i = 0; i < dumper.threads().size(); ++i) { - if (dumper.threads()[i] == getppid()) { - ASSERT_FALSE(found); - found = true; - } - } - ASSERT_TRUE(found); -} - -// Helper stack class to close a file descriptor and unmap -// a mmap'ed mapping. -class StackHelper { - public: - StackHelper() - : fd_(-1), mapping_(NULL), size_(0) {} - ~StackHelper() { - if (size_) - munmap(mapping_, size_); - if (fd_ >= 0) - close(fd_); - } - void Init(int fd, char* mapping, size_t size) { - fd_ = fd; - mapping_ = mapping; - size_ = size; - } - - char* mapping() const { return mapping_; } - size_t size() const { return size_; } - - private: - int fd_; - char* mapping_; - size_t size_; -}; - -class LinuxPtraceDumperMappingsTest : public LinuxPtraceDumperChildTest { - protected: - virtual void SetUp(); - - string helper_path_; - size_t page_size_; - StackHelper helper_; -}; - -void LinuxPtraceDumperMappingsTest::SetUp() { - helper_path_ = GetHelperBinary(); - if (helper_path_.empty()) { - FAIL() << "Couldn't find helper binary"; - exit(1); - } - - // mmap two segments out of the helper binary, one - // enclosed in the other, but with different protections. - page_size_ = sysconf(_SC_PAGESIZE); - const size_t kMappingSize = 3 * page_size_; - int fd = open(helper_path_.c_str(), O_RDONLY); - ASSERT_NE(-1, fd) << "Failed to open file: " << helper_path_ - << ", Error: " << strerror(errno); - char* mapping = - reinterpret_cast(mmap(NULL, - kMappingSize, - PROT_READ, - MAP_SHARED, - fd, - 0)); - ASSERT_TRUE(mapping); - - // Ensure that things get cleaned up. - helper_.Init(fd, mapping, kMappingSize); - - // Carve a page out of the first mapping with different permissions. - char* inside_mapping = reinterpret_cast( - mmap(mapping + 2 * page_size_, - page_size_, - PROT_NONE, - MAP_SHARED | MAP_FIXED, - fd, - // Map a different offset just to - // better test real-world conditions. - page_size_)); - ASSERT_TRUE(inside_mapping); - - LinuxPtraceDumperChildTest::SetUp(); -} - -TEST_F(LinuxPtraceDumperMappingsTest, MergedMappings) { - // Now check that LinuxPtraceDumper interpreted the mappings properly. - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - int mapping_count = 0; - for (unsigned i = 0; i < dumper.mappings().size(); ++i) { - const MappingInfo& mapping = *dumper.mappings()[i]; - if (strcmp(mapping.name, this->helper_path_.c_str()) == 0) { - // This mapping should encompass the entire original mapped - // range. - EXPECT_EQ(reinterpret_cast(this->helper_.mapping()), - mapping.start_addr); - EXPECT_EQ(this->helper_.size(), mapping.size); - EXPECT_EQ(0U, mapping.offset); - mapping_count++; - } - } - EXPECT_EQ(1, mapping_count); -} - -TEST_F(LinuxPtraceDumperChildTest, BuildProcPath) { - const pid_t pid = getppid(); - LinuxPtraceDumper dumper(pid); - - char maps_path[NAME_MAX] = ""; - char maps_path_expected[NAME_MAX]; - snprintf(maps_path_expected, sizeof(maps_path_expected), - "/proc/%d/maps", pid); - EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps")); - EXPECT_STREQ(maps_path_expected, maps_path); - - EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, 0, "maps")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, "")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL)); - - char long_node[NAME_MAX]; - size_t long_node_len = NAME_MAX - strlen("/proc/123") - 1; - memset(long_node, 'a', long_node_len); - long_node[long_node_len] = '\0'; - EXPECT_FALSE(dumper.BuildProcPath(maps_path, 123, long_node)); -} - -#if !defined(__ARM_EABI__) && !defined(__mips__) -// Ensure that the linux-gate VDSO is included in the mapping list. -TEST_F(LinuxPtraceDumperChildTest, MappingsIncludeLinuxGate) { - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - - void* linux_gate_loc = - reinterpret_cast(dumper.auxv()[AT_SYSINFO_EHDR]); - ASSERT_TRUE(linux_gate_loc); - bool found_linux_gate = false; - - const wasteful_vector mappings = dumper.mappings(); - const MappingInfo* mapping; - for (unsigned i = 0; i < mappings.size(); ++i) { - mapping = mappings[i]; - if (!strcmp(mapping->name, kLinuxGateLibraryName)) { - found_linux_gate = true; - break; - } - } - EXPECT_TRUE(found_linux_gate); - EXPECT_EQ(linux_gate_loc, reinterpret_cast(mapping->start_addr)); - EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG)); -} - -// Ensure that the linux-gate VDSO can generate a non-zeroed File ID. -TEST_F(LinuxPtraceDumperChildTest, LinuxGateMappingID) { - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - - bool found_linux_gate = false; - const wasteful_vector mappings = dumper.mappings(); - unsigned index = 0; - for (unsigned i = 0; i < mappings.size(); ++i) { - if (!strcmp(mappings[i]->name, kLinuxGateLibraryName)) { - found_linux_gate = true; - index = i; - break; - } - } - ASSERT_TRUE(found_linux_gate); - - // Need to suspend the child so ptrace actually works. - ASSERT_TRUE(dumper.ThreadsSuspend()); - id_vector identifier(make_vector()); - ASSERT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[index], - true, - index, - identifier)); - - id_vector empty_identifier(make_vector()); - empty_identifier.resize(kDefaultBuildIdSize, 0); - EXPECT_NE(empty_identifier, identifier); - EXPECT_TRUE(dumper.ThreadsResume()); -} -#endif - -TEST_F(LinuxPtraceDumperChildTest, FileIDsMatch) { - // Calculate the File ID of our binary using both - // FileID::ElfFileIdentifier and LinuxDumper::ElfFileIdentifierForMapping - // and ensure that we get the same result from both. - char exe_name[PATH_MAX]; - ASSERT_TRUE(SafeReadLink("/proc/self/exe", exe_name)); - - LinuxPtraceDumper dumper(getppid()); - ASSERT_TRUE(dumper.Init()); - const wasteful_vector mappings = dumper.mappings(); - bool found_exe = false; - unsigned i; - for (i = 0; i < mappings.size(); ++i) { - const MappingInfo* mapping = mappings[i]; - if (!strcmp(mapping->name, exe_name)) { - found_exe = true; - break; - } - } - ASSERT_TRUE(found_exe); - - id_vector identifier1(make_vector()); - id_vector identifier2(make_vector()); - EXPECT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[i], true, i, - identifier1)); - FileID fileid(exe_name); - EXPECT_TRUE(fileid.ElfFileIdentifier(identifier2)); - - string identifier_string1 = - FileID::ConvertIdentifierToUUIDString(identifier1); - string identifier_string2 = - FileID::ConvertIdentifierToUUIDString(identifier2); - EXPECT_EQ(identifier_string1, identifier_string2); -} - -/* Get back to normal behavior of TEST*() macros wrt TestBody. */ -#undef TestBody - -TEST(LinuxPtraceDumperTest, VerifyStackReadWithMultipleThreads) { - static const int kNumberOfThreadsInHelperProgram = 5; - char kNumberOfThreadsArgument[2]; - sprintf(kNumberOfThreadsArgument, "%d", kNumberOfThreadsInHelperProgram); - - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - pid_t child_pid = fork(); - if (child_pid == 0) { - // In child process. - close(fds[0]); - - string helper_path(GetHelperBinary()); - if (helper_path.empty()) { - FAIL() << "Couldn't find helper binary"; - exit(1); - } - - // Pass the pipe fd and the number of threads as arguments. - char pipe_fd_string[8]; - sprintf(pipe_fd_string, "%d", fds[1]); - execl(helper_path.c_str(), - "linux_dumper_unittest_helper", - pipe_fd_string, - kNumberOfThreadsArgument, - NULL); - // Kill if we get here. - printf("Errno from exec: %d", errno); - FAIL() << "Exec of " << helper_path << " failed: " << strerror(errno); - exit(0); - } - close(fds[1]); - - // Wait for all child threads to indicate that they have started - for (int threads = 0; threads < kNumberOfThreadsInHelperProgram; threads++) { - struct pollfd pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = fds[0]; - pfd.events = POLLIN | POLLERR; - - const int r = HANDLE_EINTR(poll(&pfd, 1, 1000)); - ASSERT_EQ(1, r); - ASSERT_TRUE(pfd.revents & POLLIN); - uint8_t junk; - ASSERT_EQ(read(fds[0], &junk, sizeof(junk)), - static_cast(sizeof(junk))); - } - close(fds[0]); - - // There is a race here because we may stop a child thread before - // it is actually running the busy loop. Empirically this sleep - // is sufficient to avoid the race. - usleep(100000); - - // Children are ready now. - LinuxPtraceDumper dumper(child_pid); - ASSERT_TRUE(dumper.Init()); - EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size()); - EXPECT_TRUE(dumper.ThreadsSuspend()); - - ThreadInfo one_thread; - for (size_t i = 0; i < dumper.threads().size(); ++i) { - EXPECT_TRUE(dumper.GetThreadInfoByIndex(i, &one_thread)); - const void* stack; - size_t stack_len; - EXPECT_TRUE(dumper.GetStackInfo(&stack, &stack_len, - one_thread.stack_pointer)); - // In the helper program, we stored a pointer to the thread id in a - // specific register. Check that we can recover its value. -#if defined(__ARM_EABI__) - pid_t* process_tid_location = (pid_t*)(one_thread.regs.uregs[3]); -#elif defined(__aarch64__) - pid_t* process_tid_location = (pid_t*)(one_thread.regs.regs[3]); -#elif defined(__i386) - pid_t* process_tid_location = (pid_t*)(one_thread.regs.ecx); -#elif defined(__x86_64) - pid_t* process_tid_location = (pid_t*)(one_thread.regs.rcx); -#elif defined(__mips__) - pid_t* process_tid_location = - reinterpret_cast(one_thread.mcontext.gregs[1]); -#else -#error This test has not been ported to this platform. -#endif - pid_t one_thread_id; - dumper.CopyFromProcess(&one_thread_id, - dumper.threads()[i], - process_tid_location, - 4); - EXPECT_EQ(dumper.threads()[i], one_thread_id); - } - EXPECT_TRUE(dumper.ThreadsResume()); - kill(child_pid, SIGKILL); - - // Reap child - int status; - ASSERT_NE(-1, HANDLE_EINTR(waitpid(child_pid, &status, 0))); - ASSERT_TRUE(WIFSIGNALED(status)); - ASSERT_EQ(SIGKILL, WTERMSIG(status)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc deleted file mode 100644 index 4b1ae5ad3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc +++ /dev/null @@ -1,1376 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This code writes out minidump files: -// http://msdn.microsoft.com/en-us/library/ms680378(VS.85,loband).aspx -// -// Minidumps are a Microsoft format which Breakpad uses for recording crash -// dumps. This code has to run in a compromised environment (the address space -// may have received SIGSEGV), thus the following rules apply: -// * You may not enter the dynamic linker. This means that we cannot call -// any symbols in a shared library (inc libc). Because of this we replace -// libc functions in linux_libc_support.h. -// * You may not call syscalls via the libc wrappers. This rule is a subset -// of the first rule but it bears repeating. We have direct wrappers -// around the system calls in linux_syscall_support.h. -// * You may not malloc. There's an alternative allocator in memory.h and -// a canonical instance in the LinuxDumper object. We use the placement -// new form to allocate objects and we don't delete them. - -#include "client/linux/handler/minidump_descriptor.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "client/minidump_file_writer-inl.h" - -#include -#include -#include -#include -#include -#if defined(__ANDROID__) -#include -#endif -#include -#include -#include -#include -#include -#include - -#include - -#include "client/linux/dump_writer_common/thread_info.h" -#include "client/linux/dump_writer_common/ucontext_reader.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/minidump_writer/cpu_set.h" -#include "client/linux/minidump_writer/line_reader.h" -#include "client/linux/minidump_writer/linux_dumper.h" -#include "client/linux/minidump_writer/linux_ptrace_dumper.h" -#include "client/linux/minidump_writer/proc_cpuinfo_reader.h" -#include "client/minidump_file_writer.h" -#include "common/linux/file_id.h" -#include "common/linux/linux_libc_support.h" -#include "common/minidump_type_helper.h" -#include "google_breakpad/common/minidump_format.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace { - -using google_breakpad::AppMemoryList; -using google_breakpad::auto_wasteful_vector; -using google_breakpad::ExceptionHandler; -using google_breakpad::CpuSet; -using google_breakpad::kDefaultBuildIdSize; -using google_breakpad::LineReader; -using google_breakpad::LinuxDumper; -using google_breakpad::LinuxPtraceDumper; -using google_breakpad::MDTypeHelper; -using google_breakpad::MappingEntry; -using google_breakpad::MappingInfo; -using google_breakpad::MappingList; -using google_breakpad::MinidumpFileWriter; -using google_breakpad::PageAllocator; -using google_breakpad::ProcCpuInfoReader; -using google_breakpad::RawContextCPU; -using google_breakpad::ThreadInfo; -using google_breakpad::TypedMDRVA; -using google_breakpad::UContextReader; -using google_breakpad::UntypedMDRVA; -using google_breakpad::wasteful_vector; - -typedef MDTypeHelper::MDRawDebug MDRawDebug; -typedef MDTypeHelper::MDRawLinkMap MDRawLinkMap; - -class MinidumpWriter { - public: - // The following kLimit* constants are for when minidump_size_limit_ is set - // and the minidump size might exceed it. - // - // Estimate for how big each thread's stack will be (in bytes). - static const unsigned kLimitAverageThreadStackLength = 8 * 1024; - // Number of threads whose stack size we don't want to limit. These base - // threads will simply be the first N threads returned by the dumper (although - // the crashing thread will never be limited). Threads beyond this count are - // the extra threads. - static const unsigned kLimitBaseThreadCount = 20; - // Maximum stack size to dump for any extra thread (in bytes). - static const unsigned kLimitMaxExtraThreadStackLen = 2 * 1024; - // Make sure this number of additional bytes can fit in the minidump - // (exclude the stack data). - static const unsigned kLimitMinidumpFudgeFactor = 64 * 1024; - - MinidumpWriter(const char* minidump_path, - int minidump_fd, - const ExceptionHandler::CrashContext* context, - const MappingList& mappings, - const AppMemoryList& appmem, - LinuxDumper* dumper) - : fd_(minidump_fd), - path_(minidump_path), - ucontext_(context ? &context->context : NULL), -#if !defined(__ARM_EABI__) && !defined(__mips__) - float_state_(context ? &context->float_state : NULL), -#endif - dumper_(dumper), - minidump_size_limit_(-1), - memory_blocks_(dumper_->allocator()), - mapping_list_(mappings), - app_memory_list_(appmem) { - // Assert there should be either a valid fd or a valid path, not both. - assert(fd_ != -1 || minidump_path); - assert(fd_ == -1 || !minidump_path); - } - - bool Init() { - if (!dumper_->Init()) - return false; - - if (fd_ != -1) - minidump_writer_.SetFile(fd_); - else if (!minidump_writer_.Open(path_)) - return false; - - return dumper_->ThreadsSuspend() && dumper_->LateInit(); - } - - ~MinidumpWriter() { - // Don't close the file descriptor when it's been provided explicitly. - // Callers might still need to use it. - if (fd_ == -1) - minidump_writer_.Close(); - dumper_->ThreadsResume(); - } - - bool Dump() { - // A minidump file contains a number of tagged streams. This is the number - // of stream which we write. - unsigned kNumWriters = 13; - - TypedMDRVA dir(&minidump_writer_); - { - // Ensure the header gets flushed, as that happens in the destructor. - // If we crash somewhere below, we should have a mostly-intact dump - TypedMDRVA header(&minidump_writer_); - if (!header.Allocate()) - return false; - - if (!dir.AllocateArray(kNumWriters)) - return false; - - my_memset(header.get(), 0, sizeof(MDRawHeader)); - - header.get()->signature = MD_HEADER_SIGNATURE; - header.get()->version = MD_HEADER_VERSION; - header.get()->time_date_stamp = time(NULL); - header.get()->stream_count = kNumWriters; - header.get()->stream_directory_rva = dir.position(); - } - - unsigned dir_index = 0; - MDRawDirectory dirent; - - if (!WriteThreadListStream(&dirent)) - return false; - dir.CopyIndex(dir_index++, &dirent); - - if (!WriteMappings(&dirent)) - return false; - dir.CopyIndex(dir_index++, &dirent); - - if (!WriteAppMemory()) - return false; - - if (!WriteMemoryListStream(&dirent)) - return false; - dir.CopyIndex(dir_index++, &dirent); - - if (!WriteExceptionStream(&dirent)) - return false; - dir.CopyIndex(dir_index++, &dirent); - - if (!WriteSystemInfoStream(&dirent)) - return false; - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_CPU_INFO; - if (!WriteFile(&dirent.location, "/proc/cpuinfo")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_PROC_STATUS; - if (!WriteProcFile(&dirent.location, GetCrashThread(), "status")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_LSB_RELEASE; - if (!WriteFile(&dirent.location, "/etc/lsb-release")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_CMD_LINE; - if (!WriteProcFile(&dirent.location, GetCrashThread(), "cmdline")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_ENVIRON; - if (!WriteProcFile(&dirent.location, GetCrashThread(), "environ")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_AUXV; - if (!WriteProcFile(&dirent.location, GetCrashThread(), "auxv")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_MAPS; - if (!WriteProcFile(&dirent.location, GetCrashThread(), "maps")) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - dirent.stream_type = MD_LINUX_DSO_DEBUG; - if (!WriteDSODebugStream(&dirent)) - NullifyDirectoryEntry(&dirent); - dir.CopyIndex(dir_index++, &dirent); - - // If you add more directory entries, don't forget to update kNumWriters, - // above. - - dumper_->ThreadsResume(); - return true; - } - - bool FillThreadStack(MDRawThread* thread, uintptr_t stack_pointer, - int max_stack_len, uint8_t** stack_copy) { - *stack_copy = NULL; - const void* stack; - size_t stack_len; - if (dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) { - UntypedMDRVA memory(&minidump_writer_); - if (max_stack_len >= 0 && - stack_len > static_cast(max_stack_len)) { - stack_len = max_stack_len; - // Skip empty chunks of length max_stack_len. - uintptr_t int_stack = reinterpret_cast(stack); - if (max_stack_len > 0) { - while (int_stack + max_stack_len < stack_pointer) { - int_stack += max_stack_len; - } - } - stack = reinterpret_cast(int_stack); - } - if (!memory.Allocate(stack_len)) - return false; - *stack_copy = reinterpret_cast(Alloc(stack_len)); - dumper_->CopyFromProcess(*stack_copy, thread->thread_id, stack, - stack_len); - memory.Copy(*stack_copy, stack_len); - thread->stack.start_of_memory_range = - reinterpret_cast(stack); - thread->stack.memory = memory.location(); - memory_blocks_.push_back(thread->stack); - } else { - thread->stack.start_of_memory_range = stack_pointer; - thread->stack.memory.data_size = 0; - thread->stack.memory.rva = minidump_writer_.position(); - } - return true; - } - - // Write information about the threads. - bool WriteThreadListStream(MDRawDirectory* dirent) { - const unsigned num_threads = dumper_->threads().size(); - - TypedMDRVA list(&minidump_writer_); - if (!list.AllocateObjectAndArray(num_threads, sizeof(MDRawThread))) - return false; - - dirent->stream_type = MD_THREAD_LIST_STREAM; - dirent->location = list.location(); - - *list.get() = num_threads; - - // If there's a minidump size limit, check if it might be exceeded. Since - // most of the space is filled with stack data, just check against that. - // If this expects to exceed the limit, set extra_thread_stack_len such - // that any thread beyond the first kLimitBaseThreadCount threads will - // have only kLimitMaxExtraThreadStackLen bytes dumped. - int extra_thread_stack_len = -1; // default to no maximum - if (minidump_size_limit_ >= 0) { - const unsigned estimated_total_stack_size = num_threads * - kLimitAverageThreadStackLength; - const off_t estimated_minidump_size = minidump_writer_.position() + - estimated_total_stack_size + kLimitMinidumpFudgeFactor; - if (estimated_minidump_size > minidump_size_limit_) - extra_thread_stack_len = kLimitMaxExtraThreadStackLen; - } - - for (unsigned i = 0; i < num_threads; ++i) { - MDRawThread thread; - my_memset(&thread, 0, sizeof(thread)); - thread.thread_id = dumper_->threads()[i]; - - // We have a different source of information for the crashing thread. If - // we used the actual state of the thread we would find it running in the - // signal handler with the alternative stack, which would be deeply - // unhelpful. - if (static_cast(thread.thread_id) == GetCrashThread() && - ucontext_ && - !dumper_->IsPostMortem()) { - uint8_t* stack_copy; - const uintptr_t stack_ptr = UContextReader::GetStackPointer(ucontext_); - if (!FillThreadStack(&thread, stack_ptr, -1, &stack_copy)) - return false; - - // Copy 256 bytes around crashing instruction pointer to minidump. - const size_t kIPMemorySize = 256; - uint64_t ip = UContextReader::GetInstructionPointer(ucontext_); - // Bound it to the upper and lower bounds of the memory map - // it's contained within. If it's not in mapped memory, - // don't bother trying to write it. - bool ip_is_mapped = false; - MDMemoryDescriptor ip_memory_d; - for (unsigned j = 0; j < dumper_->mappings().size(); ++j) { - const MappingInfo& mapping = *dumper_->mappings()[j]; - if (ip >= mapping.start_addr && - ip < mapping.start_addr + mapping.size) { - ip_is_mapped = true; - // Try to get 128 bytes before and after the IP, but - // settle for whatever's available. - ip_memory_d.start_of_memory_range = - std::max(mapping.start_addr, - uintptr_t(ip - (kIPMemorySize / 2))); - uintptr_t end_of_range = - std::min(uintptr_t(ip + (kIPMemorySize / 2)), - uintptr_t(mapping.start_addr + mapping.size)); - ip_memory_d.memory.data_size = - end_of_range - ip_memory_d.start_of_memory_range; - break; - } - } - - if (ip_is_mapped) { - UntypedMDRVA ip_memory(&minidump_writer_); - if (!ip_memory.Allocate(ip_memory_d.memory.data_size)) - return false; - uint8_t* memory_copy = - reinterpret_cast(Alloc(ip_memory_d.memory.data_size)); - dumper_->CopyFromProcess( - memory_copy, - thread.thread_id, - reinterpret_cast(ip_memory_d.start_of_memory_range), - ip_memory_d.memory.data_size); - ip_memory.Copy(memory_copy, ip_memory_d.memory.data_size); - ip_memory_d.memory = ip_memory.location(); - memory_blocks_.push_back(ip_memory_d); - } - - TypedMDRVA cpu(&minidump_writer_); - if (!cpu.Allocate()) - return false; - my_memset(cpu.get(), 0, sizeof(RawContextCPU)); -#if !defined(__ARM_EABI__) && !defined(__mips__) - UContextReader::FillCPUContext(cpu.get(), ucontext_, float_state_); -#else - UContextReader::FillCPUContext(cpu.get(), ucontext_); -#endif - thread.thread_context = cpu.location(); - crashing_thread_context_ = cpu.location(); - } else { - ThreadInfo info; - if (!dumper_->GetThreadInfoByIndex(i, &info)) - return false; - - uint8_t* stack_copy; - int max_stack_len = -1; // default to no maximum for this thread - if (minidump_size_limit_ >= 0 && i >= kLimitBaseThreadCount) - max_stack_len = extra_thread_stack_len; - if (!FillThreadStack(&thread, info.stack_pointer, max_stack_len, - &stack_copy)) - return false; - - TypedMDRVA cpu(&minidump_writer_); - if (!cpu.Allocate()) - return false; - my_memset(cpu.get(), 0, sizeof(RawContextCPU)); - info.FillCPUContext(cpu.get()); - thread.thread_context = cpu.location(); - if (dumper_->threads()[i] == GetCrashThread()) { - crashing_thread_context_ = cpu.location(); - if (!dumper_->IsPostMortem()) { - // This is the crashing thread of a live process, but - // no context was provided, so set the crash address - // while the instruction pointer is already here. - dumper_->set_crash_address(info.GetInstructionPointer()); - } - } - } - - list.CopyIndexAfterObject(i, &thread, sizeof(thread)); - } - - return true; - } - - // Write application-provided memory regions. - bool WriteAppMemory() { - for (AppMemoryList::const_iterator iter = app_memory_list_.begin(); - iter != app_memory_list_.end(); - ++iter) { - uint8_t* data_copy = - reinterpret_cast(dumper_->allocator()->Alloc(iter->length)); - dumper_->CopyFromProcess(data_copy, GetCrashThread(), iter->ptr, - iter->length); - - UntypedMDRVA memory(&minidump_writer_); - if (!memory.Allocate(iter->length)) { - return false; - } - memory.Copy(data_copy, iter->length); - MDMemoryDescriptor desc; - desc.start_of_memory_range = reinterpret_cast(iter->ptr); - desc.memory = memory.location(); - memory_blocks_.push_back(desc); - } - - return true; - } - - static bool ShouldIncludeMapping(const MappingInfo& mapping) { - if (mapping.name[0] == 0 || // only want modules with filenames. - // Only want to include one mapping per shared lib. - // Avoid filtering executable mappings. - (mapping.offset != 0 && !mapping.exec) || - mapping.size < 4096) { // too small to get a signature for. - return false; - } - - return true; - } - - // If there is caller-provided information about this mapping - // in the mapping_list_ list, return true. Otherwise, return false. - bool HaveMappingInfo(const MappingInfo& mapping) { - for (MappingList::const_iterator iter = mapping_list_.begin(); - iter != mapping_list_.end(); - ++iter) { - // Ignore any mappings that are wholly contained within - // mappings in the mapping_info_ list. - if (mapping.start_addr >= iter->first.start_addr && - (mapping.start_addr + mapping.size) <= - (iter->first.start_addr + iter->first.size)) { - return true; - } - } - return false; - } - - // Write information about the mappings in effect. Because we are using the - // minidump format, the information about the mappings is pretty limited. - // Because of this, we also include the full, unparsed, /proc/$x/maps file in - // another stream in the file. - bool WriteMappings(MDRawDirectory* dirent) { - const unsigned num_mappings = dumper_->mappings().size(); - unsigned num_output_mappings = mapping_list_.size(); - - for (unsigned i = 0; i < dumper_->mappings().size(); ++i) { - const MappingInfo& mapping = *dumper_->mappings()[i]; - if (ShouldIncludeMapping(mapping) && !HaveMappingInfo(mapping)) - num_output_mappings++; - } - - TypedMDRVA list(&minidump_writer_); - if (num_output_mappings) { - if (!list.AllocateObjectAndArray(num_output_mappings, MD_MODULE_SIZE)) - return false; - } else { - // Still create the module list stream, although it will have zero - // modules. - if (!list.Allocate()) - return false; - } - - dirent->stream_type = MD_MODULE_LIST_STREAM; - dirent->location = list.location(); - *list.get() = num_output_mappings; - - // First write all the mappings from the dumper - unsigned int j = 0; - for (unsigned i = 0; i < num_mappings; ++i) { - const MappingInfo& mapping = *dumper_->mappings()[i]; - if (!ShouldIncludeMapping(mapping) || HaveMappingInfo(mapping)) - continue; - - MDRawModule mod; - if (!FillRawModule(mapping, true, i, &mod, NULL)) - return false; - list.CopyIndexAfterObject(j++, &mod, MD_MODULE_SIZE); - } - // Next write all the mappings provided by the caller - for (MappingList::const_iterator iter = mapping_list_.begin(); - iter != mapping_list_.end(); - ++iter) { - MDRawModule mod; - if (!FillRawModule(iter->first, false, 0, &mod, iter->second)) - return false; - list.CopyIndexAfterObject(j++, &mod, MD_MODULE_SIZE); - } - - return true; - } - - // Fill the MDRawModule |mod| with information about the provided - // |mapping|. If |identifier| is non-NULL, use it instead of calculating - // a file ID from the mapping. - bool FillRawModule(const MappingInfo& mapping, - bool member, - unsigned int mapping_id, - MDRawModule* mod, - const uint8_t* identifier) { - my_memset(mod, 0, MD_MODULE_SIZE); - - mod->base_of_image = mapping.start_addr; - mod->size_of_image = mapping.size; - - auto_wasteful_vector identifier_bytes( - dumper_->allocator()); - - if (identifier) { - // GUID was provided by caller. - identifier_bytes.insert(identifier_bytes.end(), - identifier, - identifier + sizeof(MDGUID)); - } else { - // Note: ElfFileIdentifierForMapping() can manipulate the |mapping.name|. - dumper_->ElfFileIdentifierForMapping(mapping, - member, - mapping_id, - identifier_bytes); - } - - if (!identifier_bytes.empty()) { - UntypedMDRVA cv(&minidump_writer_); - if (!cv.Allocate(MDCVInfoELF_minsize + identifier_bytes.size())) - return false; - - const uint32_t cv_signature = MD_CVINFOELF_SIGNATURE; - cv.Copy(&cv_signature, sizeof(cv_signature)); - cv.Copy(cv.position() + sizeof(cv_signature), &identifier_bytes[0], - identifier_bytes.size()); - - mod->cv_record = cv.location(); - } - - char file_name[NAME_MAX]; - char file_path[NAME_MAX]; - dumper_->GetMappingEffectiveNameAndPath( - mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); - - MDLocationDescriptor ld; - if (!minidump_writer_.WriteString(file_path, my_strlen(file_path), &ld)) - return false; - mod->module_name_rva = ld.rva; - return true; - } - - bool WriteMemoryListStream(MDRawDirectory* dirent) { - TypedMDRVA list(&minidump_writer_); - if (memory_blocks_.size()) { - if (!list.AllocateObjectAndArray(memory_blocks_.size(), - sizeof(MDMemoryDescriptor))) - return false; - } else { - // Still create the memory list stream, although it will have zero - // memory blocks. - if (!list.Allocate()) - return false; - } - - dirent->stream_type = MD_MEMORY_LIST_STREAM; - dirent->location = list.location(); - - *list.get() = memory_blocks_.size(); - - for (size_t i = 0; i < memory_blocks_.size(); ++i) { - list.CopyIndexAfterObject(i, &memory_blocks_[i], - sizeof(MDMemoryDescriptor)); - } - return true; - } - - bool WriteExceptionStream(MDRawDirectory* dirent) { - TypedMDRVA exc(&minidump_writer_); - if (!exc.Allocate()) - return false; - my_memset(exc.get(), 0, sizeof(MDRawExceptionStream)); - - dirent->stream_type = MD_EXCEPTION_STREAM; - dirent->location = exc.location(); - - exc.get()->thread_id = GetCrashThread(); - exc.get()->exception_record.exception_code = dumper_->crash_signal(); - exc.get()->exception_record.exception_address = dumper_->crash_address(); - exc.get()->thread_context = crashing_thread_context_; - - return true; - } - - bool WriteSystemInfoStream(MDRawDirectory* dirent) { - TypedMDRVA si(&minidump_writer_); - if (!si.Allocate()) - return false; - my_memset(si.get(), 0, sizeof(MDRawSystemInfo)); - - dirent->stream_type = MD_SYSTEM_INFO_STREAM; - dirent->location = si.location(); - - WriteCPUInformation(si.get()); - WriteOSInformation(si.get()); - - return true; - } - - bool WriteDSODebugStream(MDRawDirectory* dirent) { - ElfW(Phdr)* phdr = reinterpret_cast(dumper_->auxv()[AT_PHDR]); - char* base; - int phnum = dumper_->auxv()[AT_PHNUM]; - if (!phnum || !phdr) - return false; - - // Assume the program base is at the beginning of the same page as the PHDR - base = reinterpret_cast(reinterpret_cast(phdr) & ~0xfff); - - // Search for the program PT_DYNAMIC segment - ElfW(Addr) dyn_addr = 0; - for (; phnum >= 0; phnum--, phdr++) { - ElfW(Phdr) ph; - if (!dumper_->CopyFromProcess(&ph, GetCrashThread(), phdr, sizeof(ph))) - return false; - - // Adjust base address with the virtual address of the PT_LOAD segment - // corresponding to offset 0 - if (ph.p_type == PT_LOAD && ph.p_offset == 0) { - base -= ph.p_vaddr; - } - if (ph.p_type == PT_DYNAMIC) { - dyn_addr = ph.p_vaddr; - } - } - if (!dyn_addr) - return false; - - ElfW(Dyn) *dynamic = reinterpret_cast(dyn_addr + base); - - // The dynamic linker makes information available that helps gdb find all - // DSOs loaded into the program. If this information is indeed available, - // dump it to a MD_LINUX_DSO_DEBUG stream. - struct r_debug* r_debug = NULL; - uint32_t dynamic_length = 0; - - for (int i = 0; ; ++i) { - ElfW(Dyn) dyn; - dynamic_length += sizeof(dyn); - if (!dumper_->CopyFromProcess(&dyn, GetCrashThread(), dynamic + i, - sizeof(dyn))) { - return false; - } - -#ifdef __mips__ - const int32_t debug_tag = DT_MIPS_RLD_MAP; -#else - const int32_t debug_tag = DT_DEBUG; -#endif - if (dyn.d_tag == debug_tag) { - r_debug = reinterpret_cast(dyn.d_un.d_ptr); - continue; - } else if (dyn.d_tag == DT_NULL) { - break; - } - } - - // The "r_map" field of that r_debug struct contains a linked list of all - // loaded DSOs. - // Our list of DSOs potentially is different from the ones in the crashing - // process. So, we have to be careful to never dereference pointers - // directly. Instead, we use CopyFromProcess() everywhere. - // See for a more detailed discussion of the how the dynamic - // loader communicates with debuggers. - - // Count the number of loaded DSOs - int dso_count = 0; - struct r_debug debug_entry; - if (!dumper_->CopyFromProcess(&debug_entry, GetCrashThread(), r_debug, - sizeof(debug_entry))) { - return false; - } - for (struct link_map* ptr = debug_entry.r_map; ptr; ) { - struct link_map map; - if (!dumper_->CopyFromProcess(&map, GetCrashThread(), ptr, sizeof(map))) - return false; - - ptr = map.l_next; - dso_count++; - } - - MDRVA linkmap_rva = minidump_writer_.kInvalidMDRVA; - if (dso_count > 0) { - // If we have at least one DSO, create an array of MDRawLinkMap - // entries in the minidump file. - TypedMDRVA linkmap(&minidump_writer_); - if (!linkmap.AllocateArray(dso_count)) - return false; - linkmap_rva = linkmap.location().rva; - int idx = 0; - - // Iterate over DSOs and write their information to mini dump - for (struct link_map* ptr = debug_entry.r_map; ptr; ) { - struct link_map map; - if (!dumper_->CopyFromProcess(&map, GetCrashThread(), ptr, sizeof(map))) - return false; - - ptr = map.l_next; - char filename[257] = { 0 }; - if (map.l_name) { - dumper_->CopyFromProcess(filename, GetCrashThread(), map.l_name, - sizeof(filename) - 1); - } - MDLocationDescriptor location; - if (!minidump_writer_.WriteString(filename, 0, &location)) - return false; - MDRawLinkMap entry; - entry.name = location.rva; - entry.addr = map.l_addr; - entry.ld = reinterpret_cast(map.l_ld); - linkmap.CopyIndex(idx++, &entry); - } - } - - // Write MD_LINUX_DSO_DEBUG record - TypedMDRVA debug(&minidump_writer_); - if (!debug.AllocateObjectAndArray(1, dynamic_length)) - return false; - my_memset(debug.get(), 0, sizeof(MDRawDebug)); - dirent->stream_type = MD_LINUX_DSO_DEBUG; - dirent->location = debug.location(); - - debug.get()->version = debug_entry.r_version; - debug.get()->map = linkmap_rva; - debug.get()->dso_count = dso_count; - debug.get()->brk = debug_entry.r_brk; - debug.get()->ldbase = debug_entry.r_ldbase; - debug.get()->dynamic = reinterpret_cast(dynamic); - - wasteful_vector dso_debug_data(dumper_->allocator(), dynamic_length); - // The passed-in size to the constructor (above) is only a hint. - // Must call .resize() to do actual initialization of the elements. - dso_debug_data.resize(dynamic_length); - dumper_->CopyFromProcess(&dso_debug_data[0], GetCrashThread(), dynamic, - dynamic_length); - debug.CopyIndexAfterObject(0, &dso_debug_data[0], dynamic_length); - - return true; - } - - void set_minidump_size_limit(off_t limit) { minidump_size_limit_ = limit; } - - private: - void* Alloc(unsigned bytes) { - return dumper_->allocator()->Alloc(bytes); - } - - pid_t GetCrashThread() const { - return dumper_->crash_thread(); - } - - void NullifyDirectoryEntry(MDRawDirectory* dirent) { - dirent->stream_type = 0; - dirent->location.data_size = 0; - dirent->location.rva = 0; - } - -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) - bool WriteCPUInformation(MDRawSystemInfo* sys_info) { - char vendor_id[sizeof(sys_info->cpu.x86_cpu_info.vendor_id) + 1] = {0}; - static const char vendor_id_name[] = "vendor_id"; - - struct CpuInfoEntry { - const char* info_name; - int value; - bool found; - } cpu_info_table[] = { - { "processor", -1, false }, -#if defined(__i386__) || defined(__x86_64__) - { "model", 0, false }, - { "stepping", 0, false }, - { "cpu family", 0, false }, -#endif - }; - - // processor_architecture should always be set, do this first - sys_info->processor_architecture = -#if defined(__mips__) -# if _MIPS_SIM == _ABIO32 - MD_CPU_ARCHITECTURE_MIPS; -# elif _MIPS_SIM == _ABI64 - MD_CPU_ARCHITECTURE_MIPS64; -# else -# error "This mips ABI is currently not supported (n32)" -#endif -#elif defined(__i386__) - MD_CPU_ARCHITECTURE_X86; -#else - MD_CPU_ARCHITECTURE_AMD64; -#endif - - const int fd = sys_open("/proc/cpuinfo", O_RDONLY, 0); - if (fd < 0) - return false; - - { - PageAllocator allocator; - ProcCpuInfoReader* const reader = new(allocator) ProcCpuInfoReader(fd); - const char* field; - while (reader->GetNextField(&field)) { - bool is_first_entry = true; - for (CpuInfoEntry& entry : cpu_info_table) { - if (!is_first_entry && entry.found) { - // except for the 'processor' field, ignore repeated values. - continue; - } - is_first_entry = false; - if (!my_strcmp(field, entry.info_name)) { - size_t value_len; - const char* value = reader->GetValueAndLen(&value_len); - if (value_len == 0) - continue; - - uintptr_t val; - if (my_read_decimal_ptr(&val, value) == value) - continue; - - entry.value = static_cast(val); - entry.found = true; - } - } - - // special case for vendor_id - if (!my_strcmp(field, vendor_id_name)) { - size_t value_len; - const char* value = reader->GetValueAndLen(&value_len); - if (value_len > 0) - my_strlcpy(vendor_id, value, sizeof(vendor_id)); - } - } - sys_close(fd); - } - - // make sure we got everything we wanted - for (const CpuInfoEntry& entry : cpu_info_table) { - if (!entry.found) { - return false; - } - } - // cpu_info_table[0] holds the last cpu id listed in /proc/cpuinfo, - // assuming this is the highest id, change it to the number of CPUs - // by adding one. - cpu_info_table[0].value++; - - sys_info->number_of_processors = cpu_info_table[0].value; -#if defined(__i386__) || defined(__x86_64__) - sys_info->processor_level = cpu_info_table[3].value; - sys_info->processor_revision = cpu_info_table[1].value << 8 | - cpu_info_table[2].value; -#endif - - if (vendor_id[0] != '\0') { - my_memcpy(sys_info->cpu.x86_cpu_info.vendor_id, vendor_id, - sizeof(sys_info->cpu.x86_cpu_info.vendor_id)); - } - return true; - } -#elif defined(__arm__) || defined(__aarch64__) - bool WriteCPUInformation(MDRawSystemInfo* sys_info) { - // The CPUID value is broken up in several entries in /proc/cpuinfo. - // This table is used to rebuild it from the entries. - const struct CpuIdEntry { - const char* field; - char format; - char bit_lshift; - char bit_length; - } cpu_id_entries[] = { - { "CPU implementer", 'x', 24, 8 }, - { "CPU variant", 'x', 20, 4 }, - { "CPU part", 'x', 4, 12 }, - { "CPU revision", 'd', 0, 4 }, - }; - - // The ELF hwcaps are listed in the "Features" entry as textual tags. - // This table is used to rebuild them. - const struct CpuFeaturesEntry { - const char* tag; - uint32_t hwcaps; - } cpu_features_entries[] = { -#if defined(__arm__) - { "swp", MD_CPU_ARM_ELF_HWCAP_SWP }, - { "half", MD_CPU_ARM_ELF_HWCAP_HALF }, - { "thumb", MD_CPU_ARM_ELF_HWCAP_THUMB }, - { "26bit", MD_CPU_ARM_ELF_HWCAP_26BIT }, - { "fastmult", MD_CPU_ARM_ELF_HWCAP_FAST_MULT }, - { "fpa", MD_CPU_ARM_ELF_HWCAP_FPA }, - { "vfp", MD_CPU_ARM_ELF_HWCAP_VFP }, - { "edsp", MD_CPU_ARM_ELF_HWCAP_EDSP }, - { "java", MD_CPU_ARM_ELF_HWCAP_JAVA }, - { "iwmmxt", MD_CPU_ARM_ELF_HWCAP_IWMMXT }, - { "crunch", MD_CPU_ARM_ELF_HWCAP_CRUNCH }, - { "thumbee", MD_CPU_ARM_ELF_HWCAP_THUMBEE }, - { "neon", MD_CPU_ARM_ELF_HWCAP_NEON }, - { "vfpv3", MD_CPU_ARM_ELF_HWCAP_VFPv3 }, - { "vfpv3d16", MD_CPU_ARM_ELF_HWCAP_VFPv3D16 }, - { "tls", MD_CPU_ARM_ELF_HWCAP_TLS }, - { "vfpv4", MD_CPU_ARM_ELF_HWCAP_VFPv4 }, - { "idiva", MD_CPU_ARM_ELF_HWCAP_IDIVA }, - { "idivt", MD_CPU_ARM_ELF_HWCAP_IDIVT }, - { "idiv", MD_CPU_ARM_ELF_HWCAP_IDIVA | MD_CPU_ARM_ELF_HWCAP_IDIVT }, -#elif defined(__aarch64__) - // No hwcaps on aarch64. -#endif - }; - - // processor_architecture should always be set, do this first - sys_info->processor_architecture = -#if defined(__aarch64__) - MD_CPU_ARCHITECTURE_ARM64; -#else - MD_CPU_ARCHITECTURE_ARM; -#endif - - // /proc/cpuinfo is not readable under various sandboxed environments - // (e.g. Android services with the android:isolatedProcess attribute) - // prepare for this by setting default values now, which will be - // returned when this happens. - // - // Note: Bogus values are used to distinguish between failures (to - // read /sys and /proc files) and really badly configured kernels. - sys_info->number_of_processors = 0; - sys_info->processor_level = 1U; // There is no ARMv1 - sys_info->processor_revision = 42; - sys_info->cpu.arm_cpu_info.cpuid = 0; - sys_info->cpu.arm_cpu_info.elf_hwcaps = 0; - - // Counting the number of CPUs involves parsing two sysfs files, - // because the content of /proc/cpuinfo will only mirror the number - // of 'online' cores, and thus will vary with time. - // See http://www.kernel.org/doc/Documentation/cputopology.txt - { - CpuSet cpus_present; - CpuSet cpus_possible; - - int fd = sys_open("/sys/devices/system/cpu/present", O_RDONLY, 0); - if (fd >= 0) { - cpus_present.ParseSysFile(fd); - sys_close(fd); - - fd = sys_open("/sys/devices/system/cpu/possible", O_RDONLY, 0); - if (fd >= 0) { - cpus_possible.ParseSysFile(fd); - sys_close(fd); - - cpus_present.IntersectWith(cpus_possible); - int cpu_count = cpus_present.GetCount(); - if (cpu_count > 255) - cpu_count = 255; - sys_info->number_of_processors = static_cast(cpu_count); - } - } - } - - // Parse /proc/cpuinfo to reconstruct the CPUID value, as well - // as the ELF hwcaps field. For the latter, it would be easier to - // read /proc/self/auxv but unfortunately, this file is not always - // readable from regular Android applications on later versions - // (>= 4.1) of the Android platform. - const int fd = sys_open("/proc/cpuinfo", O_RDONLY, 0); - if (fd < 0) { - // Do not return false here to allow the minidump generation - // to happen properly. - return true; - } - - { - PageAllocator allocator; - ProcCpuInfoReader* const reader = - new(allocator) ProcCpuInfoReader(fd); - const char* field; - while (reader->GetNextField(&field)) { - for (const CpuIdEntry& entry : cpu_id_entries) { - if (my_strcmp(entry.field, field) != 0) - continue; - uintptr_t result = 0; - const char* value = reader->GetValue(); - const char* p = value; - if (value[0] == '0' && value[1] == 'x') { - p = my_read_hex_ptr(&result, value+2); - } else if (entry.format == 'x') { - p = my_read_hex_ptr(&result, value); - } else { - p = my_read_decimal_ptr(&result, value); - } - if (p == value) - continue; - - result &= (1U << entry.bit_length)-1; - result <<= entry.bit_lshift; - sys_info->cpu.arm_cpu_info.cpuid |= - static_cast(result); - } -#if defined(__arm__) - // Get the architecture version from the "Processor" field. - // Note that it is also available in the "CPU architecture" field, - // however, some existing kernels are misconfigured and will report - // invalid values here (e.g. 6, while the CPU is ARMv7-A based). - // The "Processor" field doesn't have this issue. - if (!my_strcmp(field, "Processor")) { - size_t value_len; - const char* value = reader->GetValueAndLen(&value_len); - // Expected format: (v) - // Where is some text like "ARMv7 Processor rev 2" - // and is a decimal corresponding to the ARM - // architecture number. is either 'l' or 'b' - // and corresponds to the endianess, it is ignored here. - while (value_len > 0 && my_isspace(value[value_len-1])) - value_len--; - - size_t nn = value_len; - while (nn > 0 && value[nn-1] != '(') - nn--; - if (nn > 0 && value[nn] == 'v') { - uintptr_t arch_level = 5; - my_read_decimal_ptr(&arch_level, value + nn + 1); - sys_info->processor_level = static_cast(arch_level); - } - } -#elif defined(__aarch64__) - // The aarch64 architecture does not provide the architecture level - // in the Processor field, so we instead check the "CPU architecture" - // field. - if (!my_strcmp(field, "CPU architecture")) { - uintptr_t arch_level = 0; - const char* value = reader->GetValue(); - const char* p = value; - p = my_read_decimal_ptr(&arch_level, value); - if (p == value) - continue; - sys_info->processor_level = static_cast(arch_level); - } -#endif - // Rebuild the ELF hwcaps from the 'Features' field. - if (!my_strcmp(field, "Features")) { - size_t value_len; - const char* value = reader->GetValueAndLen(&value_len); - - // Parse each space-separated tag. - while (value_len > 0) { - const char* tag = value; - size_t tag_len = value_len; - const char* p = my_strchr(tag, ' '); - if (p) { - tag_len = static_cast(p - tag); - value += tag_len + 1; - value_len -= tag_len + 1; - } else { - tag_len = strlen(tag); - value_len = 0; - } - for (const CpuFeaturesEntry& entry : cpu_features_entries) { - if (tag_len == strlen(entry.tag) && - !memcmp(tag, entry.tag, tag_len)) { - sys_info->cpu.arm_cpu_info.elf_hwcaps |= entry.hwcaps; - break; - } - } - } - } - } - sys_close(fd); - } - - return true; - } -#else -# error "Unsupported CPU" -#endif - - bool WriteFile(MDLocationDescriptor* result, const char* filename) { - const int fd = sys_open(filename, O_RDONLY, 0); - if (fd < 0) - return false; - - // We can't stat the files because several of the files that we want to - // read are kernel seqfiles, which always have a length of zero. So we have - // to read as much as we can into a buffer. - static const unsigned kBufSize = 1024 - 2*sizeof(void*); - struct Buffers { - Buffers* next; - size_t len; - uint8_t data[kBufSize]; - } *buffers = reinterpret_cast(Alloc(sizeof(Buffers))); - buffers->next = NULL; - buffers->len = 0; - - size_t total = 0; - for (Buffers* bufptr = buffers;;) { - ssize_t r; - do { - r = sys_read(fd, &bufptr->data[bufptr->len], kBufSize - bufptr->len); - } while (r == -1 && errno == EINTR); - - if (r < 1) - break; - - total += r; - bufptr->len += r; - if (bufptr->len == kBufSize) { - bufptr->next = reinterpret_cast(Alloc(sizeof(Buffers))); - bufptr = bufptr->next; - bufptr->next = NULL; - bufptr->len = 0; - } - } - sys_close(fd); - - if (!total) - return false; - - UntypedMDRVA memory(&minidump_writer_); - if (!memory.Allocate(total)) - return false; - for (MDRVA pos = memory.position(); buffers; buffers = buffers->next) { - // Check for special case of a zero-length buffer. This should only - // occur if a file's size happens to be a multiple of the buffer's - // size, in which case the final sys_read() will have resulted in - // zero bytes being read after the final buffer was just allocated. - if (buffers->len == 0) { - // This can only occur with final buffer. - assert(buffers->next == NULL); - continue; - } - memory.Copy(pos, &buffers->data, buffers->len); - pos += buffers->len; - } - *result = memory.location(); - return true; - } - - bool WriteOSInformation(MDRawSystemInfo* sys_info) { -#if defined(__ANDROID__) - sys_info->platform_id = MD_OS_ANDROID; -#else - sys_info->platform_id = MD_OS_LINUX; -#endif - - struct utsname uts; - if (uname(&uts)) - return false; - - static const size_t buf_len = 512; - char buf[buf_len] = {0}; - size_t space_left = buf_len - 1; - const char* info_table[] = { - uts.sysname, - uts.release, - uts.version, - uts.machine, - NULL - }; - bool first_item = true; - for (const char** cur_info = info_table; *cur_info; cur_info++) { - static const char separator[] = " "; - size_t separator_len = sizeof(separator) - 1; - size_t info_len = my_strlen(*cur_info); - if (info_len == 0) - continue; - - if (space_left < info_len + (first_item ? 0 : separator_len)) - break; - - if (!first_item) { - my_strlcat(buf, separator, sizeof(buf)); - space_left -= separator_len; - } - - first_item = false; - my_strlcat(buf, *cur_info, sizeof(buf)); - space_left -= info_len; - } - - MDLocationDescriptor location; - if (!minidump_writer_.WriteString(buf, 0, &location)) - return false; - sys_info->csd_version_rva = location.rva; - - return true; - } - - bool WriteProcFile(MDLocationDescriptor* result, pid_t pid, - const char* filename) { - char buf[NAME_MAX]; - if (!dumper_->BuildProcPath(buf, pid, filename)) - return false; - return WriteFile(result, buf); - } - - // Only one of the 2 member variables below should be set to a valid value. - const int fd_; // File descriptor where the minidum should be written. - const char* path_; // Path to the file where the minidum should be written. - - const ucontext_t* const ucontext_; // also from the signal handler -#if !defined(__ARM_EABI__) && !defined(__mips__) - const google_breakpad::fpstate_t* const float_state_; // ditto -#endif - LinuxDumper* dumper_; - MinidumpFileWriter minidump_writer_; - off_t minidump_size_limit_; - MDLocationDescriptor crashing_thread_context_; - // Blocks of memory written to the dump. These are all currently - // written while writing the thread list stream, but saved here - // so a memory list stream can be written afterwards. - wasteful_vector memory_blocks_; - // Additional information about some mappings provided by the caller. - const MappingList& mapping_list_; - // Additional memory regions to be included in the dump, - // provided by the caller. - const AppMemoryList& app_memory_list_; -}; - - -bool WriteMinidumpImpl(const char* minidump_path, - int minidump_fd, - off_t minidump_size_limit, - pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appmem) { - LinuxPtraceDumper dumper(crashing_process); - const ExceptionHandler::CrashContext* context = NULL; - if (blob) { - if (blob_size != sizeof(ExceptionHandler::CrashContext)) - return false; - context = reinterpret_cast(blob); - dumper.set_crash_address( - reinterpret_cast(context->siginfo.si_addr)); - dumper.set_crash_signal(context->siginfo.si_signo); - dumper.set_crash_thread(context->tid); - } - MinidumpWriter writer(minidump_path, minidump_fd, context, mappings, - appmem, &dumper); - // Set desired limit for file size of minidump (-1 means no limit). - writer.set_minidump_size_limit(minidump_size_limit); - if (!writer.Init()) - return false; - return writer.Dump(); -} - -} // namespace - -namespace google_breakpad { - -bool WriteMinidump(const char* minidump_path, pid_t crashing_process, - const void* blob, size_t blob_size) { - return WriteMinidumpImpl(minidump_path, -1, -1, - crashing_process, blob, blob_size, - MappingList(), AppMemoryList()); -} - -bool WriteMinidump(int minidump_fd, pid_t crashing_process, - const void* blob, size_t blob_size) { - return WriteMinidumpImpl(NULL, minidump_fd, -1, - crashing_process, blob, blob_size, - MappingList(), AppMemoryList()); -} - -bool WriteMinidump(const char* minidump_path, pid_t process, - pid_t process_blamed_thread) { - LinuxPtraceDumper dumper(process); - // MinidumpWriter will set crash address - dumper.set_crash_signal(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED); - dumper.set_crash_thread(process_blamed_thread); - MinidumpWriter writer(minidump_path, -1, NULL, MappingList(), - AppMemoryList(), &dumper); - if (!writer.Init()) - return false; - return writer.Dump(); -} - -bool WriteMinidump(const char* minidump_path, pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appmem) { - return WriteMinidumpImpl(minidump_path, -1, -1, crashing_process, - blob, blob_size, - mappings, appmem); -} - -bool WriteMinidump(int minidump_fd, pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appmem) { - return WriteMinidumpImpl(NULL, minidump_fd, -1, crashing_process, - blob, blob_size, - mappings, appmem); -} - -bool WriteMinidump(const char* minidump_path, off_t minidump_size_limit, - pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appmem) { - return WriteMinidumpImpl(minidump_path, -1, minidump_size_limit, - crashing_process, blob, blob_size, - mappings, appmem); -} - -bool WriteMinidump(int minidump_fd, off_t minidump_size_limit, - pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appmem) { - return WriteMinidumpImpl(NULL, minidump_fd, minidump_size_limit, - crashing_process, blob, blob_size, - mappings, appmem); -} - -bool WriteMinidump(const char* filename, - const MappingList& mappings, - const AppMemoryList& appmem, - LinuxDumper* dumper) { - MinidumpWriter writer(filename, -1, NULL, mappings, appmem, dumper); - if (!writer.Init()) - return false; - return writer.Dump(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h deleted file mode 100644 index d13fb120b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_H_ - -#include -#include -#include -#include - -#include -#include - -#include "client/linux/minidump_writer/linux_dumper.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -class ExceptionHandler; - -#if defined(__aarch64__) -typedef struct fpsimd_context fpstate_t; -#elif !defined(__ARM_EABI__) && !defined(__mips__) -typedef struct _libc_fpstate fpstate_t; -#endif - -// These entries store a list of memory regions that the client wants included -// in the minidump. -struct AppMemory { - void* ptr; - size_t length; - - bool operator==(const struct AppMemory& other) const { - return ptr == other.ptr; - } - - bool operator==(const void* other) const { - return ptr == other; - } -}; -typedef std::list AppMemoryList; - -// Writes a minidump to the filesystem. These functions do not malloc nor use -// libc functions which may. Thus, it can be used in contexts where the state -// of the heap may be corrupt. -// minidump_path: the path to the file to write to. This is opened O_EXCL and -// fails open fails. -// crashing_process: the pid of the crashing process. This must be trusted. -// blob: a blob of data from the crashing process. See exception_handler.h -// blob_size: the length of |blob|, in bytes -// -// Returns true iff successful. -bool WriteMinidump(const char* minidump_path, pid_t crashing_process, - const void* blob, size_t blob_size); -// Same as above but takes an open file descriptor instead of a path. -bool WriteMinidump(int minidump_fd, pid_t crashing_process, - const void* blob, size_t blob_size); - -// Alternate form of WriteMinidump() that works with processes that -// are not expected to have crashed. If |process_blamed_thread| is -// meaningful, it will be the one from which a crash signature is -// extracted. It is not expected that this function will be called -// from a compromised context, but it is safe to do so. -bool WriteMinidump(const char* minidump_path, pid_t process, - pid_t process_blamed_thread); - -// These overloads also allow passing a list of known mappings and -// a list of additional memory regions to be included in the minidump. -bool WriteMinidump(const char* minidump_path, pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appdata); -bool WriteMinidump(int minidump_fd, pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appdata); - -// These overloads also allow passing a file size limit for the minidump. -bool WriteMinidump(const char* minidump_path, off_t minidump_size_limit, - pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appdata); -bool WriteMinidump(int minidump_fd, off_t minidump_size_limit, - pid_t crashing_process, - const void* blob, size_t blob_size, - const MappingList& mappings, - const AppMemoryList& appdata); - -bool WriteMinidump(const char* filename, - const MappingList& mappings, - const AppMemoryList& appdata, - LinuxDumper* dumper); - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc deleted file mode 100644 index 2e4749e7e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ /dev/null @@ -1,775 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/linux/handler/exception_handler.h" -#include "client/linux/minidump_writer/linux_dumper.h" -#include "client/linux/minidump_writer/minidump_writer.h" -#include "client/linux/minidump_writer/minidump_writer_unittest_utils.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/file_id.h" -#include "common/linux/ignore_ret.h" -#include "common/linux/safe_readlink.h" -#include "common/scoped_ptr.h" -#include "common/tests/auto_tempdir.h" -#include "common/tests/file_utils.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/minidump.h" - -using namespace google_breakpad; - -namespace { - -typedef testing::Test MinidumpWriterTest; - -const char kMDWriterUnitTestFileName[] = "/minidump-writer-unittest"; - -TEST(MinidumpWriterTest, SetupWithPath) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - - AutoTempDir temp_dir; - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - // Set a non-zero tid to avoid tripping asserts. - context.tid = child; - ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context))); - struct stat st; - ASSERT_EQ(0, stat(templ.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - close(fds[1]); -} - -TEST(MinidumpWriterTest, SetupWithFD) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - HANDLE_EINTR(read(fds[0], &b, sizeof(b))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - - AutoTempDir temp_dir; - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - int fd = open(templ.c_str(), O_CREAT | O_WRONLY, S_IRWXU); - // Set a non-zero tid to avoid tripping asserts. - context.tid = child; - ASSERT_TRUE(WriteMinidump(fd, child, &context, sizeof(context))); - struct stat st; - ASSERT_EQ(0, stat(templ.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - close(fds[1]); -} - -// Test that mapping info can be specified when writing a minidump, -// and that it ends up in the module list of the minidump. -TEST(MinidumpWriterTest, MappingInfo) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t memory_size = sysconf(_SC_PAGESIZE); - const char* kMemoryName = "a fake module"; - const uint8_t kModuleGUID[sizeof(MDGUID)] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - }; - const string module_identifier = "33221100554477668899AABBCCDDEEFF0"; - - // Get some memory. - char* memory = - reinterpret_cast(mmap(NULL, - memory_size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - ASSERT_EQ(0, getcontext(&context.context)); - context.tid = child; - - AutoTempDir temp_dir; - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - - // Add information about the mapped memory. - MappingInfo info; - info.start_addr = kMemoryAddress; - info.size = memory_size; - info.offset = 0; - info.exec = false; - strcpy(info.name, kMemoryName); - - MappingList mappings; - AppMemoryList memory_list; - MappingEntry mapping; - mapping.first = info; - memcpy(mapping.second, kModuleGUID, sizeof(MDGUID)); - mappings.push_back(mapping); - ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context), - mappings, memory_list)); - - // Read the minidump. Load the module list, and ensure that - // the mmap'ed |memory| is listed with the given module name - // and debug ID. - Minidump minidump(templ); - ASSERT_TRUE(minidump.Read()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* module = - module_list->GetModuleForAddress(kMemoryAddress); - ASSERT_TRUE(module); - - EXPECT_EQ(kMemoryAddress, module->base_address()); - EXPECT_EQ(memory_size, module->size()); - EXPECT_EQ(kMemoryName, module->code_file()); - EXPECT_EQ(module_identifier, module->debug_identifier()); - - uint32_t len; - // These streams are expected to be there - EXPECT_TRUE(minidump.SeekToStreamType(MD_THREAD_LIST_STREAM, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_MEMORY_LIST_STREAM, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_EXCEPTION_STREAM, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_SYSTEM_INFO_STREAM, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_CPU_INFO, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_PROC_STATUS, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_CMD_LINE, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_ENVIRON, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_AUXV, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_MAPS, &len)); - EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_DSO_DEBUG, &len)); - - close(fds[1]); -} - -// Test that a binary with a longer-than-usual build id note -// makes its way all the way through to the minidump unscathed. -// The linux_client_unittest is linked with an explicit --build-id -// in Makefile.am. -TEST(MinidumpWriterTest, BuildIDLong) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - ASSERT_EQ(0, getcontext(&context.context)); - context.tid = child; - - AutoTempDir temp_dir; - const string dump_path = temp_dir.path() + kMDWriterUnitTestFileName; - - EXPECT_TRUE(WriteMinidump(dump_path.c_str(), - child, &context, sizeof(context))); - close(fds[1]); - - // Read the minidump. Load the module list, and ensure that - // the main module has the correct debug id and code id. - Minidump minidump(dump_path); - ASSERT_TRUE(minidump.Read()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* module = module_list->GetMainModule(); - ASSERT_TRUE(module); - const string module_identifier = "030201000504070608090A0B0C0D0E0F0"; - // This is passed explicitly to the linker in Makefile.am - const string build_id = - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; - EXPECT_EQ(module_identifier, module->debug_identifier()); - EXPECT_EQ(build_id, module->code_identifier()); -} - -// Test that mapping info can be specified, and that it overrides -// existing mappings that are wholly contained within the specified -// range. -TEST(MinidumpWriterTest, MappingInfoContained) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const int32_t memory_size = sysconf(_SC_PAGESIZE); - const char* kMemoryName = "a fake module"; - const uint8_t kModuleGUID[sizeof(MDGUID)] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - }; - const string module_identifier = "33221100554477668899AABBCCDDEEFF0"; - - // mmap a file - AutoTempDir temp_dir; - string tempfile = temp_dir.path() + "/minidump-writer-unittest-temp"; - int fd = open(tempfile.c_str(), O_RDWR | O_CREAT, 0); - ASSERT_NE(-1, fd); - unlink(tempfile.c_str()); - // fill with zeros - google_breakpad::scoped_array buffer(new char[memory_size]); - memset(buffer.get(), 0, memory_size); - ASSERT_EQ(memory_size, write(fd, buffer.get(), memory_size)); - lseek(fd, 0, SEEK_SET); - - char* memory = - reinterpret_cast(mmap(NULL, - memory_size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE, - fd, - 0)); - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - close(fd); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - context.tid = 1; - - string dumpfile = temp_dir.path() + kMDWriterUnitTestFileName; - - // Add information about the mapped memory. Report it as being larger than - // it actually is. - MappingInfo info; - info.start_addr = kMemoryAddress - memory_size; - info.size = memory_size * 3; - info.offset = 0; - info.exec = false; - strcpy(info.name, kMemoryName); - - MappingList mappings; - AppMemoryList memory_list; - MappingEntry mapping; - mapping.first = info; - memcpy(mapping.second, kModuleGUID, sizeof(MDGUID)); - mappings.push_back(mapping); - ASSERT_TRUE(WriteMinidump(dumpfile.c_str(), child, &context, sizeof(context), - mappings, memory_list)); - - // Read the minidump. Load the module list, and ensure that - // the mmap'ed |memory| is listed with the given module name - // and debug ID. - Minidump minidump(dumpfile); - ASSERT_TRUE(minidump.Read()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* module = - module_list->GetModuleForAddress(kMemoryAddress); - ASSERT_TRUE(module); - - EXPECT_EQ(info.start_addr, module->base_address()); - EXPECT_EQ(info.size, module->size()); - EXPECT_EQ(kMemoryName, module->code_file()); - EXPECT_EQ(module_identifier, module->debug_identifier()); - - close(fds[1]); -} - -TEST(MinidumpWriterTest, DeletedBinary) { - const string kNumberOfThreadsArgument = "1"; - const string helper_path(GetHelperBinary()); - if (helper_path.empty()) { - FAIL() << "Couldn't find helper binary"; - exit(1); - } - - // Copy binary to a temp file. - AutoTempDir temp_dir; - string binpath = temp_dir.path() + "/linux-dumper-unittest-helper"; - ASSERT_TRUE(CopyFile(helper_path.c_str(), binpath.c_str())) - << "Failed to copy " << helper_path << " to " << binpath; - ASSERT_EQ(0, chmod(binpath.c_str(), 0755)); - - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - pid_t child_pid = fork(); - if (child_pid == 0) { - // In child process. - close(fds[0]); - - // Pass the pipe fd and the number of threads as arguments. - char pipe_fd_string[8]; - sprintf(pipe_fd_string, "%d", fds[1]); - execl(binpath.c_str(), - binpath.c_str(), - pipe_fd_string, - kNumberOfThreadsArgument.c_str(), - NULL); - } - close(fds[1]); - // Wait for the child process to signal that it's ready. - struct pollfd pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = fds[0]; - pfd.events = POLLIN | POLLERR; - - const int r = HANDLE_EINTR(poll(&pfd, 1, 1000)); - ASSERT_EQ(1, r); - ASSERT_TRUE(pfd.revents & POLLIN); - uint8_t junk; - const int nr = HANDLE_EINTR(read(fds[0], &junk, sizeof(junk))); - ASSERT_EQ(static_cast(sizeof(junk)), nr); - close(fds[0]); - - // Child is ready now. - // Unlink the test binary. - unlink(binpath.c_str()); - - ExceptionHandler::CrashContext context; - memset(&context, 0, sizeof(context)); - - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - // Set a non-zero tid to avoid tripping asserts. - context.tid = child_pid; - ASSERT_TRUE(WriteMinidump(templ.c_str(), child_pid, &context, - sizeof(context))); - kill(child_pid, SIGKILL); - - struct stat st; - ASSERT_EQ(0, stat(templ.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - - Minidump minidump(templ); - ASSERT_TRUE(minidump.Read()); - - // Check that the main module filename is correct. - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* module = module_list->GetMainModule(); - EXPECT_STREQ(binpath.c_str(), module->code_file().c_str()); - // Check that the file ID is correct. - FileID fileid(helper_path.c_str()); - PageAllocator allocator; - wasteful_vector identifier(&allocator, kDefaultBuildIdSize); - EXPECT_TRUE(fileid.ElfFileIdentifier(identifier)); - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - string module_identifier(identifier_string); - // Strip out dashes - size_t pos; - while ((pos = module_identifier.find('-')) != string::npos) { - module_identifier.erase(pos, 1); - } - // And append a zero, because module IDs include an "age" field - // which is always zero on Linux. - module_identifier += "0"; - EXPECT_EQ(module_identifier, module->debug_identifier()); -} - -// Test that an additional memory region can be added to the minidump. -TEST(MinidumpWriterTest, AdditionalMemory) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = sysconf(_SC_PAGESIZE); - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - HANDLE_EINTR(read(fds[0], &b, sizeof(b))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - - // This needs a valid context for minidump writing to work, but getting - // a useful one from the child is too much work, so just use one from - // the parent since the child is just a forked copy anyway. - ASSERT_EQ(0, getcontext(&context.context)); - context.tid = child; - - AutoTempDir temp_dir; - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - unlink(templ.c_str()); - - MappingList mappings; - AppMemoryList memory_list; - - // Add the memory region to the list of memory to be included. - AppMemory app_memory; - app_memory.ptr = memory; - app_memory.length = kMemorySize; - memory_list.push_back(app_memory); - ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context), - mappings, memory_list)); - - // Read the minidump. Ensure that the memory region is present - Minidump minidump(templ); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemoryAddress, region->GetBase()); - EXPECT_EQ(kMemorySize, region->GetSize()); - - // Verify memory contents. - EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize)); - - delete[] memory; - close(fds[1]); -} - -// Test that an invalid thread stack pointer still results in a minidump. -TEST(MinidumpWriterTest, InvalidStackPointer) { - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - const pid_t child = fork(); - if (child == 0) { - close(fds[1]); - char b; - HANDLE_EINTR(read(fds[0], &b, sizeof(b))); - close(fds[0]); - syscall(__NR_exit); - } - close(fds[0]); - - ExceptionHandler::CrashContext context; - - // This needs a valid context for minidump writing to work, but getting - // a useful one from the child is too much work, so just use one from - // the parent since the child is just a forked copy anyway. - ASSERT_EQ(0, getcontext(&context.context)); - context.tid = child; - - // Fake the child's stack pointer for its crashing thread. NOTE: This must - // be an invalid memory address for the child process (stack or otherwise). - // Try 1MB below the current stack. - uintptr_t invalid_stack_pointer = - reinterpret_cast(&context) - 1024*1024; -#if defined(__i386) - context.context.uc_mcontext.gregs[REG_ESP] = invalid_stack_pointer; -#elif defined(__x86_64) - context.context.uc_mcontext.gregs[REG_RSP] = invalid_stack_pointer; -#elif defined(__ARM_EABI__) - context.context.uc_mcontext.arm_sp = invalid_stack_pointer; -#elif defined(__aarch64__) - context.context.uc_mcontext.sp = invalid_stack_pointer; -#elif defined(__mips__) - context.context.uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP] = - invalid_stack_pointer; -#else -# error "This code has not been ported to your platform yet." -#endif - - AutoTempDir temp_dir; - string templ = temp_dir.path() + kMDWriterUnitTestFileName; - // NOTE: In previous versions of Breakpad, WriteMinidump() would fail if - // presented with an invalid stack pointer. - ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context))); - - // Read the minidump. Ensure that the memory region is present - Minidump minidump(templ); - ASSERT_TRUE(minidump.Read()); - - // TODO(ted.mielczarek,mkrebs): Enable this part of the test once - // https://breakpad.appspot.com/413002/ is committed. -#if 0 - // Make sure there's a thread without a stack. NOTE: It's okay if - // GetThreadList() shows the error: "ERROR: MinidumpThread has a memory - // region problem". - MinidumpThreadList* dump_thread_list = minidump.GetThreadList(); - ASSERT_TRUE(dump_thread_list); - bool found_empty_stack = false; - for (int i = 0; i < dump_thread_list->thread_count(); i++) { - MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); - // When the stack size is zero bytes, GetMemory() returns NULL. - if (thread->GetMemory() == NULL) { - found_empty_stack = true; - break; - } - } - // NOTE: If you fail this, first make sure that "invalid_stack_pointer" - // above is indeed set to an invalid address. - ASSERT_TRUE(found_empty_stack); -#endif - - close(fds[1]); -} - -// Test that limiting the size of the minidump works. -TEST(MinidumpWriterTest, MinidumpSizeLimit) { - static const int kNumberOfThreadsInHelperProgram = 40; - - char number_of_threads_arg[3]; - sprintf(number_of_threads_arg, "%d", kNumberOfThreadsInHelperProgram); - - string helper_path(GetHelperBinary()); - if (helper_path.empty()) { - FAIL() << "Couldn't find helper binary"; - exit(1); - } - - int fds[2]; - ASSERT_NE(-1, pipe(fds)); - - pid_t child_pid = fork(); - if (child_pid == 0) { - // In child process. - close(fds[0]); - - // Pass the pipe fd and the number of threads as arguments. - char pipe_fd_string[8]; - sprintf(pipe_fd_string, "%d", fds[1]); - execl(helper_path.c_str(), - helper_path.c_str(), - pipe_fd_string, - number_of_threads_arg, - NULL); - } - close(fds[1]); - - // Wait for all child threads to indicate that they have started - for (int threads = 0; threads < kNumberOfThreadsInHelperProgram; threads++) { - struct pollfd pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = fds[0]; - pfd.events = POLLIN | POLLERR; - - const int r = HANDLE_EINTR(poll(&pfd, 1, 1000)); - ASSERT_EQ(1, r); - ASSERT_TRUE(pfd.revents & POLLIN); - uint8_t junk; - ASSERT_EQ(read(fds[0], &junk, sizeof(junk)), - static_cast(sizeof(junk))); - } - close(fds[0]); - - // There is a race here because we may stop a child thread before - // it is actually running the busy loop. Empirically this sleep - // is sufficient to avoid the race. - usleep(100000); - - // Child and its threads are ready now. - - - off_t normal_file_size; - int total_normal_stack_size = 0; - AutoTempDir temp_dir; - - // First, write a minidump with no size limit. - { - string normal_dump = temp_dir.path() + - "/minidump-writer-unittest.dmp"; - ASSERT_TRUE(WriteMinidump(normal_dump.c_str(), -1, - child_pid, NULL, 0, - MappingList(), AppMemoryList())); - struct stat st; - ASSERT_EQ(0, stat(normal_dump.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - normal_file_size = st.st_size; - - Minidump minidump(normal_dump); - ASSERT_TRUE(minidump.Read()); - MinidumpThreadList* dump_thread_list = minidump.GetThreadList(); - ASSERT_TRUE(dump_thread_list); - for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) { - MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); - // When the stack size is zero bytes, GetMemory() returns NULL. - MinidumpMemoryRegion* memory = thread->GetMemory(); - ASSERT_TRUE(memory != NULL); - total_normal_stack_size += memory->GetSize(); - } - } - - // Second, write a minidump with a size limit big enough to not trigger - // anything. - { - // Set size limit arbitrarily 1MB larger than the normal file size -- such - // that the limiting code will not kick in. - const off_t minidump_size_limit = normal_file_size + 1024*1024; - - string same_dump = temp_dir.path() + - "/minidump-writer-unittest-same.dmp"; - ASSERT_TRUE(WriteMinidump(same_dump.c_str(), minidump_size_limit, - child_pid, NULL, 0, - MappingList(), AppMemoryList())); - struct stat st; - ASSERT_EQ(0, stat(same_dump.c_str(), &st)); - // Make sure limiting wasn't actually triggered. NOTE: If you fail this, - // first make sure that "minidump_size_limit" above is indeed set to a - // large enough value -- the limit-checking code in minidump_writer.cc - // does just a rough estimate. - ASSERT_EQ(normal_file_size, st.st_size); - } - - // Third, write a minidump with a size limit small enough to be triggered. - { - // Set size limit to some arbitrary amount, such that the limiting code - // will kick in. The equation used to set this value was determined by - // simply reversing the size-limit logic a little bit in order to pick a - // size we know will trigger it. The definition of - // kLimitAverageThreadStackLength here was copied from class - // MinidumpWriter in minidump_writer.cc. - static const unsigned kLimitAverageThreadStackLength = 8 * 1024; - off_t minidump_size_limit = kNumberOfThreadsInHelperProgram * - kLimitAverageThreadStackLength; - // If, in reality, each of the threads' stack is *smaller* than - // kLimitAverageThreadStackLength, the normal file size could very well be - // smaller than the arbitrary limit that was just set. In that case, - // either of these numbers should trigger the size-limiting code, but we - // might as well pick the smallest. - if (normal_file_size < minidump_size_limit) - minidump_size_limit = normal_file_size; - - string limit_dump = temp_dir.path() + - "/minidump-writer-unittest-limit.dmp"; - ASSERT_TRUE(WriteMinidump(limit_dump.c_str(), minidump_size_limit, - child_pid, NULL, 0, - MappingList(), AppMemoryList())); - struct stat st; - ASSERT_EQ(0, stat(limit_dump.c_str(), &st)); - ASSERT_GT(st.st_size, 0); - // Make sure the file size is at least smaller than the original. If this - // fails because it's the same size, then the size-limit logic didn't kick - // in like it was supposed to. - EXPECT_LT(st.st_size, normal_file_size); - - Minidump minidump(limit_dump); - ASSERT_TRUE(minidump.Read()); - MinidumpThreadList* dump_thread_list = minidump.GetThreadList(); - ASSERT_TRUE(dump_thread_list); - int total_limit_stack_size = 0; - for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) { - MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); - // When the stack size is zero bytes, GetMemory() returns NULL. - MinidumpMemoryRegion* memory = thread->GetMemory(); - ASSERT_TRUE(memory != NULL); - total_limit_stack_size += memory->GetSize(); - } - - // Make sure stack size shrunk by at least 1KB per extra thread. The - // definition of kLimitBaseThreadCount here was copied from class - // MinidumpWriter in minidump_writer.cc. - // Note: The 1KB is arbitrary, and assumes that the thread stacks are big - // enough to shrink by that much. For example, if each thread stack was - // originally only 2KB, the current size-limit logic wouldn't actually - // shrink them because that's the size to which it tries to shrink. If - // you fail this part of the test due to something like that, the test - // logic should probably be improved to account for your situation. - const unsigned kLimitBaseThreadCount = 20; - const unsigned kMinPerExtraThreadStackReduction = 1024; - const int min_expected_reduction = (kNumberOfThreadsInHelperProgram - - kLimitBaseThreadCount) * kMinPerExtraThreadStackReduction; - EXPECT_LT(total_limit_stack_size, - total_normal_stack_size - min_expected_reduction); - } - - // Kill the helper program. - kill(child_pid, SIGKILL); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc deleted file mode 100644 index 9f46fa65c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_writer_unittest_utils.cc: -// Shared routines used by unittests under client/linux/minidump_writer. - -#include -#include - -#include "client/linux/minidump_writer/minidump_writer_unittest_utils.h" -#include "common/linux/safe_readlink.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -string GetHelperBinary() { - string helper_path; - char *bindir = getenv("bindir"); - if (bindir) { - helper_path = string(bindir) + "/"; - } else { - // Locate helper binary next to the current binary. - char self_path[PATH_MAX]; - if (!SafeReadLink("/proc/self/exe", self_path)) { - return ""; - } - helper_path = string(self_path); - size_t pos = helper_path.rfind('/'); - if (pos == string::npos) { - return ""; - } - helper_path.erase(pos + 1); - } - - helper_path += "linux_dumper_unittest_helper"; - - return helper_path; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.h deleted file mode 100644 index f16cc086b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer_unittest_utils.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_writer_unittest_utils.h: -// Shared routines used by unittests under client/linux/minidump_writer. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_UNITTEST_UTILS_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_UNITTEST_UTILS_H_ - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -// Returns the full path to linux_dumper_unittest_helper. The full path is -// discovered either by using the environment variable "bindir" or by using -// the location of the main module of the currently running process. -string GetHelperBinary(); - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_UNITTEST_UTILS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader.h deleted file mode 100644 index d9461bf30..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_ -#define CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_ - -#include -#include -#include - -#include "client/linux/minidump_writer/line_reader.h" -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -// A class for reading /proc/cpuinfo without using fopen/fgets or other -// functions which may allocate memory. -class ProcCpuInfoReader { -public: - ProcCpuInfoReader(int fd) - : line_reader_(fd), pop_count_(-1) { - } - - // Return the next field name, or NULL in case of EOF. - // field: (output) Pointer to zero-terminated field name. - // Returns true on success, or false on EOF or error (line too long). - bool GetNextField(const char** field) { - for (;;) { - const char* line; - unsigned line_len; - - // Try to read next line. - if (pop_count_ >= 0) { - line_reader_.PopLine(pop_count_); - pop_count_ = -1; - } - - if (!line_reader_.GetNextLine(&line, &line_len)) - return false; - - pop_count_ = static_cast(line_len); - - const char* line_end = line + line_len; - - // Expected format: + ':' - // Note that: - // - empty lines happen. - // - can contain spaces. - // - some fields have an empty - char* sep = static_cast(my_memchr(line, ':', line_len)); - if (sep == NULL) - continue; - - // Record the value. Skip leading space after the column to get - // its start. - const char* val = sep+1; - while (val < line_end && my_isspace(*val)) - val++; - - value_ = val; - value_len_ = static_cast(line_end - val); - - // Remove trailing spaces before the column to properly 0-terminate - // the field name. - while (sep > line && my_isspace(sep[-1])) - sep--; - - if (sep == line) - continue; - - // zero-terminate field name. - *sep = '\0'; - - *field = line; - return true; - } - } - - // Return the field value. This must be called after a succesful - // call to GetNextField(). - const char* GetValue() { - assert(value_); - return value_; - } - - // Same as GetValue(), but also returns the length in characters of - // the value. - const char* GetValueAndLen(size_t* length) { - assert(value_); - *length = value_len_; - return value_; - } - -private: - LineReader line_reader_; - int pop_count_; - const char* value_; - size_t value_len_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc deleted file mode 100644 index 6037c7e66..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include - -#include "client/linux/minidump_writer/proc_cpuinfo_reader.h" -#include "breakpad_googletest_includes.h" -#include "common/linux/tests/auto_testfile.h" - -using namespace google_breakpad; - -#if !defined(__ANDROID__) -#define TEMPDIR "/tmp" -#else -#define TEMPDIR "/data/local/tmp" -#endif - - -namespace { - -typedef testing::Test ProcCpuInfoReaderTest; - -class ScopedTestFile : public AutoTestFile { -public: - explicit ScopedTestFile(const char* text) - : AutoTestFile("proc_cpuinfo_reader", text) { - } -}; - -} - -TEST(ProcCpuInfoReaderTest, EmptyFile) { - ScopedTestFile file(""); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char *field; - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, OneLineTerminated) { - ScopedTestFile file("foo : bar\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char *field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, OneLine) { - ScopedTestFile file("foo : bar"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char *field; - size_t value_len; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValueAndLen(&value_len)); - ASSERT_EQ(3U, value_len); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, TwoLinesTerminated) { - ScopedTestFile file("foo : bar\nzoo : tut\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("zoo", field); - ASSERT_STREQ("tut", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, SkipMalformedLine) { - ScopedTestFile file("this line should have a column\nfoo : bar\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, SkipOneEmptyLine) { - ScopedTestFile file("\n\nfoo : bar\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, SkipEmptyField) { - ScopedTestFile file(" : bar\nzoo : tut\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("zoo", field); - ASSERT_STREQ("tut", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, SkipTwoEmptyLines) { - ScopedTestFile file("foo : bar\n\n\nfoo : bar\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - ASSERT_STREQ("bar", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, FieldWithSpaces) { - ScopedTestFile file("foo bar : zoo\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo bar", field); - ASSERT_STREQ("zoo", reader.GetValue()); - - ASSERT_FALSE(reader.GetNextField(&field)); -} - -TEST(ProcCpuInfoReaderTest, EmptyValue) { - ScopedTestFile file("foo :\n"); - ASSERT_TRUE(file.IsOk()); - ProcCpuInfoReader reader(file.GetFd()); - - const char* field; - ASSERT_TRUE(reader.GetNextField(&field)); - ASSERT_STREQ("foo", field); - size_t value_len; - ASSERT_STREQ("", reader.GetValueAndLen(&value_len)); - ASSERT_EQ(0U, value_len); - - ASSERT_FALSE(reader.GetNextField(&field)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/moz.build b/toolkit/crashreporter/google-breakpad/src/client/linux/moz.build deleted file mode 100644 index 9bb8bace3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/moz.build +++ /dev/null @@ -1,35 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'crash_generation/crash_generation_client.cc', - 'crash_generation/crash_generation_server.cc', - 'dump_writer_common/thread_info.cc', - 'dump_writer_common/ucontext_reader.cc', - 'handler/exception_handler.cc', - 'handler/minidump_descriptor.cc', - 'log/log.cc', - 'microdump_writer/microdump_writer.cc', - 'minidump_writer/linux_dumper.cc', - 'minidump_writer/linux_ptrace_dumper.cc', - 'minidump_writer/minidump_writer.cc', -] - -if CONFIG['OS_TARGET'] == 'Android': - LOCAL_INCLUDES += [ - '/toolkit/crashreporter/google-breakpad/src/common/android/include', - ] - -# We allow warnings for third-party code that can be updated from upstream. -ALLOW_COMPILER_WARNINGS = True - -FINAL_LIBRARY = 'xul' - -if CONFIG['OS_TARGET'] == 'Android' and CONFIG['CPU_ARCH'] == 'x86': - # The NDK's user.h defines this struct with a different name. - DEFINES['user_fpxregs_struct'] = 'user_fxsr_struct' - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/sender/google_crash_report_sender.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/sender/google_crash_report_sender.cc deleted file mode 100644 index ec6c06e87..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/linux/sender/google_crash_report_sender.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/linux/google_crashdump_uploader.h" -#include "third_party/linux/include/gflags/gflags.h" -#include -#include - -#include "common/using_std_string.h" - -DEFINE_string(crash_server, "https://clients2.google.com/cr", - "The crash server to upload minidumps to."); -DEFINE_string(product_name, "", - "The product name that the minidump corresponds to."); -DEFINE_string(product_version, "", - "The version of the product that produced the minidump."); -DEFINE_string(client_id, "", - "The client GUID"); -DEFINE_string(minidump_path, "", - "The path of the minidump file."); -DEFINE_string(ptime, "", - "The process uptime in milliseconds."); -DEFINE_string(ctime, "", - "The cumulative process uptime in milliseconds."); -DEFINE_string(email, "", - "The user's email address."); -DEFINE_string(comments, "", - "Extra user comments"); -DEFINE_string(proxy_host, "", - "Proxy host"); -DEFINE_string(proxy_userpasswd, "", - "Proxy username/password in user:pass format."); - - -bool CheckForRequiredFlagsOrDie() { - string error_text = ""; - if (FLAGS_product_name.empty()) { - error_text.append("\nProduct name must be specified."); - } - - if (FLAGS_product_version.empty()) { - error_text.append("\nProduct version must be specified."); - } - - if (FLAGS_client_id.empty()) { - error_text.append("\nClient ID must be specified."); - } - - if (FLAGS_minidump_path.empty()) { - error_text.append("\nMinidump pathname must be specified."); - } - - if (!error_text.empty()) { - std::cout << error_text; - return false; - } - return true; -} - -int main(int argc, char *argv[]) { - google::InitGoogleLogging(argv[0]); - google::ParseCommandLineFlags(&argc, &argv, true); - if (!CheckForRequiredFlagsOrDie()) { - return 1; - } - google_breakpad::GoogleCrashdumpUploader g(FLAGS_product_name, - FLAGS_product_version, - FLAGS_client_id, - FLAGS_ptime, - FLAGS_ctime, - FLAGS_email, - FLAGS_comments, - FLAGS_minidump_path, - FLAGS_crash_server, - FLAGS_proxy_host, - FLAGS_proxy_userpasswd); - g.Upload(NULL, NULL, NULL); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Breakpad.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/client/mac/Breakpad.xcodeproj/project.pbxproj deleted file mode 100644 index 1a93ce6dd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Breakpad.xcodeproj/project.pbxproj +++ /dev/null @@ -1,2788 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXAggregateTarget section */ - F94585840F782326009A47BF /* All */ = { - isa = PBXAggregateTarget; - buildConfigurationList = F94585930F78235C009A47BF /* Build configuration list for PBXAggregateTarget "All" */; - buildPhases = ( - ); - dependencies = ( - F94585880F78232B009A47BF /* PBXTargetDependency */, - F945858A0F78232E009A47BF /* PBXTargetDependency */, - F945858C0F782330009A47BF /* PBXTargetDependency */, - F945858E0F782333009A47BF /* PBXTargetDependency */, - F94585900F782336009A47BF /* PBXTargetDependency */, - F93DE3A70F830D1D00608B94 /* PBXTargetDependency */, - F95BB8B3101F94D300AA053B /* PBXTargetDependency */, - F95BB8B5101F94D300AA053B /* PBXTargetDependency */, - F95BB8B7101F94D300AA053B /* PBXTargetDependency */, - 8B31023911F0CF0600FCF3E4 /* PBXTargetDependency */, - 8B31051711F1010E00FCF3E4 /* PBXTargetDependency */, - 8B31051911F1010E00FCF3E4 /* PBXTargetDependency */, - 8B31051B11F1010E00FCF3E4 /* PBXTargetDependency */, - 8B31051D11F1010E00FCF3E4 /* PBXTargetDependency */, - 8B31051F11F1010E00FCF3E4 /* PBXTargetDependency */, - ); - name = All; - productName = All; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 162F64F2161C577500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; }; - 162F64F3161C577500CD68D5 /* arch_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 162F64F1161C577500CD68D5 /* arch_utilities.h */; }; - 162F64F4161C579B00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; }; - 162F64F5161C579B00CD68D5 /* arch_utilities.h in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F1161C577500CD68D5 /* arch_utilities.h */; }; - 163201D61443019E00C4DBF5 /* ConfigFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 163201D41443019E00C4DBF5 /* ConfigFile.h */; }; - 163201D71443019E00C4DBF5 /* ConfigFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 163201D51443019E00C4DBF5 /* ConfigFile.mm */; }; - 163201E31443029300C4DBF5 /* ConfigFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 163201D51443019E00C4DBF5 /* ConfigFile.mm */; }; - 16C7C918147D45AE00776EAD /* BreakpadDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 16C7C917147D45AE00776EAD /* BreakpadDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 16E02DB8147410F0008C604D /* uploader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16E02DB4147410D4008C604D /* uploader.mm */; }; - 1EEEB6231720829E00F7E689 /* simple_string_dictionary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EEEB6211720829E00F7E689 /* simple_string_dictionary.cc */; }; - 1EEEB6241720829E00F7E689 /* simple_string_dictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EEEB6221720829E00F7E689 /* simple_string_dictionary.h */; }; - 1EEEB6271720831E00F7E689 /* BreakpadFramework_Test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F91AF5CF0FD60393009D8BE2 /* BreakpadFramework_Test.mm */; }; - 1EEEB62A1720859200F7E689 /* simple_string_dictionary_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EEEB6251720830600F7E689 /* simple_string_dictionary_unittest.cc */; }; - 1EEEB62B1720868C00F7E689 /* simple_string_dictionary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EEEB6211720829E00F7E689 /* simple_string_dictionary.cc */; }; - 3329D4ED0FA16D820007BBC5 /* Breakpad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3329D4EC0FA16D820007BBC5 /* Breakpad.xib */; }; - 33880C800F9E097100817F82 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33880C7E0F9E097100817F82 /* InfoPlist.strings */; }; - 4084699D0F5D9CF900FDCA37 /* crash_report_sender.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4084699C0F5D9CF900FDCA37 /* crash_report_sender.icns */; }; - 4D61A25F14F43CFC002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D61A26B14F43D3C002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D61A26C14F43D42002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D61A26D14F43D43002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D61A26E14F43D45002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D61A26F14F43D48002D5862 /* bootstrap_compat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */; }; - 4D72CA0E13DFAD5C006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA0D13DFAD5C006CABE3 /* md5.cc */; }; - 4D72CA2513DFAE1C006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA0D13DFAD5C006CABE3 /* md5.cc */; }; - 4D72CA2F13DFAE65006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA0D13DFAD5C006CABE3 /* md5.cc */; }; - 4D72CA3813DFAE91006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA0D13DFAD5C006CABE3 /* md5.cc */; }; - 4D72CA3913DFAE92006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA0D13DFAD5C006CABE3 /* md5.cc */; }; - 4DBE49A6134A4F200072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; }; - 4DBE49A7134A4F280072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; }; - 4DBE49A8134A4F380072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; }; - 4DBE49A9134A4F460072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; }; - 8B3101C611F0CD9F00FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; }; - 8B3101C711F0CD9F00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8B3101CA11F0CDB000FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; }; - 8B3101CB11F0CDB000FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8B3101EA11F0CDE300FCF3E4 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B3101E911F0CDE300FCF3E4 /* SenTestingKit.framework */; }; - 8B31029411F0D54300FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8B3102E611F0D74C00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8B3102EB11F0D78000FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8B31FC8211EFD2B800FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; - D23F4B2E12A7E13200686C8D /* minidump_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D23F4B2C12A7E13200686C8D /* minidump_generator_test.cc */; }; - D23F4B3312A7E17700686C8D /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F9A41512131EF0002747C1 /* libgtest.a */; }; - D23F4BB112A868CB00686C8D /* minidump_generator_test_helper.cc in Sources */ = {isa = PBXBuildFile; fileRef = D23F4B9A12A8688800686C8D /* minidump_generator_test_helper.cc */; }; - D23F4BB812A868F700686C8D /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; }; - D244536A12426F00009BBCE0 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535112426EBB009BBCE0 /* logging.cc */; }; - D244536B12426F00009BBCE0 /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535212426EBB009BBCE0 /* minidump.cc */; }; - D244536C12426F00009BBCE0 /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535312426EBB009BBCE0 /* pathname_stripper.cc */; }; - D244536D12426F00009BBCE0 /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244534F12426E98009BBCE0 /* basic_code_modules.cc */; }; - D244540B12439BA0009BBCE0 /* memory_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244540A12439BA0009BBCE0 /* memory_unittest.cc */; }; - D246417012BAA40E005170D0 /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; }; - D246417112BAA41C005170D0 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; }; - D246417512BAA438005170D0 /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; }; - D246417612BAA43F005170D0 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; }; - D246417712BAA444005170D0 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; }; - D246418412BAA4BA005170D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - D246418812BAA4E3005170D0 /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; }; - D246418C12BAA508005170D0 /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - D246419012BAA52A005170D0 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - D246419112BAA52F005170D0 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - D246419512BAA54C005170D0 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; }; - D246419612BAA55A005170D0 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; }; - D24641A012BAA67F005170D0 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; }; - D24641AF12BAA82D005170D0 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; }; - D24641EC12BAC6FB005170D0 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535112426EBB009BBCE0 /* logging.cc */; }; - D24641ED12BAC6FB005170D0 /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535212426EBB009BBCE0 /* minidump.cc */; }; - D24641EE12BAC6FB005170D0 /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535312426EBB009BBCE0 /* pathname_stripper.cc */; }; - D24641EF12BAC6FB005170D0 /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244534F12426E98009BBCE0 /* basic_code_modules.cc */; }; - D24BBBFD121050F000F3D417 /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; }; - D24BBD291211EDB100F3D417 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; }; - D24BBD321212CACF00F3D417 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; }; - D2A5DD301188633800081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; }; - D2A5DD401188640400081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; }; - D2A5DD411188642E00081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; }; - D2C1DBE412AFC270006917BD /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535112426EBB009BBCE0 /* logging.cc */; }; - D2C1DBE512AFC270006917BD /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535212426EBB009BBCE0 /* minidump.cc */; }; - D2C1DBE612AFC270006917BD /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244535312426EBB009BBCE0 /* pathname_stripper.cc */; }; - D2C1DBE712AFC270006917BD /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = D244534F12426E98009BBCE0 /* basic_code_modules.cc */; }; - D2F9A3D51212F87C002747C1 /* exception_handler_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A3D41212F87C002747C1 /* exception_handler_test.cc */; }; - D2F9A43D12131F55002747C1 /* gmock-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A43C12131F55002747C1 /* gmock-all.cc */; }; - D2F9A44012131F65002747C1 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A43E12131F65002747C1 /* gtest_main.cc */; }; - D2F9A44112131F65002747C1 /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A43F12131F65002747C1 /* gtest-all.cc */; }; - D2F9A44412131F84002747C1 /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F9A41512131EF0002747C1 /* libgtest.a */; }; - D2F9A4C9121336C7002747C1 /* client_info.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C4121336C7002747C1 /* client_info.h */; }; - D2F9A4CA121336C7002747C1 /* crash_generation_client.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C5121336C7002747C1 /* crash_generation_client.h */; }; - D2F9A4CB121336C7002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; }; - D2F9A4CC121336C7002747C1 /* crash_generation_server.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C7121336C7002747C1 /* crash_generation_server.h */; }; - D2F9A4CD121336C7002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; }; - D2F9A4DF12133AD9002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; }; - D2F9A4E012133AD9002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; }; - D2F9A4E112133AE2002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; }; - D2F9A4E212133AE2002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; }; - D2F9A52E121383A1002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; }; - D2F9A52F121383A1002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; }; - D2F9A530121383A1002747C1 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; }; - D2F9A531121383A1002747C1 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; }; - D2F9A532121383A1002747C1 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; }; - D2F9A533121383A1002747C1 /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; }; - D2F9A534121383A1002747C1 /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; }; - D2F9A535121383A1002747C1 /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - D2F9A536121383A1002747C1 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - D2F9A537121383A1002747C1 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - D2F9A538121383A1002747C1 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; }; - D2F9A539121383A1002747C1 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; }; - D2F9A53A121383A1002747C1 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; }; - D2F9A53B121383A1002747C1 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; }; - D2F9A53C121383A1002747C1 /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; }; - D2F9A53F121383A1002747C1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - D2F9A541121383A1002747C1 /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F9A41512131EF0002747C1 /* libgtest.a */; }; - D2F9A553121383DC002747C1 /* crash_generation_server_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */; }; - F4DAB1DD19F1027100A5A838 /* launch_reporter.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4DAB1DB19F1027100A5A838 /* launch_reporter.cc */; }; - F4DAB1DE19F1027100A5A838 /* launch_reporter.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DAB1DC19F1027100A5A838 /* launch_reporter.h */; }; - F4F916B619F10FFC00B83BE4 /* launch_reporter.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4DAB1DB19F1027100A5A838 /* launch_reporter.cc */; }; - F91AF6210FD60784009D8BE2 /* Breakpad.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; }; - F9286B3A0F7EB25800A4DCC8 /* InspectorMain.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9286B390F7EB25800A4DCC8 /* InspectorMain.mm */; }; - F92C53B80ECCE7B3009BE4BA /* Inspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53B70ECCE7B3009BE4BA /* Inspector.mm */; }; - F92C554C0ECCF534009BE4BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; - F92C55D00ECD0064009BE4BA /* Breakpad.h in Headers */ = {isa = PBXBuildFile; fileRef = F92C55CE0ECD0064009BE4BA /* Breakpad.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F92C55D10ECD0064009BE4BA /* Breakpad.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C55CF0ECD0064009BE4BA /* Breakpad.mm */; }; - F92C56330ECD0DF1009BE4BA /* OnDemandServer.h in Headers */ = {isa = PBXBuildFile; fileRef = F92C56310ECD0DF1009BE4BA /* OnDemandServer.h */; }; - F92C56340ECD0DF1009BE4BA /* OnDemandServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C56320ECD0DF1009BE4BA /* OnDemandServer.mm */; }; - F92C563F0ECD10CA009BE4BA /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - F92C56400ECD10CA009BE4BA /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; }; - F92C56410ECD10CA009BE4BA /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; }; - F92C56420ECD10CA009BE4BA /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; }; - F92C56430ECD10CA009BE4BA /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; }; - F92C56440ECD10CA009BE4BA /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; }; - F92C56450ECD10CA009BE4BA /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; }; - F92C56460ECD10CA009BE4BA /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - F92C56470ECD10CA009BE4BA /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; }; - F92C56490ECD10CA009BE4BA /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; }; - F92C564A0ECD10CA009BE4BA /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - F92C564C0ECD10DD009BE4BA /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; }; - F92C56570ECD113E009BE4BA /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C554A0ECCF530009BE4BA /* Carbon.framework */; }; - F92C565C0ECD1158009BE4BA /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; }; - F92C565F0ECD116B009BE4BA /* protected_memory_allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53720ECCE3FD009BE4BA /* protected_memory_allocator.cc */; }; - F92C56630ECD1179009BE4BA /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; }; - F92C56650ECD1185009BE4BA /* breakpadUtilities.dylib in Resources */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; }; - F92C568A0ECD15F9009BE4BA /* Inspector in Resources */ = {isa = PBXBuildFile; fileRef = F92C53540ECCE349009BE4BA /* Inspector */; }; - F92C56A90ECE04C5009BE4BA /* crash_report_sender.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C56A80ECE04C5009BE4BA /* crash_report_sender.m */; }; - F93803CD0F8083B7004D428B /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; }; - F93803CE0F8083B7004D428B /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; }; - F93803CF0F8083B7004D428B /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; }; - F93803D00F8083B7004D428B /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - F93803D10F8083B7004D428B /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - F93803D20F8083B7004D428B /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - F93803D30F8083B7004D428B /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; }; - F93803D40F8083B7004D428B /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; }; - F93803D50F8083B7004D428B /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; }; - F93803D60F8083B7004D428B /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; }; - F93803D70F8083B7004D428B /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; }; - F93DE2D80F82A70E00608B94 /* minidump_file_writer_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = F93DE2D70F82A70E00608B94 /* minidump_file_writer_unittest.cc */; }; - F93DE2D90F82A73500608B94 /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - F93DE2DA0F82A73500608B94 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - F93DE2DB0F82A73500608B94 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - F93DE3350F82C66B00608B94 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; }; - F93DE3360F82C66B00608B94 /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; }; - F93DE3370F82C66B00608B94 /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; }; - F93DE3380F82C66B00608B94 /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; }; - F93DE3390F82C66B00608B94 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; }; - F93DE33A0F82C66B00608B94 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; }; - F93DE33B0F82C66B00608B94 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; }; - F93DE33C0F82C66B00608B94 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; }; - F93DE33D0F82C66B00608B94 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; }; - F93DE33E0F82C66B00608B94 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; }; - F93DE33F0F82C66B00608B94 /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; }; - F945849E0F280E3C009A47BF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F945849C0F280E3C009A47BF /* Localizable.strings */; }; - F9B630A0100FF96B00D0F4AC /* goArrow.png in Resources */ = {isa = PBXBuildFile; fileRef = F9B6309F100FF96B00D0F4AC /* goArrow.png */; }; - F9C44DB20EF07288003AEBAA /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C44DAC0EF07288003AEBAA /* Controller.m */; }; - F9C44DB30EF07288003AEBAA /* crashduringload in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DAD0EF07288003AEBAA /* crashduringload */; }; - F9C44DB40EF07288003AEBAA /* crashInMain in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DAE0EF07288003AEBAA /* crashInMain */; }; - F9C44DB60EF07288003AEBAA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C44DB00EF07288003AEBAA /* main.m */; }; - F9C44DB70EF07288003AEBAA /* TestClass.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9C44DB10EF07288003AEBAA /* TestClass.mm */; }; - F9C44DBC0EF072A0003AEBAA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DB80EF072A0003AEBAA /* InfoPlist.strings */; }; - F9C44DBD0EF072A0003AEBAA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DBA0EF072A0003AEBAA /* MainMenu.xib */; }; - F9C44E000EF077CD003AEBAA /* Breakpad.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; }; - F9C44E3C0EF08B12003AEBAA /* Breakpad.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; }; - F9C44E980EF09F56003AEBAA /* crash_report_sender.app in Resources */ = {isa = PBXBuildFile; fileRef = F92C56A00ECE04A7009BE4BA /* crash_report_sender.app */; }; - F9C44EA20EF09F93003AEBAA /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C53770ECCE635009BE4BA /* HTTPMultipartUpload.m */; }; - F9C44EE50EF0A006003AEBAA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C44EE40EF0A006003AEBAA /* SystemConfiguration.framework */; }; - F9C44EE90EF0A3C1003AEBAA /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C44EE80EF0A3C1003AEBAA /* GTMLogger.m */; }; - F9C77E130F7DDF810045F7DB /* GTMSenTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C77E120F7DDF810045F7DB /* GTMSenTestCase.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 8B31023811F0CF0600FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = B88FAFC9116BDCAD00407530; - remoteInfo = all_unittests; - }; - 8B31051611F1010E00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F93803BD0F80820F004D428B; - remoteInfo = generator_test; - }; - 8B31051811F1010E00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F93DE2D00F82A67300608B94; - remoteInfo = minidump_file_writer_unittest; - }; - 8B31051A11F1010E00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F93DE32B0F82C55600608B94; - remoteInfo = handler_test; - }; - 8B31051C11F1010E00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = B89E0E731166575200DD08C9; - remoteInfo = macho_dump; - }; - 8B31051E11F1010E00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB894101F94C000AA053B /* symupload.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 9BD835FA0B0544950055103E; - remoteInfo = minidump_upload; - }; - 8B31F7A011EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B89E0E741166575200DD08C9; - remoteInfo = macho_dump; - }; - 8B31F7A211EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB024116BDFFF00407530; - remoteInfo = gtestmockall; - }; - 8B31F7A411EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB14B116CF4A700407530; - remoteInfo = byte_cursor_unittest; - }; - 8B31F7A611EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B89E0E9511665A6400DD08C9; - remoteInfo = macho_reader_unittest; - }; - 8B31F7A811EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB007116BDE8300407530; - remoteInfo = stabs_reader_unittest; - }; - 8B31F7AA11EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB135116CF30F00407530; - remoteInfo = bytereader_unittest; - }; - 8B31F7AC11EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FAF2F116A591E00407530; - remoteInfo = dwarf2reader_cfi_unittest; - }; - 8B31F7AE11EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB0DF116CEEA800407530; - remoteInfo = dwarf2diehandler_unittest; - }; - 8B31F7B011EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB10A116CF07900407530; - remoteInfo = dwarf_cu_to_module_unittest; - }; - 8B31F7B211EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB0F2116CEF1900407530; - remoteInfo = dwarf_line_to_module_unittest; - }; - 8B31F7B411EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB11F116CF27F00407530; - remoteInfo = dwarf_cfi_to_module_unittest; - }; - 8B31F7B611EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B84A91F4116CF784006C210E; - remoteInfo = stabs_to_module_unittest; - }; - 8B31F7B811EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B88FB0B9116CEABF00407530; - remoteInfo = module_unittest; - }; - 8B31F7BA11EF9A8700FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = D21F97D211CBA0F200239E38; - remoteInfo = test_assembler_unittest; - }; - D23F4B2F12A7E16200686C8D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2F9A41412131EF0002747C1; - remoteInfo = gtest; - }; - D23F4BB912A8694C00686C8D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D23F4BAA12A868A500686C8D; - remoteInfo = minidump_generator_test_helper; - }; - D2F9A44212131F80002747C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2F9A41412131EF0002747C1; - remoteInfo = gtest; - }; - D2F9A52C121383A1002747C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2F9A41412131EF0002747C1; - remoteInfo = gtest; - }; - D2F9A5DE12142A6A002747C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2F9A52A121383A1002747C1; - remoteInfo = crash_generation_server_test; - }; - F91AF6370FD60A74009D8BE2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8DC2EF4F0486A6940098B216; - remoteInfo = Breakpad; - }; - F92C564D0ECD10E5009BE4BA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C563B0ECD10B3009BE4BA; - remoteInfo = breakpadUtilities; - }; - F92C56850ECD15EF009BE4BA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C563B0ECD10B3009BE4BA; - remoteInfo = breakpadUtilities; - }; - F92C56870ECD15F1009BE4BA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C53530ECCE349009BE4BA; - remoteInfo = Inspector; - }; - F93DE2FB0F82C3C600608B94 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F93803BD0F80820F004D428B; - remoteInfo = generator_test; - }; - F93DE36F0F82CC1300608B94 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F93DE32B0F82C55600608B94; - remoteInfo = handler_test; - }; - F93DE3A60F830D1D00608B94 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F9C77DD90F7DD5CF0045F7DB; - remoteInfo = UnitTests; - }; - F94585870F78232B009A47BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8DC2EF4F0486A6940098B216; - remoteInfo = Breakpad; - }; - F94585890F78232E009A47BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C53530ECCE349009BE4BA; - remoteInfo = Inspector; - }; - F945858B0F782330009A47BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C563B0ECD10B3009BE4BA; - remoteInfo = breakpadUtilities; - }; - F945858D0F782333009A47BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C569F0ECE04A7009BE4BA; - remoteInfo = crash_report_sender; - }; - F945858F0F782336009A47BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F9C44DA40EF060A8003AEBAA; - remoteInfo = BreakpadTest; - }; - F95BB884101F949F00AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB87C101F949F00AA053B /* crash_report.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8DD76FA10486AA7600D96B5E; - remoteInfo = crash_report; - }; - F95BB891101F94AC00AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8DD76FA10486AA7600D96B5E; - remoteInfo = dump_syms; - }; - F95BB89E101F94C000AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB894101F94C000AA053B /* symupload.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8DD76FA10486AA7600D96B5E; - remoteInfo = symupload; - }; - F95BB8A0101F94C000AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB894101F94C000AA053B /* symupload.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9BD835FB0B0544950055103E; - remoteInfo = minidump_upload; - }; - F95BB8B2101F94D300AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = B8C5B5101166531A00D34F4E; - remoteInfo = dump_syms; - }; - F95BB8B4101F94D300AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB894101F94C000AA053B /* symupload.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8DD76F960486AA7600D96B5E; - remoteInfo = symupload; - }; - F95BB8B6101F94D300AA053B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F95BB87C101F949F00AA053B /* crash_report.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8DD76F960486AA7600D96B5E; - remoteInfo = crash_report; - }; - F9C44E190EF0790F003AEBAA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8DC2EF4F0486A6940098B216; - remoteInfo = Breakpad; - }; - F9C44E960EF09F4B003AEBAA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F92C569F0ECE04A7009BE4BA; - remoteInfo = crash_report_sender; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - F9C44E410EF08B17003AEBAA /* Copy Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - F9C44E3C0EF08B12003AEBAA /* Breakpad.framework in Copy Frameworks */, - ); - name = "Copy Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; - 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 162F64F0161C577500CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../common/mac/arch_utilities.cc; sourceTree = ""; }; - 162F64F1161C577500CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../common/mac/arch_utilities.h; sourceTree = ""; }; - 163201D41443019E00C4DBF5 /* ConfigFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConfigFile.h; path = crash_generation/ConfigFile.h; sourceTree = ""; }; - 163201D51443019E00C4DBF5 /* ConfigFile.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = ConfigFile.mm; path = crash_generation/ConfigFile.mm; sourceTree = ""; }; - 163202431443201300C4DBF5 /* uploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = uploader.h; path = sender/uploader.h; sourceTree = ""; }; - 16C7C917147D45AE00776EAD /* BreakpadDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakpadDefines.h; sourceTree = ""; }; - 16E02DB4147410D4008C604D /* uploader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = uploader.mm; path = sender/uploader.mm; sourceTree = ""; }; - 1EEEB6211720829E00F7E689 /* simple_string_dictionary.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = simple_string_dictionary.cc; path = ../../common/simple_string_dictionary.cc; sourceTree = ""; }; - 1EEEB6221720829E00F7E689 /* simple_string_dictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = simple_string_dictionary.h; path = ../../common/simple_string_dictionary.h; sourceTree = ""; }; - 1EEEB6251720830600F7E689 /* simple_string_dictionary_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = simple_string_dictionary_unittest.cc; path = ../../common/simple_string_dictionary_unittest.cc; sourceTree = ""; }; - 32DBCF5E0370ADEE00C91783 /* Breakpad_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Breakpad_Prefix.pch; path = Framework/Breakpad_Prefix.pch; sourceTree = ""; }; - 3329D4EC0FA16D820007BBC5 /* Breakpad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Breakpad.xib; path = sender/Breakpad.xib; sourceTree = ""; }; - 33880C7F0F9E097100817F82 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = sender/English.lproj/InfoPlist.strings; sourceTree = ""; }; - 4084699C0F5D9CF900FDCA37 /* crash_report_sender.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = crash_report_sender.icns; path = sender/crash_report_sender.icns; sourceTree = ""; }; - 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bootstrap_compat.cc; path = ../../common/mac/bootstrap_compat.cc; sourceTree = SOURCE_ROOT; }; - 4D61A25E14F43CFC002D5862 /* bootstrap_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bootstrap_compat.h; path = ../../common/mac/bootstrap_compat.h; sourceTree = SOURCE_ROOT; }; - 4D72CA0D13DFAD5C006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../common/md5.cc; sourceTree = SOURCE_ROOT; }; - 4DBE4769134A4F080072546A /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; - 8B31007011F0CD3C00FCF3E4 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMDefines.h; path = ../../common/mac/GTMDefines.h; sourceTree = SOURCE_ROOT; }; - 8B3101E911F0CDE300FCF3E4 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; - 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B31FFF611F0C90500FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; - 8DC2EF5B0486A6940098B216 /* Breakpad.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Breakpad.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D23F4B2C12A7E13200686C8D /* minidump_generator_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_generator_test.cc; path = tests/minidump_generator_test.cc; sourceTree = ""; }; - D23F4B9A12A8688800686C8D /* minidump_generator_test_helper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_generator_test_helper.cc; path = tests/minidump_generator_test_helper.cc; sourceTree = ""; }; - D23F4BAB12A868A500686C8D /* minidump_generator_test_helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_generator_test_helper; sourceTree = BUILT_PRODUCTS_DIR; }; - D244534F12426E98009BBCE0 /* basic_code_modules.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basic_code_modules.cc; path = ../../processor/basic_code_modules.cc; sourceTree = SOURCE_ROOT; }; - D244535112426EBB009BBCE0 /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logging.cc; path = ../../processor/logging.cc; sourceTree = SOURCE_ROOT; }; - D244535212426EBB009BBCE0 /* minidump.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump.cc; path = ../../processor/minidump.cc; sourceTree = SOURCE_ROOT; }; - D244535312426EBB009BBCE0 /* pathname_stripper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pathname_stripper.cc; path = ../../processor/pathname_stripper.cc; sourceTree = SOURCE_ROOT; }; - D244540A12439BA0009BBCE0 /* memory_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory_unittest.cc; path = ../../common/memory_unittest.cc; sourceTree = SOURCE_ROOT; }; - D2F9A3D41212F87C002747C1 /* exception_handler_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exception_handler_test.cc; path = tests/exception_handler_test.cc; sourceTree = ""; }; - D2F9A41512131EF0002747C1 /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D2F9A43C12131F55002747C1 /* gmock-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gmock-all.cc"; path = "../../testing/src/gmock-all.cc"; sourceTree = SOURCE_ROOT; }; - D2F9A43E12131F65002747C1 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gtest_main.cc; path = ../../testing/gtest/src/gtest_main.cc; sourceTree = ""; }; - D2F9A43F12131F65002747C1 /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gtest-all.cc"; path = "../../testing/gtest/src/gtest-all.cc"; sourceTree = ""; }; - D2F9A4C4121336C7002747C1 /* client_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = client_info.h; path = crash_generation/client_info.h; sourceTree = ""; }; - D2F9A4C5121336C7002747C1 /* crash_generation_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crash_generation_client.h; path = crash_generation/crash_generation_client.h; sourceTree = ""; }; - D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_client.cc; path = crash_generation/crash_generation_client.cc; sourceTree = ""; }; - D2F9A4C7121336C7002747C1 /* crash_generation_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crash_generation_server.h; path = crash_generation/crash_generation_server.h; sourceTree = ""; }; - D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_server.cc; path = crash_generation/crash_generation_server.cc; sourceTree = ""; }; - D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_server_test.cc; path = tests/crash_generation_server_test.cc; sourceTree = ""; }; - D2F9A546121383A1002747C1 /* crash_generation_server_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = crash_generation_server_test; sourceTree = BUILT_PRODUCTS_DIR; }; - DE43467411C72855004F095F /* da */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = da; path = sender/da.lproj/Localizable.strings; sourceTree = ""; }; - DE43467511C72857004F095F /* de */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = de; path = sender/de.lproj/Localizable.strings; sourceTree = ""; }; - DE43467611C7285B004F095F /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = sender/es.lproj/Localizable.strings; sourceTree = ""; }; - DE43467711C72862004F095F /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = sender/fr.lproj/Localizable.strings; sourceTree = ""; }; - DE43467811C72869004F095F /* it */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = it; path = sender/it.lproj/Localizable.strings; sourceTree = ""; }; - DE43467911C7286D004F095F /* nl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = nl; path = sender/nl.lproj/Localizable.strings; sourceTree = ""; }; - DE43467A11C72873004F095F /* no */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = no; path = sender/no.lproj/Localizable.strings; sourceTree = ""; }; - DE43467B11C72877004F095F /* sl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sl; path = sender/sl.lproj/Localizable.strings; sourceTree = ""; }; - DE43467C11C7287A004F095F /* sv */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sv; path = sender/sv.lproj/Localizable.strings; sourceTree = ""; }; - DE43467E11C728DC004F095F /* ja */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ja; path = sender/ja.lproj/Localizable.strings; sourceTree = ""; }; - DE43467F11C728E1004F095F /* tr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = tr; path = sender/tr.lproj/Localizable.strings; sourceTree = ""; }; - DE43468611C72958004F095F /* de */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = de; path = sender/de.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468711C7295D004F095F /* da */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = da; path = sender/da.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468811C7295F004F095F /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = sender/es.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468911C72964004F095F /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = sender/fr.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468A11C72967004F095F /* it */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = it; path = sender/it.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468B11C7296B004F095F /* ja */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ja; path = sender/ja.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468C11C7296D004F095F /* nl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = nl; path = sender/nl.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468D11C7296F004F095F /* no */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = no; path = sender/no.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468E11C72971004F095F /* sl */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sl; path = sender/sl.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43468F11C72973004F095F /* sv */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sv; path = sender/sv.lproj/InfoPlist.strings; sourceTree = ""; }; - DE43469011C72976004F095F /* tr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = tr; path = sender/tr.lproj/InfoPlist.strings; sourceTree = ""; }; - F4DAB1DB19F1027100A5A838 /* launch_reporter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = launch_reporter.cc; path = ../../common/mac/launch_reporter.cc; sourceTree = SOURCE_ROOT; }; - F4DAB1DC19F1027100A5A838 /* launch_reporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = launch_reporter.h; path = ../../common/mac/launch_reporter.h; sourceTree = SOURCE_ROOT; }; - F91AF5CF0FD60393009D8BE2 /* BreakpadFramework_Test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = BreakpadFramework_Test.mm; path = tests/BreakpadFramework_Test.mm; sourceTree = ""; }; - F9286B380F7EB25800A4DCC8 /* Inspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Inspector.h; path = crash_generation/Inspector.h; sourceTree = ""; }; - F9286B390F7EB25800A4DCC8 /* InspectorMain.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InspectorMain.mm; path = crash_generation/InspectorMain.mm; sourceTree = ""; }; - F92C53540ECCE349009BE4BA /* Inspector */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Inspector; sourceTree = BUILT_PRODUCTS_DIR; }; - F92C53670ECCE3FD009BE4BA /* breakpad_exc_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = breakpad_exc_server.c; path = handler/breakpad_exc_server.c; sourceTree = SOURCE_ROOT; }; - F92C53680ECCE3FD009BE4BA /* breakpad_exc_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = breakpad_exc_server.h; path = handler/breakpad_exc_server.h; sourceTree = SOURCE_ROOT; }; - F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = breakpad_nlist_64.cc; path = handler/breakpad_nlist_64.cc; sourceTree = SOURCE_ROOT; }; - F92C536A0ECCE3FD009BE4BA /* breakpad_nlist_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = breakpad_nlist_64.h; path = handler/breakpad_nlist_64.h; sourceTree = SOURCE_ROOT; }; - F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dynamic_images.cc; path = handler/dynamic_images.cc; sourceTree = SOURCE_ROOT; }; - F92C536C0ECCE3FD009BE4BA /* dynamic_images.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic_images.h; path = handler/dynamic_images.h; sourceTree = SOURCE_ROOT; }; - F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exception_handler.cc; path = handler/exception_handler.cc; sourceTree = SOURCE_ROOT; }; - F92C536E0ECCE3FD009BE4BA /* exception_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exception_handler.h; path = handler/exception_handler.h; sourceTree = SOURCE_ROOT; }; - F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_generator.cc; path = handler/minidump_generator.cc; sourceTree = SOURCE_ROOT; }; - F92C53700ECCE3FD009BE4BA /* minidump_generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = minidump_generator.h; path = handler/minidump_generator.h; sourceTree = SOURCE_ROOT; }; - F92C53720ECCE3FD009BE4BA /* protected_memory_allocator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = protected_memory_allocator.cc; path = handler/protected_memory_allocator.cc; sourceTree = SOURCE_ROOT; }; - F92C53730ECCE3FD009BE4BA /* protected_memory_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = protected_memory_allocator.h; path = handler/protected_memory_allocator.h; sourceTree = SOURCE_ROOT; }; - F92C53740ECCE635009BE4BA /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; }; - F92C53750ECCE635009BE4BA /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; }; - F92C53760ECCE635009BE4BA /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPMultipartUpload.h; path = ../../common/mac/HTTPMultipartUpload.h; sourceTree = SOURCE_ROOT; }; - F92C53770ECCE635009BE4BA /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPMultipartUpload.m; path = ../../common/mac/HTTPMultipartUpload.m; sourceTree = SOURCE_ROOT; }; - F92C53780ECCE635009BE4BA /* MachIPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MachIPC.h; path = ../../common/mac/MachIPC.h; sourceTree = SOURCE_ROOT; }; - F92C53790ECCE635009BE4BA /* MachIPC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MachIPC.mm; path = ../../common/mac/MachIPC.mm; sourceTree = SOURCE_ROOT; }; - F92C537A0ECCE635009BE4BA /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; }; - F92C537B0ECCE635009BE4BA /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; - F92C537C0ECCE635009BE4BA /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; }; - F92C537D0ECCE635009BE4BA /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; }; - F92C537E0ECCE635009BE4BA /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; - F92C537F0ECCE635009BE4BA /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; - F92C53820ECCE635009BE4BA /* string_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = string_utilities.cc; path = ../../common/mac/string_utilities.cc; sourceTree = SOURCE_ROOT; }; - F92C53830ECCE635009BE4BA /* string_utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = string_utilities.h; path = ../../common/mac/string_utilities.h; sourceTree = SOURCE_ROOT; }; - F92C53850ECCE6AD009BE4BA /* string_conversion.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = string_conversion.cc; path = ../../common/string_conversion.cc; sourceTree = SOURCE_ROOT; }; - F92C53860ECCE6AD009BE4BA /* string_conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = string_conversion.h; path = ../../common/string_conversion.h; sourceTree = SOURCE_ROOT; }; - F92C53870ECCE6C0009BE4BA /* convert_UTF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = convert_UTF.c; path = ../../common/convert_UTF.c; sourceTree = SOURCE_ROOT; }; - F92C53880ECCE6C0009BE4BA /* convert_UTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = convert_UTF.h; path = ../../common/convert_UTF.h; sourceTree = SOURCE_ROOT; }; - F92C538E0ECCE70A009BE4BA /* minidump_file_writer-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "minidump_file_writer-inl.h"; path = "../minidump_file_writer-inl.h"; sourceTree = SOURCE_ROOT; }; - F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_file_writer.cc; path = ../minidump_file_writer.cc; sourceTree = SOURCE_ROOT; }; - F92C53900ECCE70A009BE4BA /* minidump_file_writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = minidump_file_writer.h; path = ../minidump_file_writer.h; sourceTree = SOURCE_ROOT; }; - F92C53B70ECCE7B3009BE4BA /* Inspector.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Inspector.mm; path = crash_generation/Inspector.mm; sourceTree = SOURCE_ROOT; }; - F92C554A0ECCF530009BE4BA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; - F92C55CE0ECD0064009BE4BA /* Breakpad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Breakpad.h; path = Framework/Breakpad.h; sourceTree = ""; }; - F92C55CF0ECD0064009BE4BA /* Breakpad.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Breakpad.mm; path = Framework/Breakpad.mm; sourceTree = ""; }; - F92C56310ECD0DF1009BE4BA /* OnDemandServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OnDemandServer.h; path = Framework/OnDemandServer.h; sourceTree = ""; }; - F92C56320ECD0DF1009BE4BA /* OnDemandServer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OnDemandServer.mm; path = Framework/OnDemandServer.mm; sourceTree = ""; }; - F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = breakpadUtilities.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - F92C56A00ECE04A7009BE4BA /* crash_report_sender.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = crash_report_sender.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F92C56A20ECE04A7009BE4BA /* crash_report_sender-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "crash_report_sender-Info.plist"; path = "sender/crash_report_sender-Info.plist"; sourceTree = ""; }; - F92C56A70ECE04C5009BE4BA /* crash_report_sender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crash_report_sender.h; path = sender/crash_report_sender.h; sourceTree = ""; }; - F92C56A80ECE04C5009BE4BA /* crash_report_sender.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = crash_report_sender.m; path = sender/crash_report_sender.m; sourceTree = ""; }; - F93803BE0F80820F004D428B /* generator_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = generator_test; sourceTree = BUILT_PRODUCTS_DIR; }; - F93DE2D10F82A67300608B94 /* minidump_file_writer_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_file_writer_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - F93DE2D70F82A70E00608B94 /* minidump_file_writer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_file_writer_unittest.cc; path = ../minidump_file_writer_unittest.cc; sourceTree = SOURCE_ROOT; }; - F93DE32C0F82C55600608B94 /* handler_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = handler_test; sourceTree = BUILT_PRODUCTS_DIR; }; - F945849D0F280E3C009A47BF /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = sender/English.lproj/Localizable.strings; sourceTree = ""; }; - F945859D0F78241E009A47BF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Framework/Info.plist; sourceTree = ""; }; - F95BB87C101F949F00AA053B /* crash_report.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = crash_report.xcodeproj; path = ../../tools/mac/crash_report/crash_report.xcodeproj; sourceTree = SOURCE_ROOT; }; - F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = dump_syms.xcodeproj; path = ../../tools/mac/dump_syms/dump_syms.xcodeproj; sourceTree = SOURCE_ROOT; }; - F95BB894101F94C000AA053B /* symupload.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = symupload.xcodeproj; path = ../../tools/mac/symupload/symupload.xcodeproj; sourceTree = SOURCE_ROOT; }; - F9B6309F100FF96B00D0F4AC /* goArrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goArrow.png; path = sender/goArrow.png; sourceTree = ""; }; - F9C44DA50EF060A8003AEBAA /* BreakpadTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BreakpadTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F9C44DAC0EF07288003AEBAA /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Controller.m; path = testapp/Controller.m; sourceTree = ""; }; - F9C44DAD0EF07288003AEBAA /* crashduringload */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = crashduringload; path = testapp/crashduringload; sourceTree = ""; }; - F9C44DAE0EF07288003AEBAA /* crashInMain */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = crashInMain; path = testapp/crashInMain; sourceTree = ""; }; - F9C44DAF0EF07288003AEBAA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = testapp/Info.plist; sourceTree = ""; }; - F9C44DB00EF07288003AEBAA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testapp/main.m; sourceTree = ""; }; - F9C44DB10EF07288003AEBAA /* TestClass.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestClass.mm; path = testapp/TestClass.mm; sourceTree = ""; }; - F9C44DB90EF072A0003AEBAA /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = testapp/English.lproj/InfoPlist.strings; sourceTree = ""; }; - F9C44DBB0EF072A0003AEBAA /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = testapp/English.lproj/MainMenu.xib; sourceTree = ""; }; - F9C44DBF0EF0778F003AEBAA /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Controller.h; path = testapp/Controller.h; sourceTree = ""; }; - F9C44DC00EF0778F003AEBAA /* TestClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestClass.h; path = testapp/TestClass.h; sourceTree = ""; }; - F9C44EE40EF0A006003AEBAA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; - F9C44EE70EF0A3C1003AEBAA /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMLogger.h; path = ../../common/mac/GTMLogger.h; sourceTree = SOURCE_ROOT; }; - F9C44EE80EF0A3C1003AEBAA /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GTMLogger.m; path = ../../common/mac/GTMLogger.m; sourceTree = SOURCE_ROOT; }; - F9C77DDA0F7DD5CF0045F7DB /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; - F9C77DDB0F7DD5CF0045F7DB /* UnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UnitTests-Info.plist"; sourceTree = ""; }; - F9C77E110F7DDF810045F7DB /* GTMSenTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMSenTestCase.h; path = ../../common/mac/testing/GTMSenTestCase.h; sourceTree = SOURCE_ROOT; }; - F9C77E120F7DDF810045F7DB /* GTMSenTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GTMSenTestCase.m; path = ../../common/mac/testing/GTMSenTestCase.m; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DC2EF560486A6940098B216 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F92C565C0ECD1158009BE4BA /* breakpadUtilities.dylib in Frameworks */, - 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D23F4BA912A868A500686C8D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D246418412BAA4BA005170D0 /* Foundation.framework in Frameworks */, - 4DBE49A6134A4F200072546A /* CoreServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2F9A41312131EF0002747C1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2F9A53E121383A1002747C1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D2F9A53F121383A1002747C1 /* Foundation.framework in Frameworks */, - D2F9A541121383A1002747C1 /* libgtest.a in Frameworks */, - 4DBE49A9134A4F460072546A /* CoreServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C53520ECCE349009BE4BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F92C564C0ECD10DD009BE4BA /* breakpadUtilities.dylib in Frameworks */, - F92C554C0ECCF534009BE4BA /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C563A0ECD10B3009BE4BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8B31FC8211EFD2B800FCF3E4 /* Foundation.framework in Frameworks */, - F92C56570ECD113E009BE4BA /* Carbon.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C569E0ECE04A7009BE4BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44EE50EF0A006003AEBAA /* SystemConfiguration.framework in Frameworks */, - 8B3101C611F0CD9F00FCF3E4 /* AppKit.framework in Frameworks */, - 8B3101C711F0CD9F00FCF3E4 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93803BC0F80820F004D428B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8B31029411F0D54300FCF3E4 /* Foundation.framework in Frameworks */, - D23F4B3312A7E17700686C8D /* libgtest.a in Frameworks */, - 4DBE49A7134A4F280072546A /* CoreServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93DE2CF0F82A67300608B94 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93DE32A0F82C55600608B94 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8B3102E611F0D74C00FCF3E4 /* Foundation.framework in Frameworks */, - D2F9A44412131F84002747C1 /* libgtest.a in Frameworks */, - 4DBE49A8134A4F380072546A /* CoreServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C44DA30EF060A8003AEBAA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44E000EF077CD003AEBAA /* Breakpad.framework in Frameworks */, - 8B3101CA11F0CDB000FCF3E4 /* AppKit.framework in Frameworks */, - 8B3101CB11F0CDB000FCF3E4 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C77DD70F7DD5CF0045F7DB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F91AF6210FD60784009D8BE2 /* Breakpad.framework in Frameworks */, - 8B3101EA11F0CDE300FCF3E4 /* SenTestingKit.framework in Frameworks */, - 8B3102EB11F0D78000FCF3E4 /* Foundation.framework in Frameworks */, - D24BBBFD121050F000F3D417 /* breakpadUtilities.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DFFF38A50411DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - 8DC2EF5B0486A6940098B216 /* Breakpad.framework */, - F92C53540ECCE349009BE4BA /* Inspector */, - F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */, - F92C56A00ECE04A7009BE4BA /* crash_report_sender.app */, - F9C44DA50EF060A8003AEBAA /* BreakpadTest.app */, - F9C77DDA0F7DD5CF0045F7DB /* UnitTests.octest */, - F93803BE0F80820F004D428B /* generator_test */, - F93DE2D10F82A67300608B94 /* minidump_file_writer_unittest */, - F93DE32C0F82C55600608B94 /* handler_test */, - D2F9A41512131EF0002747C1 /* libgtest.a */, - D2F9A546121383A1002747C1 /* crash_generation_server_test */, - D23F4BAB12A868A500686C8D /* minidump_generator_test_helper */, - ); - name = Products; - sourceTree = ""; - }; - 0867D691FE84028FC02AAC07 /* Breakpad */ = { - isa = PBXGroup; - children = ( - D2F9A43812131F3B002747C1 /* gtest */, - 8B31FFF611F0C90500FCF3E4 /* Breakpad.xcconfig */, - 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */, - 8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */, - F95BB8A3101F94C300AA053B /* Tools */, - 32DBCF5E0370ADEE00C91783 /* Breakpad_Prefix.pch */, - F92C538D0ECCE6F2009BE4BA /* client */, - F92C53600ECCE3D6009BE4BA /* common */, - D244536912426EE7009BBCE0 /* processor */, - 0867D69AFE84028FC02AAC07 /* Frameworks */, - 034768DFFF38A50411DB9C8B /* Products */, - F9C77DDB0F7DD5CF0045F7DB /* UnitTests-Info.plist */, - ); - name = Breakpad; - sourceTree = ""; - }; - 0867D69AFE84028FC02AAC07 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8B3101E911F0CDE300FCF3E4 /* SenTestingKit.framework */, - F9C44EE40EF0A006003AEBAA /* SystemConfiguration.framework */, - F92C554A0ECCF530009BE4BA /* Carbon.framework */, - 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, - 0867D6A5FE840307C02AAC07 /* AppKit.framework */, - 0867D69BFE84028FC02AAC07 /* Foundation.framework */, - 4DBE4769134A4F080072546A /* CoreServices.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 16C7C915147D45AE00776EAD /* apple */ = { - isa = PBXGroup; - children = ( - 16C7C916147D45AE00776EAD /* Framework */, - ); - name = apple; - path = ../apple; - sourceTree = SOURCE_ROOT; - }; - 16C7C916147D45AE00776EAD /* Framework */ = { - isa = PBXGroup; - children = ( - 16C7C917147D45AE00776EAD /* BreakpadDefines.h */, - ); - path = Framework; - sourceTree = ""; - }; - D244536912426EE7009BBCE0 /* processor */ = { - isa = PBXGroup; - children = ( - D244535112426EBB009BBCE0 /* logging.cc */, - D244535212426EBB009BBCE0 /* minidump.cc */, - D244535312426EBB009BBCE0 /* pathname_stripper.cc */, - D244534F12426E98009BBCE0 /* basic_code_modules.cc */, - ); - name = processor; - sourceTree = ""; - }; - D2F9A43812131F3B002747C1 /* gtest */ = { - isa = PBXGroup; - children = ( - D2F9A43E12131F65002747C1 /* gtest_main.cc */, - D2F9A43F12131F65002747C1 /* gtest-all.cc */, - D2F9A43C12131F55002747C1 /* gmock-all.cc */, - ); - name = gtest; - sourceTree = ""; - }; - F92C53590ECCE3BB009BE4BA /* handler */ = { - isa = PBXGroup; - children = ( - F92C53670ECCE3FD009BE4BA /* breakpad_exc_server.c */, - F92C53680ECCE3FD009BE4BA /* breakpad_exc_server.h */, - F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */, - F92C536A0ECCE3FD009BE4BA /* breakpad_nlist_64.h */, - F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */, - F92C536C0ECCE3FD009BE4BA /* dynamic_images.h */, - F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */, - F92C536E0ECCE3FD009BE4BA /* exception_handler.h */, - F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */, - F92C53700ECCE3FD009BE4BA /* minidump_generator.h */, - F92C53720ECCE3FD009BE4BA /* protected_memory_allocator.cc */, - F92C53730ECCE3FD009BE4BA /* protected_memory_allocator.h */, - ); - name = handler; - sourceTree = ""; - }; - F92C53600ECCE3D6009BE4BA /* common */ = { - isa = PBXGroup; - children = ( - D244540A12439BA0009BBCE0 /* memory_unittest.cc */, - F92C53870ECCE6C0009BE4BA /* convert_UTF.c */, - F92C53880ECCE6C0009BE4BA /* convert_UTF.h */, - 4D72CA0D13DFAD5C006CABE3 /* md5.cc */, - 1EEEB6211720829E00F7E689 /* simple_string_dictionary.cc */, - 1EEEB6221720829E00F7E689 /* simple_string_dictionary.h */, - F92C53850ECCE6AD009BE4BA /* string_conversion.cc */, - F92C53860ECCE6AD009BE4BA /* string_conversion.h */, - F92C53840ECCE68D009BE4BA /* mac */, - ); - name = common; - sourceTree = ""; - }; - F92C53840ECCE68D009BE4BA /* mac */ = { - isa = PBXGroup; - children = ( - 162F64F0161C577500CD68D5 /* arch_utilities.cc */, - 162F64F1161C577500CD68D5 /* arch_utilities.h */, - 8B31007011F0CD3C00FCF3E4 /* GTMDefines.h */, - F9C77E0F0F7DDF650045F7DB /* testing */, - F9C44EE70EF0A3C1003AEBAA /* GTMLogger.h */, - F9C44EE80EF0A3C1003AEBAA /* GTMLogger.m */, - F92C53740ECCE635009BE4BA /* file_id.cc */, - F92C53750ECCE635009BE4BA /* file_id.h */, - F92C53760ECCE635009BE4BA /* HTTPMultipartUpload.h */, - F92C53770ECCE635009BE4BA /* HTTPMultipartUpload.m */, - F4DAB1DB19F1027100A5A838 /* launch_reporter.cc */, - F4DAB1DC19F1027100A5A838 /* launch_reporter.h */, - F92C53780ECCE635009BE4BA /* MachIPC.h */, - F92C53790ECCE635009BE4BA /* MachIPC.mm */, - 4D61A25D14F43CFC002D5862 /* bootstrap_compat.cc */, - 4D61A25E14F43CFC002D5862 /* bootstrap_compat.h */, - F92C537A0ECCE635009BE4BA /* macho_id.cc */, - F92C537B0ECCE635009BE4BA /* macho_id.h */, - F92C537C0ECCE635009BE4BA /* macho_utilities.cc */, - F92C537D0ECCE635009BE4BA /* macho_utilities.h */, - F92C537E0ECCE635009BE4BA /* macho_walker.cc */, - F92C537F0ECCE635009BE4BA /* macho_walker.h */, - F92C53820ECCE635009BE4BA /* string_utilities.cc */, - F92C53830ECCE635009BE4BA /* string_utilities.h */, - ); - name = mac; - sourceTree = ""; - }; - F92C538D0ECCE6F2009BE4BA /* client */ = { - isa = PBXGroup; - children = ( - 16C7C915147D45AE00776EAD /* apple */, - F92C53990ECCE78E009BE4BA /* mac */, - F92C538E0ECCE70A009BE4BA /* minidump_file_writer-inl.h */, - F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */, - F92C53900ECCE70A009BE4BA /* minidump_file_writer.h */, - F93DE2D70F82A70E00608B94 /* minidump_file_writer_unittest.cc */, - ); - name = client; - sourceTree = ""; - }; - F92C53990ECCE78E009BE4BA /* mac */ = { - isa = PBXGroup; - children = ( - F9C77DDF0F7DD7CF0045F7DB /* tests */, - F9C44DAB0EF0726F003AEBAA /* testapp */, - F92C56A60ECE04B6009BE4BA /* sender */, - F92C55CD0ECD0053009BE4BA /* Framework */, - F92C53B50ECCE799009BE4BA /* crash_generation */, - F92C53590ECCE3BB009BE4BA /* handler */, - ); - name = mac; - sourceTree = ""; - }; - F92C53B50ECCE799009BE4BA /* crash_generation */ = { - isa = PBXGroup; - children = ( - 163201D41443019E00C4DBF5 /* ConfigFile.h */, - 163201D51443019E00C4DBF5 /* ConfigFile.mm */, - D2F9A4C4121336C7002747C1 /* client_info.h */, - D2F9A4C5121336C7002747C1 /* crash_generation_client.h */, - D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */, - D2F9A4C7121336C7002747C1 /* crash_generation_server.h */, - D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */, - F9286B380F7EB25800A4DCC8 /* Inspector.h */, - F9286B390F7EB25800A4DCC8 /* InspectorMain.mm */, - F92C53B70ECCE7B3009BE4BA /* Inspector.mm */, - ); - name = crash_generation; - sourceTree = ""; - }; - F92C55CD0ECD0053009BE4BA /* Framework */ = { - isa = PBXGroup; - children = ( - F945859D0F78241E009A47BF /* Info.plist */, - F92C56310ECD0DF1009BE4BA /* OnDemandServer.h */, - F92C56320ECD0DF1009BE4BA /* OnDemandServer.mm */, - F92C55CE0ECD0064009BE4BA /* Breakpad.h */, - F92C55CF0ECD0064009BE4BA /* Breakpad.mm */, - ); - name = Framework; - sourceTree = ""; - }; - F92C56A60ECE04B6009BE4BA /* sender */ = { - isa = PBXGroup; - children = ( - 16E02DB4147410D4008C604D /* uploader.mm */, - 163202431443201300C4DBF5 /* uploader.h */, - F9B6309F100FF96B00D0F4AC /* goArrow.png */, - F92C56A70ECE04C5009BE4BA /* crash_report_sender.h */, - F92C56A80ECE04C5009BE4BA /* crash_report_sender.m */, - F945849C0F280E3C009A47BF /* Localizable.strings */, - 33880C7E0F9E097100817F82 /* InfoPlist.strings */, - 3329D4EC0FA16D820007BBC5 /* Breakpad.xib */, - 4084699C0F5D9CF900FDCA37 /* crash_report_sender.icns */, - F92C56A20ECE04A7009BE4BA /* crash_report_sender-Info.plist */, - ); - name = sender; - sourceTree = ""; - }; - F95BB87D101F949F00AA053B /* Products */ = { - isa = PBXGroup; - children = ( - F95BB885101F949F00AA053B /* crash_report */, - ); - name = Products; - sourceTree = ""; - }; - F95BB88A101F94AC00AA053B /* Products */ = { - isa = PBXGroup; - children = ( - F95BB892101F94AC00AA053B /* dump_syms */, - 8B31F7A111EF9A8700FCF3E4 /* macho_dump */, - 8B31F7A311EF9A8700FCF3E4 /* libgtestmockall.a */, - 8B31F7A511EF9A8700FCF3E4 /* byte_cursor_unittest */, - 8B31F7A711EF9A8700FCF3E4 /* macho_reader_unittest */, - 8B31F7A911EF9A8700FCF3E4 /* stabs_reader_unittest */, - 8B31F7AB11EF9A8700FCF3E4 /* bytereader_unittest */, - 8B31F7AD11EF9A8700FCF3E4 /* dwarf2reader_cfi_unittest */, - 8B31F7AF11EF9A8700FCF3E4 /* dwarf2diehandler_unittest */, - 8B31F7B111EF9A8700FCF3E4 /* dwarf_cu_to_module_unittest */, - 8B31F7B311EF9A8700FCF3E4 /* dwarf_line_to_module_unittest */, - 8B31F7B511EF9A8700FCF3E4 /* dwarf_cfi_to_module_unittest */, - 8B31F7B711EF9A8700FCF3E4 /* stabs_to_module_unittest */, - 8B31F7B911EF9A8700FCF3E4 /* module_unittest */, - 8B31F7BB11EF9A8700FCF3E4 /* test_assembler_unittest */, - ); - name = Products; - sourceTree = ""; - }; - F95BB895101F94C000AA053B /* Products */ = { - isa = PBXGroup; - children = ( - F95BB89F101F94C000AA053B /* symupload */, - F95BB8A1101F94C000AA053B /* minidump_upload */, - ); - name = Products; - sourceTree = ""; - }; - F95BB8A3101F94C300AA053B /* Tools */ = { - isa = PBXGroup; - children = ( - F95BB894101F94C000AA053B /* symupload.xcodeproj */, - F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */, - F95BB87C101F949F00AA053B /* crash_report.xcodeproj */, - ); - name = Tools; - sourceTree = ""; - }; - F9C44DAB0EF0726F003AEBAA /* testapp */ = { - isa = PBXGroup; - children = ( - F9C44DBF0EF0778F003AEBAA /* Controller.h */, - F9C44DC00EF0778F003AEBAA /* TestClass.h */, - F9C44DB80EF072A0003AEBAA /* InfoPlist.strings */, - F9C44DBA0EF072A0003AEBAA /* MainMenu.xib */, - F9C44DAC0EF07288003AEBAA /* Controller.m */, - F9C44DAD0EF07288003AEBAA /* crashduringload */, - F9C44DAE0EF07288003AEBAA /* crashInMain */, - F9C44DAF0EF07288003AEBAA /* Info.plist */, - F9C44DB00EF07288003AEBAA /* main.m */, - F9C44DB10EF07288003AEBAA /* TestClass.mm */, - ); - name = testapp; - sourceTree = ""; - }; - F9C77DDF0F7DD7CF0045F7DB /* tests */ = { - isa = PBXGroup; - children = ( - 1EEEB6251720830600F7E689 /* simple_string_dictionary_unittest.cc */, - D23F4B9A12A8688800686C8D /* minidump_generator_test_helper.cc */, - D23F4B2C12A7E13200686C8D /* minidump_generator_test.cc */, - D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */, - D2F9A3D41212F87C002747C1 /* exception_handler_test.cc */, - F91AF5CF0FD60393009D8BE2 /* BreakpadFramework_Test.mm */, - ); - name = tests; - sourceTree = ""; - }; - F9C77E0F0F7DDF650045F7DB /* testing */ = { - isa = PBXGroup; - children = ( - F9C77E110F7DDF810045F7DB /* GTMSenTestCase.h */, - F9C77E120F7DDF810045F7DB /* GTMSenTestCase.m */, - ); - name = testing; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8DC2EF500486A6940098B216 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F92C55D00ECD0064009BE4BA /* Breakpad.h in Headers */, - F92C56330ECD0DF1009BE4BA /* OnDemandServer.h in Headers */, - D2F9A4C9121336C7002747C1 /* client_info.h in Headers */, - D2F9A4CA121336C7002747C1 /* crash_generation_client.h in Headers */, - D2F9A4CC121336C7002747C1 /* crash_generation_server.h in Headers */, - 163201D61443019E00C4DBF5 /* ConfigFile.h in Headers */, - 16C7C918147D45AE00776EAD /* BreakpadDefines.h in Headers */, - 162F64F3161C577500CD68D5 /* arch_utilities.h in Headers */, - F4DAB1DE19F1027100A5A838 /* launch_reporter.h in Headers */, - 1EEEB6241720829E00F7E689 /* simple_string_dictionary.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2F9A41112131EF0002747C1 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C56380ECD10B3009BE4BA /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 8DC2EF4F0486A6940098B216 /* Breakpad */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */; - buildPhases = ( - F97A0E850ED4EC15008784D3 /* Change install name of breakpadUtilities */, - 8DC2EF500486A6940098B216 /* Headers */, - 8DC2EF520486A6940098B216 /* Resources */, - 8DC2EF540486A6940098B216 /* Sources */, - 8DC2EF560486A6940098B216 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - F92C56860ECD15EF009BE4BA /* PBXTargetDependency */, - F92C56880ECD15F1009BE4BA /* PBXTargetDependency */, - F9C44E970EF09F4B003AEBAA /* PBXTargetDependency */, - ); - name = Breakpad; - productInstallPath = "$(HOME)/Library/Frameworks"; - productName = Breakpad; - productReference = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; - productType = "com.apple.product-type.framework"; - }; - D23F4BAA12A868A500686C8D /* minidump_generator_test_helper */ = { - isa = PBXNativeTarget; - buildConfigurationList = D23F4BB012A868C400686C8D /* Build configuration list for PBXNativeTarget "minidump_generator_test_helper" */; - buildPhases = ( - D23F4BA812A868A500686C8D /* Sources */, - D23F4BA912A868A500686C8D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = minidump_generator_test_helper; - productName = minidump_generator_test_helper; - productReference = D23F4BAB12A868A500686C8D /* minidump_generator_test_helper */; - productType = "com.apple.product-type.tool"; - }; - D2F9A41412131EF0002747C1 /* gtest */ = { - isa = PBXNativeTarget; - buildConfigurationList = D2F9A42D12131F0E002747C1 /* Build configuration list for PBXNativeTarget "gtest" */; - buildPhases = ( - D2F9A41112131EF0002747C1 /* Headers */, - D2F9A41212131EF0002747C1 /* Sources */, - D2F9A41312131EF0002747C1 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = gtest; - productName = gtest; - productReference = D2F9A41512131EF0002747C1 /* libgtest.a */; - productType = "com.apple.product-type.library.static"; - }; - D2F9A52A121383A1002747C1 /* crash_generation_server_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = D2F9A542121383A1002747C1 /* Build configuration list for PBXNativeTarget "crash_generation_server_test" */; - buildPhases = ( - D2F9A52D121383A1002747C1 /* Sources */, - D2F9A53E121383A1002747C1 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - D2F9A52B121383A1002747C1 /* PBXTargetDependency */, - ); - name = crash_generation_server_test; - productName = handler_test; - productReference = D2F9A546121383A1002747C1 /* crash_generation_server_test */; - productType = "com.apple.product-type.tool"; - }; - F92C53530ECCE349009BE4BA /* Inspector */ = { - isa = PBXNativeTarget; - buildConfigurationList = F92C53580ECCE36D009BE4BA /* Build configuration list for PBXNativeTarget "Inspector" */; - buildPhases = ( - F94584840F27FB40009A47BF /* Change install name of breakpadUtilities */, - F92C53510ECCE349009BE4BA /* Sources */, - F92C53520ECCE349009BE4BA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - F92C564E0ECD10E5009BE4BA /* PBXTargetDependency */, - ); - name = Inspector; - productName = Inspector; - productReference = F92C53540ECCE349009BE4BA /* Inspector */; - productType = "com.apple.product-type.tool"; - }; - F92C563B0ECD10B3009BE4BA /* breakpadUtilities */ = { - isa = PBXNativeTarget; - buildConfigurationList = F92C56670ECD11A3009BE4BA /* Build configuration list for PBXNativeTarget "breakpadUtilities" */; - buildPhases = ( - F92C56380ECD10B3009BE4BA /* Headers */, - F92C56390ECD10B3009BE4BA /* Sources */, - F92C563A0ECD10B3009BE4BA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = breakpadUtilities; - productName = breakpadUtilities; - productReference = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; - F92C569F0ECE04A7009BE4BA /* crash_report_sender */ = { - isa = PBXNativeTarget; - buildConfigurationList = F92C56A50ECE04A8009BE4BA /* Build configuration list for PBXNativeTarget "crash_report_sender" */; - buildPhases = ( - F92C569C0ECE04A7009BE4BA /* Resources */, - F92C569D0ECE04A7009BE4BA /* Sources */, - F92C569E0ECE04A7009BE4BA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = crash_report_sender; - productName = crash_report_sender; - productReference = F92C56A00ECE04A7009BE4BA /* crash_report_sender.app */; - productType = "com.apple.product-type.application"; - }; - F93803BD0F80820F004D428B /* generator_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = F93803C40F80822E004D428B /* Build configuration list for PBXNativeTarget "generator_test" */; - buildPhases = ( - F93803BB0F80820F004D428B /* Sources */, - F93803BC0F80820F004D428B /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - D23F4B3012A7E16200686C8D /* PBXTargetDependency */, - D23F4BBA12A8694C00686C8D /* PBXTargetDependency */, - ); - name = generator_test; - productName = generator_test; - productReference = F93803BE0F80820F004D428B /* generator_test */; - productType = "com.apple.product-type.tool"; - }; - F93DE2D00F82A67300608B94 /* minidump_file_writer_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = F93DE2D60F82A67700608B94 /* Build configuration list for PBXNativeTarget "minidump_file_writer_unittest" */; - buildPhases = ( - F93DE2CE0F82A67300608B94 /* Sources */, - F93DE2CF0F82A67300608B94 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = minidump_file_writer_unittest; - productName = minidump_file_writer_unittest; - productReference = F93DE2D10F82A67300608B94 /* minidump_file_writer_unittest */; - productType = "com.apple.product-type.tool"; - }; - F93DE32B0F82C55600608B94 /* handler_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = F93DE3320F82C5D800608B94 /* Build configuration list for PBXNativeTarget "handler_test" */; - buildPhases = ( - F93DE3290F82C55600608B94 /* Sources */, - F93DE32A0F82C55600608B94 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - D2F9A44312131F80002747C1 /* PBXTargetDependency */, - ); - name = handler_test; - productName = handler_test; - productReference = F93DE32C0F82C55600608B94 /* handler_test */; - productType = "com.apple.product-type.tool"; - }; - F9C44DA40EF060A8003AEBAA /* BreakpadTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = F9C44DAA0EF060A9003AEBAA /* Build configuration list for PBXNativeTarget "BreakpadTest" */; - buildPhases = ( - F9C44DA10EF060A8003AEBAA /* Resources */, - F9C44DA20EF060A8003AEBAA /* Sources */, - F9C44DA30EF060A8003AEBAA /* Frameworks */, - F9C44E410EF08B17003AEBAA /* Copy Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - F9C44E1A0EF0790F003AEBAA /* PBXTargetDependency */, - ); - name = BreakpadTest; - productName = BreakpadTest; - productReference = F9C44DA50EF060A8003AEBAA /* BreakpadTest.app */; - productType = "com.apple.product-type.application"; - }; - F9C77DD90F7DD5CF0045F7DB /* UnitTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = F9C77DDE0F7DD5D00045F7DB /* Build configuration list for PBXNativeTarget "UnitTests" */; - buildPhases = ( - F9C77DD50F7DD5CF0045F7DB /* Resources */, - F9C77DD60F7DD5CF0045F7DB /* Sources */, - F9C77DD70F7DD5CF0045F7DB /* Frameworks */, - F9C77DD80F7DD5CF0045F7DB /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - F93DE2FC0F82C3C600608B94 /* PBXTargetDependency */, - F93DE3700F82CC1300608B94 /* PBXTargetDependency */, - F91AF6380FD60A74009D8BE2 /* PBXTargetDependency */, - D2F9A5DF12142A6A002747C1 /* PBXTargetDependency */, - ); - name = UnitTests; - productName = UnitTests; - productReference = F9C77DDA0F7DD5CF0045F7DB /* UnitTests.octest */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "Breakpad" */; - compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - da, - de, - es, - fr, - it, - ja, - nl, - no, - sl, - sv, - tr, - ); - mainGroup = 0867D691FE84028FC02AAC07 /* Breakpad */; - productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = F95BB87D101F949F00AA053B /* Products */; - ProjectRef = F95BB87C101F949F00AA053B /* crash_report.xcodeproj */; - }, - { - ProductGroup = F95BB88A101F94AC00AA053B /* Products */; - ProjectRef = F95BB889101F94AC00AA053B /* dump_syms.xcodeproj */; - }, - { - ProductGroup = F95BB895101F94C000AA053B /* Products */; - ProjectRef = F95BB894101F94C000AA053B /* symupload.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 8DC2EF4F0486A6940098B216 /* Breakpad */, - F92C53530ECCE349009BE4BA /* Inspector */, - F92C563B0ECD10B3009BE4BA /* breakpadUtilities */, - F92C569F0ECE04A7009BE4BA /* crash_report_sender */, - F9C44DA40EF060A8003AEBAA /* BreakpadTest */, - F94585840F782326009A47BF /* All */, - F9C77DD90F7DD5CF0045F7DB /* UnitTests */, - F93803BD0F80820F004D428B /* generator_test */, - F93DE2D00F82A67300608B94 /* minidump_file_writer_unittest */, - F93DE32B0F82C55600608B94 /* handler_test */, - D2F9A41412131EF0002747C1 /* gtest */, - D2F9A52A121383A1002747C1 /* crash_generation_server_test */, - D23F4BAA12A868A500686C8D /* minidump_generator_test_helper */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 8B31F7A111EF9A8700FCF3E4 /* macho_dump */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = macho_dump; - remoteRef = 8B31F7A011EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7A311EF9A8700FCF3E4 /* libgtestmockall.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libgtestmockall.a; - remoteRef = 8B31F7A211EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7A511EF9A8700FCF3E4 /* byte_cursor_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = byte_cursor_unittest; - remoteRef = 8B31F7A411EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7A711EF9A8700FCF3E4 /* macho_reader_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = macho_reader_unittest; - remoteRef = 8B31F7A611EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7A911EF9A8700FCF3E4 /* stabs_reader_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = stabs_reader_unittest; - remoteRef = 8B31F7A811EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7AB11EF9A8700FCF3E4 /* bytereader_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = bytereader_unittest; - remoteRef = 8B31F7AA11EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7AD11EF9A8700FCF3E4 /* dwarf2reader_cfi_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dwarf2reader_cfi_unittest; - remoteRef = 8B31F7AC11EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7AF11EF9A8700FCF3E4 /* dwarf2diehandler_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dwarf2diehandler_unittest; - remoteRef = 8B31F7AE11EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7B111EF9A8700FCF3E4 /* dwarf_cu_to_module_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dwarf_cu_to_module_unittest; - remoteRef = 8B31F7B011EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7B311EF9A8700FCF3E4 /* dwarf_line_to_module_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dwarf_line_to_module_unittest; - remoteRef = 8B31F7B211EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7B511EF9A8700FCF3E4 /* dwarf_cfi_to_module_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dwarf_cfi_to_module_unittest; - remoteRef = 8B31F7B411EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7B711EF9A8700FCF3E4 /* stabs_to_module_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = stabs_to_module_unittest; - remoteRef = 8B31F7B611EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7B911EF9A8700FCF3E4 /* module_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = module_unittest; - remoteRef = 8B31F7B811EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8B31F7BB11EF9A8700FCF3E4 /* test_assembler_unittest */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = test_assembler_unittest; - remoteRef = 8B31F7BA11EF9A8700FCF3E4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F95BB885101F949F00AA053B /* crash_report */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = crash_report; - remoteRef = F95BB884101F949F00AA053B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F95BB892101F94AC00AA053B /* dump_syms */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = dump_syms; - remoteRef = F95BB891101F94AC00AA053B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F95BB89F101F94C000AA053B /* symupload */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = symupload; - remoteRef = F95BB89E101F94C000AA053B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F95BB8A1101F94C000AA053B /* minidump_upload */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = minidump_upload; - remoteRef = F95BB8A0101F94C000AA053B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 8DC2EF520486A6940098B216 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44E980EF09F56003AEBAA /* crash_report_sender.app in Resources */, - F92C568A0ECD15F9009BE4BA /* Inspector in Resources */, - F92C56650ECD1185009BE4BA /* breakpadUtilities.dylib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C569C0ECE04A7009BE4BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F945849E0F280E3C009A47BF /* Localizable.strings in Resources */, - 4084699D0F5D9CF900FDCA37 /* crash_report_sender.icns in Resources */, - 33880C800F9E097100817F82 /* InfoPlist.strings in Resources */, - 3329D4ED0FA16D820007BBC5 /* Breakpad.xib in Resources */, - F9B630A0100FF96B00D0F4AC /* goArrow.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C44DA10EF060A8003AEBAA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44DB30EF07288003AEBAA /* crashduringload in Resources */, - F9C44DB40EF07288003AEBAA /* crashInMain in Resources */, - F9C44DBC0EF072A0003AEBAA /* InfoPlist.strings in Resources */, - F9C44DBD0EF072A0003AEBAA /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C77DD50F7DD5CF0045F7DB /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - F94584840F27FB40009A47BF /* Change install name of breakpadUtilities */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Change install name of breakpadUtilities"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "install_name_tool -id \"@executable_path/../Resources/breakpadUtilities.dylib\" \"${BUILT_PRODUCTS_DIR}/breakpadUtilities.dylib\"\n"; - }; - F97A0E850ED4EC15008784D3 /* Change install name of breakpadUtilities */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Change install name of breakpadUtilities"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/bin/bash\ninstall_name_tool -id \"@executable_path/../Frameworks/Breakpad.framework/Resources/breakpadUtilities.dylib\" \"${BUILT_PRODUCTS_DIR}/breakpadUtilities.dylib\"\n"; - }; - F9C77DD80F7DD5CF0045F7DB /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n\necho running minidump generator tests...\n\"${BUILT_PRODUCTS_DIR}/generator_test\"\necho Running exception handler tests...\n\"${BUILT_PRODUCTS_DIR}/handler_test\"\necho Running crash generation server tests...\n\"${BUILT_PRODUCTS_DIR}/crash_generation_server_test\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DC2EF540486A6940098B216 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F92C565F0ECD116B009BE4BA /* protected_memory_allocator.cc in Sources */, - F92C56630ECD1179009BE4BA /* exception_handler.cc in Sources */, - F92C55D10ECD0064009BE4BA /* Breakpad.mm in Sources */, - F4DAB1DD19F1027100A5A838 /* launch_reporter.cc in Sources */, - F92C56340ECD0DF1009BE4BA /* OnDemandServer.mm in Sources */, - D2F9A4CB121336C7002747C1 /* crash_generation_client.cc in Sources */, - D2F9A4CD121336C7002747C1 /* crash_generation_server.cc in Sources */, - 163201D71443019E00C4DBF5 /* ConfigFile.mm in Sources */, - 162F64F2161C577500CD68D5 /* arch_utilities.cc in Sources */, - 1EEEB6231720829E00F7E689 /* simple_string_dictionary.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D23F4BA812A868A500686C8D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D23F4BB112A868CB00686C8D /* minidump_generator_test_helper.cc in Sources */, - D23F4BB812A868F700686C8D /* MachIPC.mm in Sources */, - D246417012BAA40E005170D0 /* exception_handler.cc in Sources */, - D246417112BAA41C005170D0 /* crash_generation_client.cc in Sources */, - D246417512BAA438005170D0 /* minidump_generator.cc in Sources */, - D246417612BAA43F005170D0 /* dynamic_images.cc in Sources */, - D246417712BAA444005170D0 /* breakpad_nlist_64.cc in Sources */, - D246418812BAA4E3005170D0 /* string_utilities.cc in Sources */, - D246418C12BAA508005170D0 /* minidump_file_writer.cc in Sources */, - D246419012BAA52A005170D0 /* string_conversion.cc in Sources */, - D246419112BAA52F005170D0 /* convert_UTF.c in Sources */, - D246419512BAA54C005170D0 /* file_id.cc in Sources */, - D246419612BAA55A005170D0 /* macho_id.cc in Sources */, - D24641A012BAA67F005170D0 /* macho_walker.cc in Sources */, - D24641AF12BAA82D005170D0 /* macho_utilities.cc in Sources */, - 4D72CA2513DFAE1C006CABE3 /* md5.cc in Sources */, - 4D61A26C14F43D42002D5862 /* bootstrap_compat.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2F9A41212131EF0002747C1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D2F9A43D12131F55002747C1 /* gmock-all.cc in Sources */, - D2F9A44012131F65002747C1 /* gtest_main.cc in Sources */, - D2F9A44112131F65002747C1 /* gtest-all.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2F9A52D121383A1002747C1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D2F9A553121383DC002747C1 /* crash_generation_server_test.cc in Sources */, - D2F9A52E121383A1002747C1 /* crash_generation_client.cc in Sources */, - D2F9A52F121383A1002747C1 /* crash_generation_server.cc in Sources */, - D2F9A530121383A1002747C1 /* MachIPC.mm in Sources */, - D2F9A531121383A1002747C1 /* breakpad_nlist_64.cc in Sources */, - D2F9A532121383A1002747C1 /* dynamic_images.cc in Sources */, - D2F9A533121383A1002747C1 /* exception_handler.cc in Sources */, - D2F9A534121383A1002747C1 /* minidump_generator.cc in Sources */, - D2F9A535121383A1002747C1 /* minidump_file_writer.cc in Sources */, - D2F9A536121383A1002747C1 /* convert_UTF.c in Sources */, - D2F9A537121383A1002747C1 /* string_conversion.cc in Sources */, - D2F9A538121383A1002747C1 /* file_id.cc in Sources */, - D2F9A539121383A1002747C1 /* macho_id.cc in Sources */, - D2F9A53A121383A1002747C1 /* macho_utilities.cc in Sources */, - D2F9A53B121383A1002747C1 /* macho_walker.cc in Sources */, - D2F9A53C121383A1002747C1 /* string_utilities.cc in Sources */, - D24641EC12BAC6FB005170D0 /* logging.cc in Sources */, - D24641ED12BAC6FB005170D0 /* minidump.cc in Sources */, - D24641EE12BAC6FB005170D0 /* pathname_stripper.cc in Sources */, - D24641EF12BAC6FB005170D0 /* basic_code_modules.cc in Sources */, - 4D72CA3913DFAE92006CABE3 /* md5.cc in Sources */, - 4D61A26F14F43D48002D5862 /* bootstrap_compat.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C53510ECCE349009BE4BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F92C53B80ECCE7B3009BE4BA /* Inspector.mm in Sources */, - F9286B3A0F7EB25800A4DCC8 /* InspectorMain.mm in Sources */, - 163201E31443029300C4DBF5 /* ConfigFile.mm in Sources */, - 4D61A26B14F43D3C002D5862 /* bootstrap_compat.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C56390ECD10B3009BE4BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F4F916B619F10FFC00B83BE4 /* launch_reporter.cc in Sources */, - 162F64F4161C579B00CD68D5 /* arch_utilities.cc in Sources */, - 162F64F5161C579B00CD68D5 /* arch_utilities.h in Sources */, - D2A5DD301188633800081F03 /* breakpad_nlist_64.cc in Sources */, - F92C563F0ECD10CA009BE4BA /* convert_UTF.c in Sources */, - F92C56400ECD10CA009BE4BA /* dynamic_images.cc in Sources */, - F92C56410ECD10CA009BE4BA /* file_id.cc in Sources */, - F92C56420ECD10CA009BE4BA /* macho_id.cc in Sources */, - F92C56430ECD10CA009BE4BA /* macho_utilities.cc in Sources */, - F92C56440ECD10CA009BE4BA /* macho_walker.cc in Sources */, - F92C56450ECD10CA009BE4BA /* MachIPC.mm in Sources */, - 4D72CA0E13DFAD5C006CABE3 /* md5.cc in Sources */, - F92C56460ECD10CA009BE4BA /* minidump_file_writer.cc in Sources */, - F92C56470ECD10CA009BE4BA /* minidump_generator.cc in Sources */, - F92C56490ECD10CA009BE4BA /* string_utilities.cc in Sources */, - F92C564A0ECD10CA009BE4BA /* string_conversion.cc in Sources */, - 4D61A25F14F43CFC002D5862 /* bootstrap_compat.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F92C569D0ECE04A7009BE4BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44EA20EF09F93003AEBAA /* HTTPMultipartUpload.m in Sources */, - F92C56A90ECE04C5009BE4BA /* crash_report_sender.m in Sources */, - F9C44EE90EF0A3C1003AEBAA /* GTMLogger.m in Sources */, - 16E02DB8147410F0008C604D /* uploader.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93803BB0F80820F004D428B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D2C1DBE412AFC270006917BD /* logging.cc in Sources */, - D2C1DBE512AFC270006917BD /* minidump.cc in Sources */, - D2C1DBE612AFC270006917BD /* pathname_stripper.cc in Sources */, - D2C1DBE712AFC270006917BD /* basic_code_modules.cc in Sources */, - D2F9A4DF12133AD9002747C1 /* crash_generation_client.cc in Sources */, - D2F9A4E012133AD9002747C1 /* crash_generation_server.cc in Sources */, - D24BBD291211EDB100F3D417 /* MachIPC.mm in Sources */, - D2A5DD401188640400081F03 /* breakpad_nlist_64.cc in Sources */, - F93803CD0F8083B7004D428B /* dynamic_images.cc in Sources */, - F93803CE0F8083B7004D428B /* exception_handler.cc in Sources */, - F93803CF0F8083B7004D428B /* minidump_generator.cc in Sources */, - F93803D00F8083B7004D428B /* minidump_file_writer.cc in Sources */, - F93803D10F8083B7004D428B /* convert_UTF.c in Sources */, - F93803D20F8083B7004D428B /* string_conversion.cc in Sources */, - F93803D30F8083B7004D428B /* file_id.cc in Sources */, - F93803D40F8083B7004D428B /* macho_id.cc in Sources */, - F93803D50F8083B7004D428B /* macho_utilities.cc in Sources */, - F93803D60F8083B7004D428B /* macho_walker.cc in Sources */, - F93803D70F8083B7004D428B /* string_utilities.cc in Sources */, - D23F4B2E12A7E13200686C8D /* minidump_generator_test.cc in Sources */, - 4D72CA2F13DFAE65006CABE3 /* md5.cc in Sources */, - 4D61A26D14F43D43002D5862 /* bootstrap_compat.cc in Sources */, - 1EEEB62B1720868C00F7E689 /* simple_string_dictionary.cc in Sources */, - 1EEEB62A1720859200F7E689 /* simple_string_dictionary_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93DE2CE0F82A67300608B94 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F93DE2D90F82A73500608B94 /* minidump_file_writer.cc in Sources */, - F93DE2DA0F82A73500608B94 /* convert_UTF.c in Sources */, - F93DE2DB0F82A73500608B94 /* string_conversion.cc in Sources */, - F93DE2D80F82A70E00608B94 /* minidump_file_writer_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93DE3290F82C55600608B94 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D244536A12426F00009BBCE0 /* logging.cc in Sources */, - D244536B12426F00009BBCE0 /* minidump.cc in Sources */, - D244536C12426F00009BBCE0 /* pathname_stripper.cc in Sources */, - D244536D12426F00009BBCE0 /* basic_code_modules.cc in Sources */, - D2F9A4E112133AE2002747C1 /* crash_generation_client.cc in Sources */, - D2F9A4E212133AE2002747C1 /* crash_generation_server.cc in Sources */, - D24BBD321212CACF00F3D417 /* MachIPC.mm in Sources */, - D2A5DD411188642E00081F03 /* breakpad_nlist_64.cc in Sources */, - F93DE3350F82C66B00608B94 /* dynamic_images.cc in Sources */, - F93DE3360F82C66B00608B94 /* exception_handler.cc in Sources */, - F93DE3370F82C66B00608B94 /* minidump_generator.cc in Sources */, - F93DE3380F82C66B00608B94 /* minidump_file_writer.cc in Sources */, - F93DE3390F82C66B00608B94 /* convert_UTF.c in Sources */, - F93DE33A0F82C66B00608B94 /* string_conversion.cc in Sources */, - F93DE33B0F82C66B00608B94 /* file_id.cc in Sources */, - F93DE33C0F82C66B00608B94 /* macho_id.cc in Sources */, - F93DE33D0F82C66B00608B94 /* macho_utilities.cc in Sources */, - F93DE33E0F82C66B00608B94 /* macho_walker.cc in Sources */, - F93DE33F0F82C66B00608B94 /* string_utilities.cc in Sources */, - D2F9A3D51212F87C002747C1 /* exception_handler_test.cc in Sources */, - D244540B12439BA0009BBCE0 /* memory_unittest.cc in Sources */, - 4D72CA3813DFAE91006CABE3 /* md5.cc in Sources */, - 4D61A26E14F43D45002D5862 /* bootstrap_compat.cc in Sources */, - 1EEEB6271720831E00F7E689 /* BreakpadFramework_Test.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C44DA20EF060A8003AEBAA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C44DB20EF07288003AEBAA /* Controller.m in Sources */, - F9C44DB60EF07288003AEBAA /* main.m in Sources */, - F9C44DB70EF07288003AEBAA /* TestClass.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9C77DD60F7DD5CF0045F7DB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C77E130F7DDF810045F7DB /* GTMSenTestCase.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 8B31023911F0CF0600FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = all_unittests; - targetProxy = 8B31023811F0CF0600FCF3E4 /* PBXContainerItemProxy */; - }; - 8B31051711F1010E00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93803BD0F80820F004D428B /* generator_test */; - targetProxy = 8B31051611F1010E00FCF3E4 /* PBXContainerItemProxy */; - }; - 8B31051911F1010E00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93DE2D00F82A67300608B94 /* minidump_file_writer_unittest */; - targetProxy = 8B31051811F1010E00FCF3E4 /* PBXContainerItemProxy */; - }; - 8B31051B11F1010E00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93DE32B0F82C55600608B94 /* handler_test */; - targetProxy = 8B31051A11F1010E00FCF3E4 /* PBXContainerItemProxy */; - }; - 8B31051D11F1010E00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = macho_dump; - targetProxy = 8B31051C11F1010E00FCF3E4 /* PBXContainerItemProxy */; - }; - 8B31051F11F1010E00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = minidump_upload; - targetProxy = 8B31051E11F1010E00FCF3E4 /* PBXContainerItemProxy */; - }; - D23F4B3012A7E16200686C8D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2F9A41412131EF0002747C1 /* gtest */; - targetProxy = D23F4B2F12A7E16200686C8D /* PBXContainerItemProxy */; - }; - D23F4BBA12A8694C00686C8D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D23F4BAA12A868A500686C8D /* minidump_generator_test_helper */; - targetProxy = D23F4BB912A8694C00686C8D /* PBXContainerItemProxy */; - }; - D2F9A44312131F80002747C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2F9A41412131EF0002747C1 /* gtest */; - targetProxy = D2F9A44212131F80002747C1 /* PBXContainerItemProxy */; - }; - D2F9A52B121383A1002747C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2F9A41412131EF0002747C1 /* gtest */; - targetProxy = D2F9A52C121383A1002747C1 /* PBXContainerItemProxy */; - }; - D2F9A5DF12142A6A002747C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2F9A52A121383A1002747C1 /* crash_generation_server_test */; - targetProxy = D2F9A5DE12142A6A002747C1 /* PBXContainerItemProxy */; - }; - F91AF6380FD60A74009D8BE2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8DC2EF4F0486A6940098B216 /* Breakpad */; - targetProxy = F91AF6370FD60A74009D8BE2 /* PBXContainerItemProxy */; - }; - F92C564E0ECD10E5009BE4BA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C563B0ECD10B3009BE4BA /* breakpadUtilities */; - targetProxy = F92C564D0ECD10E5009BE4BA /* PBXContainerItemProxy */; - }; - F92C56860ECD15EF009BE4BA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C563B0ECD10B3009BE4BA /* breakpadUtilities */; - targetProxy = F92C56850ECD15EF009BE4BA /* PBXContainerItemProxy */; - }; - F92C56880ECD15F1009BE4BA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C53530ECCE349009BE4BA /* Inspector */; - targetProxy = F92C56870ECD15F1009BE4BA /* PBXContainerItemProxy */; - }; - F93DE2FC0F82C3C600608B94 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93803BD0F80820F004D428B /* generator_test */; - targetProxy = F93DE2FB0F82C3C600608B94 /* PBXContainerItemProxy */; - }; - F93DE3700F82CC1300608B94 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93DE32B0F82C55600608B94 /* handler_test */; - targetProxy = F93DE36F0F82CC1300608B94 /* PBXContainerItemProxy */; - }; - F93DE3A70F830D1D00608B94 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F9C77DD90F7DD5CF0045F7DB /* UnitTests */; - targetProxy = F93DE3A60F830D1D00608B94 /* PBXContainerItemProxy */; - }; - F94585880F78232B009A47BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8DC2EF4F0486A6940098B216 /* Breakpad */; - targetProxy = F94585870F78232B009A47BF /* PBXContainerItemProxy */; - }; - F945858A0F78232E009A47BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C53530ECCE349009BE4BA /* Inspector */; - targetProxy = F94585890F78232E009A47BF /* PBXContainerItemProxy */; - }; - F945858C0F782330009A47BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C563B0ECD10B3009BE4BA /* breakpadUtilities */; - targetProxy = F945858B0F782330009A47BF /* PBXContainerItemProxy */; - }; - F945858E0F782333009A47BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C569F0ECE04A7009BE4BA /* crash_report_sender */; - targetProxy = F945858D0F782333009A47BF /* PBXContainerItemProxy */; - }; - F94585900F782336009A47BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F9C44DA40EF060A8003AEBAA /* BreakpadTest */; - targetProxy = F945858F0F782336009A47BF /* PBXContainerItemProxy */; - }; - F95BB8B3101F94D300AA053B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = dump_syms; - targetProxy = F95BB8B2101F94D300AA053B /* PBXContainerItemProxy */; - }; - F95BB8B5101F94D300AA053B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = symupload; - targetProxy = F95BB8B4101F94D300AA053B /* PBXContainerItemProxy */; - }; - F95BB8B7101F94D300AA053B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = crash_report; - targetProxy = F95BB8B6101F94D300AA053B /* PBXContainerItemProxy */; - }; - F9C44E1A0EF0790F003AEBAA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8DC2EF4F0486A6940098B216 /* Breakpad */; - targetProxy = F9C44E190EF0790F003AEBAA /* PBXContainerItemProxy */; - }; - F9C44E970EF09F4B003AEBAA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F92C569F0ECE04A7009BE4BA /* crash_report_sender */; - targetProxy = F9C44E960EF09F4B003AEBAA /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33880C7E0F9E097100817F82 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 33880C7F0F9E097100817F82 /* English */, - DE43468711C7295D004F095F /* da */, - DE43468611C72958004F095F /* de */, - DE43468811C7295F004F095F /* es */, - DE43468911C72964004F095F /* fr */, - DE43468A11C72967004F095F /* it */, - DE43468B11C7296B004F095F /* ja */, - DE43468C11C7296D004F095F /* nl */, - DE43468D11C7296F004F095F /* no */, - DE43468E11C72971004F095F /* sl */, - DE43468F11C72973004F095F /* sv */, - DE43469011C72976004F095F /* tr */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - F945849C0F280E3C009A47BF /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - F945849D0F280E3C009A47BF /* English */, - DE43467411C72855004F095F /* da */, - DE43467511C72857004F095F /* de */, - DE43467611C7285B004F095F /* es */, - DE43467711C72862004F095F /* fr */, - DE43467811C72869004F095F /* it */, - DE43467E11C728DC004F095F /* ja */, - DE43467911C7286D004F095F /* nl */, - DE43467A11C72873004F095F /* no */, - DE43467B11C72877004F095F /* sl */, - DE43467C11C7287A004F095F /* sv */, - DE43467F11C728E1004F095F /* tr */, - ); - name = Localizable.strings; - sourceTree = ""; - }; - F9C44DB80EF072A0003AEBAA /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - F9C44DB90EF072A0003AEBAA /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - F9C44DBA0EF072A0003AEBAA /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - F9C44DBB0EF072A0003AEBAA /* English */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 1DEB91AE08733DA50010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Framework/Breakpad_Prefix.pch; - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = Framework/Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - PRODUCT_NAME = Breakpad; - WRAPPER_EXTENSION = framework; - }; - name = Debug; - }; - 1DEB91AF08733DA50010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Framework/Breakpad_Prefix.pch; - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = Framework/Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - PRODUCT_NAME = Breakpad; - WRAPPER_EXTENSION = framework; - }; - name = Release; - }; - 1DEB91B208733DA50010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - SDKROOT = macosx10.5; - }; - name = Debug; - }; - 1DEB91B308733DA50010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - }; - name = Release; - }; - D23F4BAD12A868A600686C8D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ../..; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = minidump_generator_test_helper; - }; - name = Debug; - }; - D23F4BAE12A868A600686C8D /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = ../..; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = minidump_generator_test_helper; - }; - name = "Debug With Code Coverage"; - }; - D23F4BAF12A868A600686C8D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = ../..; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = minidump_generator_test_helper; - ZERO_LINK = NO; - }; - name = Release; - }; - D2F9A41612131EF0002747C1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PREBINDING = NO; - PRODUCT_NAME = gtest; - }; - name = Debug; - }; - D2F9A41712131EF0002747C1 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PREBINDING = NO; - PRODUCT_NAME = gtest; - }; - name = "Debug With Code Coverage"; - }; - D2F9A41812131EF0002747C1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PREBINDING = NO; - PRODUCT_NAME = gtest; - ZERO_LINK = NO; - }; - name = Release; - }; - D2F9A543121383A1002747C1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_INLINES_ARE_PRIVATE_EXTERN = NO; - GCC_PREPROCESSOR_DEFINITIONS = "BP_LOGGING_INCLUDE=\\\"client/mac/tests/testlogging.h\\\""; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = ( - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Debug\"", - ); - PRODUCT_NAME = crash_generation_server_test; - }; - name = Debug; - }; - D2F9A544121383A1002747C1 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\"$(SRCROOT)/build/Debug\\\"", - ); - PRODUCT_NAME = crash_generation_server_test; - }; - name = "Debug With Code Coverage"; - }; - D2F9A545121383A1002747C1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\"$(SRCROOT)/build/Debug\\\"", - ); - PRODUCT_NAME = crash_generation_server_test; - }; - name = Release; - }; - F92C53560ECCE34A009BE4BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = Inspector; - }; - name = Debug; - }; - F92C53570ECCE34A009BE4BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = Inspector; - }; - name = Release; - }; - F92C563D0ECD10B3009BE4BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - HEADER_SEARCH_PATHS = ../..; - LD_DYLIB_INSTALL_NAME = "@executable_path/../Resources/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-headerpad_max_install_names", - ); - PRODUCT_NAME = breakpadUtilities; - }; - name = Debug; - }; - F92C563E0ECD10B3009BE4BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - HEADER_SEARCH_PATHS = ../..; - LD_DYLIB_INSTALL_NAME = "@executable_path/../Resources/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-headerpad_max_install_names", - ); - PRODUCT_NAME = breakpadUtilities; - }; - name = Release; - }; - F92C56A30ECE04A8009BE4BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = "sender/crash_report_sender-Info.plist"; - PRODUCT_NAME = crash_report_sender; - }; - name = Debug; - }; - F92C56A40ECE04A8009BE4BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = "sender/crash_report_sender-Info.plist"; - PRODUCT_NAME = crash_report_sender; - }; - name = Release; - }; - F93803C00F808210004D428B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = "BP_LOGGING_INCLUDE=\\\"client/mac/tests/testlogging.h\\\""; - HEADER_SEARCH_PATHS = ( - ../.., - ../../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PRODUCT_NAME = generator_test; - }; - name = Debug; - }; - F93803C10F808210004D428B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../.., - ../../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PRODUCT_NAME = generator_test; - }; - name = Release; - }; - F93DE2D30F82A67400608B94 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = minidump_file_writer_unittest; - }; - name = Debug; - }; - F93DE2D40F82A67400608B94 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = minidump_file_writer_unittest; - }; - name = Release; - }; - F93DE32E0F82C55700608B94 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_INLINES_ARE_PRIVATE_EXTERN = NO; - GCC_PREPROCESSOR_DEFINITIONS = "BP_LOGGING_INCLUDE=\\\"client/mac/tests/testlogging.h\\\""; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = ( - ../../.., - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Debug\"", - ); - PRODUCT_NAME = handler_test; - }; - name = Debug; - }; - F93DE32F0F82C55700608B94 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../../.., - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Debug\"", - ); - PRODUCT_NAME = handler_test; - }; - name = Release; - }; - F93DE3B90F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BA0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Framework/Breakpad_Prefix.pch; - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = Framework/Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - PRODUCT_NAME = Breakpad; - WRAPPER_EXTENSION = framework; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BB0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = Inspector; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BC0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - HEADER_SEARCH_PATHS = ../..; - LD_DYLIB_INSTALL_NAME = "@executable_path/../Resources/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-headerpad_max_install_names", - ); - PRODUCT_NAME = breakpadUtilities; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BD0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = "sender/crash_report_sender-Info.plist"; - PRODUCT_NAME = crash_report_sender; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BE0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/build/$(CONFIGURATION)"; - INFOPLIST_FILE = testapp/Info.plist; - PRODUCT_NAME = BreakpadTest; - }; - name = "Debug With Code Coverage"; - }; - F93DE3BF0F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = All; - }; - name = "Debug With Code Coverage"; - }; - F93DE3C00F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", - ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = ../..; - INFOPLIST_FILE = "UnitTests-Info.plist"; - PRODUCT_NAME = UnitTests; - WRAPPER_EXTENSION = octest; - }; - name = "Debug With Code Coverage"; - }; - F93DE3C10F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../.., - ../../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - PRODUCT_NAME = generator_test; - }; - name = "Debug With Code Coverage"; - }; - F93DE3C20F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../..; - PRODUCT_NAME = minidump_file_writer_unittest; - }; - name = "Debug With Code Coverage"; - }; - F93DE3C30F830E7000608B94 /* Debug With Code Coverage */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../../.., - ../.., - ../../testing, - ../../testing/include, - ../../testing/gtest, - ../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Debug\"", - ); - PRODUCT_NAME = handler_test; - }; - name = "Debug With Code Coverage"; - }; - F94585850F782326009A47BF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = All; - }; - name = Debug; - }; - F94585860F782326009A47BF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = All; - }; - name = Release; - }; - F9C44DA80EF060A8003AEBAA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/build/$(CONFIGURATION)"; - INFOPLIST_FILE = testapp/Info.plist; - PRODUCT_NAME = BreakpadTest; - }; - name = Debug; - }; - F9C44DA90EF060A8003AEBAA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/build/$(CONFIGURATION)"; - INFOPLIST_FILE = testapp/Info.plist; - PRODUCT_NAME = BreakpadTest; - }; - name = Release; - }; - F9C77DDC0F7DD5D00045F7DB /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", - ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - INFOPLIST_FILE = "UnitTests-Info.plist"; - PRODUCT_NAME = UnitTests; - WRAPPER_EXTENSION = octest; - }; - name = Debug; - }; - F9C77DDD0F7DD5D00045F7DB /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", - ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - INFOPLIST_FILE = "UnitTests-Info.plist"; - PRODUCT_NAME = UnitTests; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91AE08733DA50010E9CD /* Debug */, - F93DE3BA0F830E7000608B94 /* Debug With Code Coverage */, - 1DEB91AF08733DA50010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "Breakpad" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91B208733DA50010E9CD /* Debug */, - F93DE3B90F830E7000608B94 /* Debug With Code Coverage */, - 1DEB91B308733DA50010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D23F4BB012A868C400686C8D /* Build configuration list for PBXNativeTarget "minidump_generator_test_helper" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D23F4BAD12A868A600686C8D /* Debug */, - D23F4BAE12A868A600686C8D /* Debug With Code Coverage */, - D23F4BAF12A868A600686C8D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D2F9A42D12131F0E002747C1 /* Build configuration list for PBXNativeTarget "gtest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D2F9A41612131EF0002747C1 /* Debug */, - D2F9A41712131EF0002747C1 /* Debug With Code Coverage */, - D2F9A41812131EF0002747C1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D2F9A542121383A1002747C1 /* Build configuration list for PBXNativeTarget "crash_generation_server_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D2F9A543121383A1002747C1 /* Debug */, - D2F9A544121383A1002747C1 /* Debug With Code Coverage */, - D2F9A545121383A1002747C1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F92C53580ECCE36D009BE4BA /* Build configuration list for PBXNativeTarget "Inspector" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F92C53560ECCE34A009BE4BA /* Debug */, - F93DE3BB0F830E7000608B94 /* Debug With Code Coverage */, - F92C53570ECCE34A009BE4BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F92C56670ECD11A3009BE4BA /* Build configuration list for PBXNativeTarget "breakpadUtilities" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F92C563D0ECD10B3009BE4BA /* Debug */, - F93DE3BC0F830E7000608B94 /* Debug With Code Coverage */, - F92C563E0ECD10B3009BE4BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F92C56A50ECE04A8009BE4BA /* Build configuration list for PBXNativeTarget "crash_report_sender" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F92C56A30ECE04A8009BE4BA /* Debug */, - F93DE3BD0F830E7000608B94 /* Debug With Code Coverage */, - F92C56A40ECE04A8009BE4BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F93803C40F80822E004D428B /* Build configuration list for PBXNativeTarget "generator_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F93803C00F808210004D428B /* Debug */, - F93DE3C10F830E7000608B94 /* Debug With Code Coverage */, - F93803C10F808210004D428B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F93DE2D60F82A67700608B94 /* Build configuration list for PBXNativeTarget "minidump_file_writer_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F93DE2D30F82A67400608B94 /* Debug */, - F93DE3C20F830E7000608B94 /* Debug With Code Coverage */, - F93DE2D40F82A67400608B94 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F93DE3320F82C5D800608B94 /* Build configuration list for PBXNativeTarget "handler_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F93DE32E0F82C55700608B94 /* Debug */, - F93DE3C30F830E7000608B94 /* Debug With Code Coverage */, - F93DE32F0F82C55700608B94 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F94585930F78235C009A47BF /* Build configuration list for PBXAggregateTarget "All" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F94585850F782326009A47BF /* Debug */, - F93DE3BF0F830E7000608B94 /* Debug With Code Coverage */, - F94585860F782326009A47BF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F9C44DAA0EF060A9003AEBAA /* Build configuration list for PBXNativeTarget "BreakpadTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F9C44DA80EF060A8003AEBAA /* Debug */, - F93DE3BE0F830E7000608B94 /* Debug With Code Coverage */, - F9C44DA90EF060A8003AEBAA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F9C77DDE0F7DD5D00045F7DB /* Build configuration list for PBXNativeTarget "UnitTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F9C77DDC0F7DD5D00045F7DB /* Debug */, - F93DE3C00F830E7000608B94 /* Debug With Code Coverage */, - F9C77DDD0F7DD5D00045F7DB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.h b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.h deleted file mode 100644 index dc7e45d1c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.h +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Framework to provide a simple C API to crash reporting for -// applications. By default, if any machine-level exception (e.g., -// EXC_BAD_ACCESS) occurs, it will be handled by the BreakpadRef -// object as follows: -// -// 1. Create a minidump file (see Breakpad for details) -// 2. Prompt the user (using CFUserNotification) -// 3. Invoke a command line reporting tool to send the minidump to a -// server -// -// By specifying parameters to the BreakpadCreate function, you can -// modify the default behavior to suit your needs and wants and -// desires. - -// A service name associated with the original bootstrap parent port, saved in -// OnDemandServer and restored in Inspector. -#define BREAKPAD_BOOTSTRAP_PARENT_PORT "com.Breakpad.BootstrapParent" - -typedef void *BreakpadRef; - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include "BreakpadDefines.h" - -// Optional user-defined function to dec to decide if we should handle -// this crash or forward it along. -// Return true if you want Breakpad to handle it. -// Return false if you want Breakpad to skip it -// The exception handler always returns false, as if SEND_AND_EXIT were false -// (which means the next exception handler will take the exception) -typedef bool (*BreakpadFilterCallback)(int exception_type, - int exception_code, - mach_port_t crashing_thread, - void *context); - -// Create a new BreakpadRef object and install it as an exception -// handler. The |parameters| will typically be the contents of your -// bundle's Info.plist. -// -// You can also specify these additional keys for customizable behavior: -// Key: Value: -// BREAKPAD_PRODUCT Product name (e.g., "MyAwesomeProduct") -// This one is used as the key to identify -// the product when uploading. Falls back to -// CFBundleName if not specified. -// REQUIRED -// -// BREAKPAD_PRODUCT_DISPLAY This is the display name, e.g. a pretty -// name for the product when the crash_sender -// pops up UI for the user. Falls back first to -// CFBundleDisplayName and then to -// BREAKPAD_PRODUCT if not specified. -// -// BREAKPAD_VERSION Product version (e.g., 1.2.3), used -// as metadata for crash report. Falls back to -// CFBundleVersion if not specified. -// REQUIRED -// -// BREAKPAD_VENDOR Vendor name, used in UI (e.g. "A report has -// been created that you can send to ") -// -// BREAKPAD_URL URL destination for reporting -// REQUIRED -// -// BREAKPAD_REPORT_INTERVAL # of seconds between sending -// reports. If an additional report is -// generated within this time, it will -// be ignored. Default: 3600sec. -// Specify 0 to send all reports. -// -// BREAKPAD_SKIP_CONFIRM If true, the reporter will send the report -// without any user intervention. -// Defaults to NO -// -// BREAKPAD_CONFIRM_TIMEOUT Number of seconds before the upload -// confirmation dialog will be automatically -// dismissed (cancelling the upload). -// Default: 300 seconds (min of 60). -// Specify 0 to prevent timeout. -// -// BREAKPAD_SEND_AND_EXIT If true, the handler will exit after sending. -// This will prevent any other handler (e.g., -// CrashReporter) from getting the crash. -// Defaults TO YES -// -// BREAKPAD_DUMP_DIRECTORY The directory to store crash-dumps -// in. By default, we use -// ~/Library/Breakpad/ -// The path you specify here is tilde-expanded. -// -// BREAKPAD_INSPECTOR_LOCATION The full path to the Inspector executable. -// Defaults to /Inspector -// -// BREAKPAD_REPORTER_EXE_LOCATION The full path to the Reporter/sender -// executable. -// Default: -// /crash_report_sender.app -// -// BREAKPAD_LOGFILES Indicates an array of log file paths that -// should be uploaded at crash time. -// -// BREAKPAD_REQUEST_COMMENTS If true, the message dialog will have a -// text box for the user to enter comments. -// Default: NO -// -// BREAKPAD_REQUEST_EMAIL If true and BREAKPAD_REQUEST_COMMENTS is also -// true, the message dialog will have a text -// box for the user to enter their email address. -// Default: NO -// -// BREAKPAD_SERVER_TYPE A parameter that tells Breakpad how to -// rewrite the upload parameters for a specific -// server type. The currently valid values are -// 'socorro' or 'google'. If you want to add -// other types, see the function in -// crash_report_sender.m that maps parameters to -// URL parameters. Defaults to 'google'. -// -// BREAKPAD_SERVER_PARAMETER_DICT A plist dictionary of static -// parameters that are uploaded to the -// server. The parameters are sent as -// is to the crash server. Their -// content isn't added to the minidump -// but pass as URL parameters when -// uploading theminidump to the crash -// server. -// -// BREAKPAD_IN_PROCESS A boolean NSNumber value. If YES, Breakpad -// will write the dump file in-process and then -// launch the reporter executable as a child -// process. -//============================================================================= -// The BREAKPAD_PRODUCT, BREAKPAD_VERSION and BREAKPAD_URL are -// required to have non-NULL values. By default, the BREAKPAD_PRODUCT -// will be the CFBundleName and the BREAKPAD_VERSION will be the -// CFBundleVersion when these keys are present in the bundle's -// Info.plist, which is usually passed in to BreakpadCreate() as an -// NSDictionary (you could also pass in another dictionary that had -// the same keys configured). If the BREAKPAD_PRODUCT or -// BREAKPAD_VERSION are ultimately undefined, BreakpadCreate() will -// fail. You have been warned. -// -// If you are running in a debugger, Breakpad will not install, unless the -// BREAKPAD_IGNORE_DEBUGGER envionment variable is set and/or non-zero. -// -// The BREAKPAD_SKIP_CONFIRM and BREAKPAD_SEND_AND_EXIT default -// values are NO and YES. However, they can be controlled by setting their -// values in a user or global plist. -// -// It's easiest to use Breakpad via the Framework, but if you're compiling the -// code in directly, BREAKPAD_INSPECTOR_LOCATION and -// BREAKPAD_REPORTER_EXE_LOCATION allow you to specify custom paths -// to the helper executables. -// -//============================================================================= -// The following are NOT user-supplied but are documented here for -// completeness. They are calculated by Breakpad during initialization & -// crash-dump generation, or entered in by the user. -// -// BREAKPAD_PROCESS_START_TIME The time, in seconds since the Epoch, the -// process started -// -// BREAKPAD_PROCESS_CRASH_TIME The time, in seconds since the Epoch, the -// process crashed. -// -// BREAKPAD_PROCESS_UP_TIME The total time in milliseconds the process -// has been running. This parameter is not -// set until the crash-dump-generation phase. -// -// BREAKPAD_LOGFILE_KEY_PREFIX Used to find out which parameters in the -// parameter dictionary correspond to log -// file paths. -// -// BREAKPAD_SERVER_PARAMETER_PREFIX This prefix is used by Breakpad -// internally, because Breakpad uses -// the same dictionary internally to -// track both its internal -// configuration parameters and -// parameters meant to be uploaded -// to the server. This string is -// used internally by Breakpad to -// prefix user-supplied parameter -// names so those can be sent to the -// server without leaking Breakpad's -// internal values. -// -// BREAKPAD_ON_DEMAND Used internally to indicate to the -// Reporter that we're sending on-demand, -// not as result of a crash. -// -// BREAKPAD_COMMENTS The text the user provided as comments. -// Only used in crash_report_sender. - -// Returns a new BreakpadRef object on success, NULL otherwise. -BreakpadRef BreakpadCreate(NSDictionary *parameters); - -// Uninstall and release the data associated with |ref|. -void BreakpadRelease(BreakpadRef ref); - -// Clients may set an optional callback which gets called when a crash -// occurs. The callback function should return |true| if we should -// handle the crash, generate a crash report, etc. or |false| if we -// should ignore it and forward the crash (normally to CrashReporter). -// Context is a pointer to arbitrary data to make the callback with. -void BreakpadSetFilterCallback(BreakpadRef ref, - BreakpadFilterCallback callback, - void *context); - -// User defined key and value string storage. Generally this is used -// to configure Breakpad's internal operation, such as whether the -// crash_sender should prompt the user, or the filesystem location for -// the minidump file. See Breakpad.h for some parameters that can be -// set. Anything longer than 255 bytes will be truncated. Note that -// the string is converted to UTF8 before truncation, so any multibyte -// character that straddles the 255(256 - 1 for terminator) byte limit -// will be mangled. -// -// A maximum number of 64 key/value pairs are supported. An assert() -// will fire if more than this number are set. Unfortunately, right -// now, the same dictionary is used for both Breakpad's parameters AND -// the Upload parameters. -// -// TODO (nealsid): Investigate how necessary this is if we don't -// automatically upload parameters to the server anymore. -// TODO (nealsid): separate server parameter dictionary from the -// dictionary used to configure Breakpad, and document limits for each -// independently. -void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value); -NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key); -void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key); - -// You can use this method to specify parameters that will be uploaded -// to the crash server. They will be automatically encoded as -// necessary. Note that as mentioned above there are limits on both -// the number of keys and their length. -void BreakpadAddUploadParameter(BreakpadRef ref, NSString *key, - NSString *value); - -// This method will remove a previously-added parameter from the -// upload parameter set. -void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key); - -// Add a log file for Breakpad to read and send upon crash dump -void BreakpadAddLogFile(BreakpadRef ref, NSString *logPathname); - -// Generate a minidump and send -void BreakpadGenerateAndSendReport(BreakpadRef ref); - -#ifdef __cplusplus -} -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.mm deleted file mode 100644 index 1d2e519bb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad.mm +++ /dev/null @@ -1,1043 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - - -#define IGNORE_DEBUGGER "BREAKPAD_IGNORE_DEBUGGER" - -#import "client/mac/Framework/Breakpad.h" - -#include -#import -#include -#include -#include - -#import "client/mac/crash_generation/Inspector.h" -#import "client/mac/handler/exception_handler.h" -#import "client/mac/Framework/Breakpad.h" -#import "client/mac/Framework/OnDemandServer.h" -#import "client/mac/handler/protected_memory_allocator.h" -#include "common/mac/launch_reporter.h" -#import "common/mac/MachIPC.h" -#import "common/simple_string_dictionary.h" - -#if !defined(__EXCEPTIONS) || (__clang__ && !__has_feature(cxx_exceptions)) -// This file uses C++ try/catch (but shouldn't). Duplicate the macros from -// allowing this file to work properly with -// exceptions disabled even when other C++ libraries are used. #undef the try -// and catch macros first in case libstdc++ is in use and has already provided -// its own definitions. -#undef try -#define try if (true) -#undef catch -#define catch(X) if (false) -#endif // __EXCEPTIONS - -using google_breakpad::MachPortSender; -using google_breakpad::MachReceiveMessage; -using google_breakpad::MachSendMessage; -using google_breakpad::ReceivePort; -using google_breakpad::SimpleStringDictionary; - -//============================================================================= -// We want any memory allocations which are used by breakpad during the -// exception handling process (after a crash has happened) to be read-only -// to prevent them from being smashed before a crash occurs. Unfortunately -// we cannot protect against smashes to our exception handling thread's -// stack. -// -// NOTE: Any memory allocations which are not used during the exception -// handling process may be allocated in the normal ways. -// -// The ProtectedMemoryAllocator class provides an Allocate() method which -// we'll using in conjunction with placement operator new() to control -// allocation of C++ objects. Note that we don't use operator delete() -// but instead call the objects destructor directly: object->~ClassName(); -// -ProtectedMemoryAllocator *gMasterAllocator = NULL; -ProtectedMemoryAllocator *gKeyValueAllocator = NULL; -ProtectedMemoryAllocator *gBreakpadAllocator = NULL; - -// Mutex for thread-safe access to the key/value dictionary used by breakpad. -// It's a global instead of an instance variable of Breakpad -// since it can't live in a protected memory area. -pthread_mutex_t gDictionaryMutex; - -//============================================================================= -// Stack-based object for thread-safe access to a memory-protected region. -// It's assumed that normally the memory block (allocated by the allocator) -// is protected (read-only). Creating a stack-based instance of -// ProtectedMemoryLocker will unprotect this block after taking the lock. -// Its destructor will first re-protect the memory then release the lock. -class ProtectedMemoryLocker { - public: - ProtectedMemoryLocker(pthread_mutex_t *mutex, - ProtectedMemoryAllocator *allocator) - : mutex_(mutex), - allocator_(allocator) { - // Lock the mutex - __attribute__((unused)) int rv = pthread_mutex_lock(mutex_); - assert(rv == 0); - - // Unprotect the memory - allocator_->Unprotect(); - } - - ~ProtectedMemoryLocker() { - // First protect the memory - allocator_->Protect(); - - // Then unlock the mutex - __attribute__((unused)) int rv = pthread_mutex_unlock(mutex_); - assert(rv == 0); - }; - - private: - ProtectedMemoryLocker(); - ProtectedMemoryLocker(const ProtectedMemoryLocker&); - ProtectedMemoryLocker& operator=(const ProtectedMemoryLocker&); - - pthread_mutex_t *mutex_; - ProtectedMemoryAllocator *allocator_; -}; - -//============================================================================= -class Breakpad { - public: - // factory method - static Breakpad *Create(NSDictionary *parameters) { - // Allocate from our special allocation pool - Breakpad *breakpad = - new (gBreakpadAllocator->Allocate(sizeof(Breakpad))) - Breakpad(); - - if (!breakpad) - return NULL; - - if (!breakpad->Initialize(parameters)) { - // Don't use operator delete() here since we allocated from special pool - breakpad->~Breakpad(); - return NULL; - } - - return breakpad; - } - - ~Breakpad(); - - void SetKeyValue(NSString *key, NSString *value); - NSString *KeyValue(NSString *key); - void RemoveKeyValue(NSString *key); - - void GenerateAndSendReport(); - - void SetFilterCallback(BreakpadFilterCallback callback, void *context) { - filter_callback_ = callback; - filter_callback_context_ = context; - } - - private: - Breakpad() - : handler_(NULL), - config_params_(NULL), - send_and_exit_(true), - filter_callback_(NULL), - filter_callback_context_(NULL) { - inspector_path_[0] = 0; - } - - bool Initialize(NSDictionary *parameters); - bool InitializeInProcess(NSDictionary *parameters); - bool InitializeOutOfProcess(NSDictionary *parameters); - - bool ExtractParameters(NSDictionary *parameters); - - // Dispatches to HandleException() - static bool ExceptionHandlerDirectCallback(void *context, - int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread); - - bool HandleException(int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread); - - // Dispatches to HandleMinidump(). - // This gets called instead of ExceptionHandlerDirectCallback when running - // with the BREAKPAD_IN_PROCESS option. - static bool HandleMinidumpCallback(const char *dump_dir, - const char *minidump_id, - void *context, - bool succeeded); - - // This is only used when BREAKPAD_IN_PROCESS is YES. - bool HandleMinidump(const char *dump_dir, const char *minidump_id); - - // Since ExceptionHandler (w/o namespace) is defined as typedef in OSX's - // MachineExceptions.h, we have to explicitly name the handler. - google_breakpad::ExceptionHandler *handler_; // The actual handler (STRONG) - - char inspector_path_[PATH_MAX]; // Path to inspector tool - - SimpleStringDictionary *config_params_; // Create parameters (STRONG) - - OnDemandServer inspector_; - - bool send_and_exit_; // Exit after sending, if true - - BreakpadFilterCallback filter_callback_; - void *filter_callback_context_; -}; - -#pragma mark - -#pragma mark Helper functions - -//============================================================================= -// Helper functions - -//============================================================================= -static BOOL IsDebuggerActive() { - BOOL result = NO; - NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults]; - - // We check both defaults and the environment variable here - - BOOL ignoreDebugger = [stdDefaults boolForKey:@IGNORE_DEBUGGER]; - - if (!ignoreDebugger) { - char *ignoreDebuggerStr = getenv(IGNORE_DEBUGGER); - ignoreDebugger = (ignoreDebuggerStr ? strtol(ignoreDebuggerStr, NULL, 10) : 0) != 0; - } - - if (!ignoreDebugger) { - pid_t pid = getpid(); - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - int mibSize = sizeof(mib) / sizeof(int); - size_t actualSize; - - if (sysctl(mib, mibSize, NULL, &actualSize, NULL, 0) == 0) { - struct kinfo_proc *info = (struct kinfo_proc *)malloc(actualSize); - - if (info) { - // This comes from looking at the Darwin xnu Kernel - if (sysctl(mib, mibSize, info, &actualSize, NULL, 0) == 0) - result = (info->kp_proc.p_flag & P_TRACED) ? YES : NO; - - free(info); - } - } - } - - return result; -} - -//============================================================================= -bool Breakpad::ExceptionHandlerDirectCallback(void *context, - int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread) { - Breakpad *breakpad = (Breakpad *)context; - - // If our context is damaged or something, just return false to indicate that - // the handler should continue without us. - if (!breakpad) - return false; - - return breakpad->HandleException( exception_type, - exception_code, - exception_subcode, - crashing_thread); -} - -//============================================================================= -bool Breakpad::HandleMinidumpCallback(const char *dump_dir, - const char *minidump_id, - void *context, - bool succeeded) { - Breakpad *breakpad = (Breakpad *)context; - - // If our context is damaged or something, just return false to indicate that - // the handler should continue without us. - if (!breakpad || !succeeded) - return false; - - return breakpad->HandleMinidump(dump_dir, minidump_id); -} - -//============================================================================= -#pragma mark - - -#include - -//============================================================================= -// Returns the pathname to the Resources directory for this version of -// Breakpad which we are now running. -// -// Don't make the function static, since _dyld_lookup_and_bind_fully needs a -// simple non-static C name -// -extern "C" { -NSString * GetResourcePath(); -NSString * GetResourcePath() { - NSString *resourcePath = nil; - - // If there are multiple breakpads installed then calling bundleWithIdentifier - // will not work properly, so only use that as a backup plan. - // We want to find the bundle containing the code where this function lives - // and work from there - // - - // Get the pathname to the code which contains this function - Dl_info info; - if (dladdr((const void*)GetResourcePath, &info) != 0) { - NSFileManager *filemgr = [NSFileManager defaultManager]; - NSString *filePath = - [filemgr stringWithFileSystemRepresentation:info.dli_fname - length:strlen(info.dli_fname)]; - NSString *bundlePath = [filePath stringByDeletingLastPathComponent]; - // The "Resources" directory should be in the same directory as the - // executable code, since that's how the Breakpad framework is built. - resourcePath = [bundlePath stringByAppendingPathComponent:@"Resources/"]; - } else { - // fallback plan - NSBundle *bundle = - [NSBundle bundleWithIdentifier:@"com.Google.BreakpadFramework"]; - resourcePath = [bundle resourcePath]; - } - - return resourcePath; -} -} // extern "C" - -//============================================================================= -bool Breakpad::Initialize(NSDictionary *parameters) { - // Initialize - config_params_ = NULL; - handler_ = NULL; - - // Check for debugger - if (IsDebuggerActive()) { - return true; - } - - // Gather any user specified parameters - if (!ExtractParameters(parameters)) { - return false; - } - - if ([[parameters objectForKey:@BREAKPAD_IN_PROCESS] boolValue]) - return InitializeInProcess(parameters); - else - return InitializeOutOfProcess(parameters); -} - -//============================================================================= -bool Breakpad::InitializeInProcess(NSDictionary* parameters) { - handler_ = - new (gBreakpadAllocator->Allocate( - sizeof(google_breakpad::ExceptionHandler))) - google_breakpad::ExceptionHandler( - config_params_->GetValueForKey(BREAKPAD_DUMP_DIRECTORY), - 0, &HandleMinidumpCallback, this, true, 0); - return true; -} - -//============================================================================= -bool Breakpad::InitializeOutOfProcess(NSDictionary* parameters) { - // Get path to Inspector executable. - NSString *inspectorPathString = KeyValue(@BREAKPAD_INSPECTOR_LOCATION); - - // Standardize path (resolve symlinkes, etc.) and escape spaces - inspectorPathString = [inspectorPathString stringByStandardizingPath]; - inspectorPathString = [[inspectorPathString componentsSeparatedByString:@" "] - componentsJoinedByString:@"\\ "]; - - // Create an on-demand server object representing the Inspector. - // In case of a crash, we simply need to call the LaunchOnDemand() - // method on it, then send a mach message to its service port. - // It will then launch and perform a process inspection of our crashed state. - // See the HandleException() method for the details. -#define RECEIVE_PORT_NAME "com.Breakpad.Inspector" - - name_t portName; - snprintf(portName, sizeof(name_t), "%s%d", RECEIVE_PORT_NAME, getpid()); - - // Save the location of the Inspector - strlcpy(inspector_path_, [inspectorPathString fileSystemRepresentation], - sizeof(inspector_path_)); - - // Append a single command-line argument to the Inspector path - // representing the bootstrap name of the launch-on-demand receive port. - // When the Inspector is launched, it can use this to lookup the port - // by calling bootstrap_check_in(). - strlcat(inspector_path_, " ", sizeof(inspector_path_)); - strlcat(inspector_path_, portName, sizeof(inspector_path_)); - - kern_return_t kr = inspector_.Initialize(inspector_path_, - portName, - true); // shutdown on exit - - if (kr != KERN_SUCCESS) { - return false; - } - - // Create the handler (allocating it in our special protected pool) - handler_ = - new (gBreakpadAllocator->Allocate( - sizeof(google_breakpad::ExceptionHandler))) - google_breakpad::ExceptionHandler( - Breakpad::ExceptionHandlerDirectCallback, this, true); - return true; -} - -//============================================================================= -Breakpad::~Breakpad() { - // Note that we don't use operator delete() on these pointers, - // since they were allocated by ProtectedMemoryAllocator objects. - // - if (config_params_) { - config_params_->~SimpleStringDictionary(); - } - - if (handler_) - handler_->~ExceptionHandler(); -} - -//============================================================================= -bool Breakpad::ExtractParameters(NSDictionary *parameters) { - NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults]; - NSString *skipConfirm = [stdDefaults stringForKey:@BREAKPAD_SKIP_CONFIRM]; - NSString *sendAndExit = [stdDefaults stringForKey:@BREAKPAD_SEND_AND_EXIT]; - - NSString *serverType = [parameters objectForKey:@BREAKPAD_SERVER_TYPE]; - NSString *display = [parameters objectForKey:@BREAKPAD_PRODUCT_DISPLAY]; - NSString *product = [parameters objectForKey:@BREAKPAD_PRODUCT]; - NSString *version = [parameters objectForKey:@BREAKPAD_VERSION]; - NSString *urlStr = [parameters objectForKey:@BREAKPAD_URL]; - NSString *interval = [parameters objectForKey:@BREAKPAD_REPORT_INTERVAL]; - NSString *inspectorPathString = - [parameters objectForKey:@BREAKPAD_INSPECTOR_LOCATION]; - NSString *reporterPathString = - [parameters objectForKey:@BREAKPAD_REPORTER_EXE_LOCATION]; - NSString *timeout = [parameters objectForKey:@BREAKPAD_CONFIRM_TIMEOUT]; - NSArray *logFilePaths = [parameters objectForKey:@BREAKPAD_LOGFILES]; - NSString *logFileTailSize = - [parameters objectForKey:@BREAKPAD_LOGFILE_UPLOAD_SIZE]; - NSString *requestUserText = - [parameters objectForKey:@BREAKPAD_REQUEST_COMMENTS]; - NSString *requestEmail = [parameters objectForKey:@BREAKPAD_REQUEST_EMAIL]; - NSString *vendor = - [parameters objectForKey:@BREAKPAD_VENDOR]; - NSString *dumpSubdirectory = - [parameters objectForKey:@BREAKPAD_DUMP_DIRECTORY]; - - NSDictionary *serverParameters = - [parameters objectForKey:@BREAKPAD_SERVER_PARAMETER_DICT]; - - // These may have been set above as user prefs, which take priority. - if (!skipConfirm) { - skipConfirm = [parameters objectForKey:@BREAKPAD_SKIP_CONFIRM]; - } - if (!sendAndExit) { - sendAndExit = [parameters objectForKey:@BREAKPAD_SEND_AND_EXIT]; - } - - if (!product) - product = [parameters objectForKey:@"CFBundleName"]; - - if (!display) { - display = [parameters objectForKey:@"CFBundleDisplayName"]; - if (!display) { - display = product; - } - } - - if (!version) - version = [parameters objectForKey:@"CFBundleVersion"]; - - if (!interval) - interval = @"3600"; - - if (!timeout) - timeout = @"300"; - - if (!logFileTailSize) - logFileTailSize = @"200000"; - - if (!vendor) { - vendor = @"Vendor not specified"; - } - - // Normalize the values. - if (skipConfirm) { - skipConfirm = [skipConfirm uppercaseString]; - - if ([skipConfirm isEqualToString:@"YES"] || - [skipConfirm isEqualToString:@"TRUE"] || - [skipConfirm isEqualToString:@"1"]) - skipConfirm = @"YES"; - else - skipConfirm = @"NO"; - } else { - skipConfirm = @"NO"; - } - - send_and_exit_ = true; - if (sendAndExit) { - sendAndExit = [sendAndExit uppercaseString]; - - if ([sendAndExit isEqualToString:@"NO"] || - [sendAndExit isEqualToString:@"FALSE"] || - [sendAndExit isEqualToString:@"0"]) - send_and_exit_ = false; - } - - if (requestUserText) { - requestUserText = [requestUserText uppercaseString]; - - if ([requestUserText isEqualToString:@"YES"] || - [requestUserText isEqualToString:@"TRUE"] || - [requestUserText isEqualToString:@"1"]) - requestUserText = @"YES"; - else - requestUserText = @"NO"; - } else { - requestUserText = @"NO"; - } - - // Find the helper applications if not specified in user config. - NSString *resourcePath = nil; - if (!inspectorPathString || !reporterPathString) { - resourcePath = GetResourcePath(); - if (!resourcePath) { - return false; - } - } - - // Find Inspector. - if (!inspectorPathString) { - inspectorPathString = - [resourcePath stringByAppendingPathComponent:@"Inspector"]; - } - - // Verify that there is an Inspector tool. - if (![[NSFileManager defaultManager] fileExistsAtPath:inspectorPathString]) { - return false; - } - - // Find Reporter. - if (!reporterPathString) { - reporterPathString = - [resourcePath - stringByAppendingPathComponent:@"crash_report_sender.app"]; - reporterPathString = - [[NSBundle bundleWithPath:reporterPathString] executablePath]; - } - - // Verify that there is a Reporter application. - if (![[NSFileManager defaultManager] - fileExistsAtPath:reporterPathString]) { - return false; - } - - if (!dumpSubdirectory) { - dumpSubdirectory = @""; - } - - // The product, version, and URL are required values. - if (![product length]) { - return false; - } - - if (![version length]) { - return false; - } - - if (![urlStr length]) { - return false; - } - - config_params_ = - new (gKeyValueAllocator->Allocate(sizeof(SimpleStringDictionary)) ) - SimpleStringDictionary(); - - SimpleStringDictionary &dictionary = *config_params_; - - dictionary.SetKeyValue(BREAKPAD_SERVER_TYPE, [serverType UTF8String]); - dictionary.SetKeyValue(BREAKPAD_PRODUCT_DISPLAY, [display UTF8String]); - dictionary.SetKeyValue(BREAKPAD_PRODUCT, [product UTF8String]); - dictionary.SetKeyValue(BREAKPAD_VERSION, [version UTF8String]); - dictionary.SetKeyValue(BREAKPAD_URL, [urlStr UTF8String]); - dictionary.SetKeyValue(BREAKPAD_REPORT_INTERVAL, [interval UTF8String]); - dictionary.SetKeyValue(BREAKPAD_SKIP_CONFIRM, [skipConfirm UTF8String]); - dictionary.SetKeyValue(BREAKPAD_CONFIRM_TIMEOUT, [timeout UTF8String]); - dictionary.SetKeyValue(BREAKPAD_INSPECTOR_LOCATION, - [inspectorPathString fileSystemRepresentation]); - dictionary.SetKeyValue(BREAKPAD_REPORTER_EXE_LOCATION, - [reporterPathString fileSystemRepresentation]); - dictionary.SetKeyValue(BREAKPAD_LOGFILE_UPLOAD_SIZE, - [logFileTailSize UTF8String]); - dictionary.SetKeyValue(BREAKPAD_REQUEST_COMMENTS, - [requestUserText UTF8String]); - dictionary.SetKeyValue(BREAKPAD_REQUEST_EMAIL, [requestEmail UTF8String]); - dictionary.SetKeyValue(BREAKPAD_VENDOR, [vendor UTF8String]); - dictionary.SetKeyValue(BREAKPAD_DUMP_DIRECTORY, - [dumpSubdirectory UTF8String]); - - struct timeval tv; - gettimeofday(&tv, NULL); - char timeStartedString[32]; - sprintf(timeStartedString, "%zd", tv.tv_sec); - dictionary.SetKeyValue(BREAKPAD_PROCESS_START_TIME, - timeStartedString); - - if (logFilePaths) { - char logFileKey[255]; - for(unsigned int i = 0; i < [logFilePaths count]; i++) { - sprintf(logFileKey,"%s%d", BREAKPAD_LOGFILE_KEY_PREFIX, i); - dictionary.SetKeyValue(logFileKey, - [[logFilePaths objectAtIndex:i] - fileSystemRepresentation]); - } - } - - if (serverParameters) { - // For each key-value pair, call BreakpadAddUploadParameter() - NSEnumerator *keyEnumerator = [serverParameters keyEnumerator]; - NSString *aParameter; - while ((aParameter = [keyEnumerator nextObject])) { - BreakpadAddUploadParameter(this, aParameter, - [serverParameters objectForKey:aParameter]); - } - } - return true; -} - -//============================================================================= -void Breakpad::SetKeyValue(NSString *key, NSString *value) { - // We allow nil values. This is the same as removing the keyvalue. - if (!config_params_ || !key) - return; - - config_params_->SetKeyValue([key UTF8String], [value UTF8String]); -} - -//============================================================================= -NSString *Breakpad::KeyValue(NSString *key) { - if (!config_params_ || !key) - return nil; - - const char *value = config_params_->GetValueForKey([key UTF8String]); - return value ? [NSString stringWithUTF8String:value] : nil; -} - -//============================================================================= -void Breakpad::RemoveKeyValue(NSString *key) { - if (!config_params_ || !key) return; - - config_params_->RemoveKey([key UTF8String]); -} - -//============================================================================= -void Breakpad::GenerateAndSendReport() { - config_params_->SetKeyValue(BREAKPAD_ON_DEMAND, "YES"); - HandleException(0, 0, 0, mach_thread_self()); - config_params_->SetKeyValue(BREAKPAD_ON_DEMAND, "NO"); -} - -//============================================================================= -bool Breakpad::HandleException(int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread) { - if (filter_callback_) { - bool should_handle = filter_callback_(exception_type, - exception_code, - crashing_thread, - filter_callback_context_); - if (!should_handle) return false; - } - - // We need to reset the memory protections to be read/write, - // since LaunchOnDemand() requires changing state. - gBreakpadAllocator->Unprotect(); - // Configure the server to launch when we message the service port. - // The reason we do this here, rather than at startup, is that we - // can leak a bootstrap service entry if this method is called and - // there never ends up being a crash. - inspector_.LaunchOnDemand(); - gBreakpadAllocator->Protect(); - - // The Inspector should send a message to this port to verify it - // received our information and has finished the inspection. - ReceivePort acknowledge_port; - - // Send initial information to the Inspector. - MachSendMessage message(kMsgType_InspectorInitialInfo); - message.AddDescriptor(mach_task_self()); // our task - message.AddDescriptor(crashing_thread); // crashing thread - message.AddDescriptor(mach_thread_self()); // exception-handling thread - message.AddDescriptor(acknowledge_port.GetPort());// message receive port - - InspectorInfo info; - info.exception_type = exception_type; - info.exception_code = exception_code; - info.exception_subcode = exception_subcode; - info.parameter_count = config_params_->GetCount(); - message.SetData(&info, sizeof(info)); - - MachPortSender sender(inspector_.GetServicePort()); - - kern_return_t result = sender.SendMessage(message, 2000); - - if (result == KERN_SUCCESS) { - // Now, send a series of key-value pairs to the Inspector. - const SimpleStringDictionary::Entry *entry = NULL; - SimpleStringDictionary::Iterator iter(*config_params_); - - while ( (entry = iter.Next()) ) { - KeyValueMessageData keyvalue_data(*entry); - - MachSendMessage keyvalue_message(kMsgType_InspectorKeyValuePair); - keyvalue_message.SetData(&keyvalue_data, sizeof(keyvalue_data)); - - result = sender.SendMessage(keyvalue_message, 2000); - - if (result != KERN_SUCCESS) { - break; - } - } - - if (result == KERN_SUCCESS) { - // Wait for acknowledgement that the inspection has finished. - MachReceiveMessage acknowledge_messsage; - result = acknowledge_port.WaitForMessage(&acknowledge_messsage, 5000); - } - } - -#if VERBOSE - PRINT_MACH_RESULT(result, "Breakpad: SendMessage "); - printf("Breakpad: Inspector service port = %#x\n", - inspector_.GetServicePort()); -#endif - - // If we don't want any forwarding, return true here to indicate that we've - // processed things as much as we want. - if (send_and_exit_) return true; - - return false; -} - -//============================================================================= -bool Breakpad::HandleMinidump(const char *dump_dir, const char *minidump_id) { - google_breakpad::ConfigFile config_file; - config_file.WriteFile(dump_dir, config_params_, dump_dir, minidump_id); - google_breakpad::LaunchReporter( - config_params_->GetValueForKey(BREAKPAD_REPORTER_EXE_LOCATION), - config_file.GetFilePath()); - return true; -} - -//============================================================================= -//============================================================================= - -#pragma mark - -#pragma mark Public API - -//============================================================================= -BreakpadRef BreakpadCreate(NSDictionary *parameters) { - try { - // This is confusing. Our two main allocators for breakpad memory are: - // - gKeyValueAllocator for the key/value memory - // - gBreakpadAllocator for the Breakpad, ExceptionHandler, and other - // breakpad allocations which are accessed at exception handling time. - // - // But in order to avoid these two allocators themselves from being smashed, - // we'll protect them as well by allocating them with gMasterAllocator. - // - // gMasterAllocator itself will NOT be protected, but this doesn't matter, - // since once it does its allocations and locks the memory, smashes to itself - // don't affect anything we care about. - gMasterAllocator = - new ProtectedMemoryAllocator(sizeof(ProtectedMemoryAllocator) * 2); - - gKeyValueAllocator = - new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator))) - ProtectedMemoryAllocator(sizeof(SimpleStringDictionary)); - - // Create a mutex for use in accessing the SimpleStringDictionary - int mutexResult = pthread_mutex_init(&gDictionaryMutex, NULL); - if (mutexResult == 0) { - - // With the current compiler, gBreakpadAllocator is allocating 1444 bytes. - // Let's round up to the nearest page size. - // - int breakpad_pool_size = 4096; - - /* - sizeof(Breakpad) - + sizeof(google_breakpad::ExceptionHandler) - + sizeof( STUFF ALLOCATED INSIDE ExceptionHandler ) - */ - - gBreakpadAllocator = - new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator))) - ProtectedMemoryAllocator(breakpad_pool_size); - - // Stack-based autorelease pool for Breakpad::Create() obj-c code. - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Breakpad *breakpad = Breakpad::Create(parameters); - - if (breakpad) { - // Make read-only to protect against memory smashers - gMasterAllocator->Protect(); - gKeyValueAllocator->Protect(); - gBreakpadAllocator->Protect(); - // Can uncomment this line to figure out how much space was actually - // allocated using this allocator - // printf("gBreakpadAllocator allocated size = %d\n", - // gBreakpadAllocator->GetAllocatedSize() ); - [pool release]; - return (BreakpadRef)breakpad; - } - - [pool release]; - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadCreate() : error\n"); - } - - if (gKeyValueAllocator) { - gKeyValueAllocator->~ProtectedMemoryAllocator(); - gKeyValueAllocator = NULL; - } - - if (gBreakpadAllocator) { - gBreakpadAllocator->~ProtectedMemoryAllocator(); - gBreakpadAllocator = NULL; - } - - delete gMasterAllocator; - gMasterAllocator = NULL; - - return NULL; -} - -//============================================================================= -void BreakpadRelease(BreakpadRef ref) { - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (gMasterAllocator) { - gMasterAllocator->Unprotect(); - gKeyValueAllocator->Unprotect(); - gBreakpadAllocator->Unprotect(); - - breakpad->~Breakpad(); - - // Unfortunately, it's not possible to deallocate this stuff - // because the exception handling thread is still finishing up - // asynchronously at this point... OK, it could be done with - // locks, etc. But since BreakpadRelease() should usually only - // be called right before the process exits, it's not worth - // deallocating this stuff. -#if 0 - gKeyValueAllocator->~ProtectedMemoryAllocator(); - gBreakpadAllocator->~ProtectedMemoryAllocator(); - delete gMasterAllocator; - - gMasterAllocator = NULL; - gKeyValueAllocator = NULL; - gBreakpadAllocator = NULL; -#endif - - pthread_mutex_destroy(&gDictionaryMutex); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRelease() : error\n"); - } -} - -//============================================================================= -void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - breakpad->SetKeyValue(key, value); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadSetKeyValue() : error\n"); - } -} - -void BreakpadAddUploadParameter(BreakpadRef ref, - NSString *key, - NSString *value) { - // The only difference, internally, between an upload parameter and - // a key value one that is set with BreakpadSetKeyValue is that we - // prepend the keyname with a special prefix. This informs the - // crash sender that the parameter should be sent along with the - // POST of the crash dump upload. - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - NSString *prefixedKey = [@BREAKPAD_SERVER_PARAMETER_PREFIX - stringByAppendingString:key]; - breakpad->SetKeyValue(prefixedKey, value); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadSetKeyValue() : error\n"); - } -} - -void BreakpadRemoveUploadParameter(BreakpadRef ref, - NSString *key) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - NSString *prefixedKey = [NSString stringWithFormat:@"%@%@", - @BREAKPAD_SERVER_PARAMETER_PREFIX, key]; - breakpad->RemoveKeyValue(prefixedKey); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRemoveKeyValue() : error\n"); - } -} -//============================================================================= -NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key) { - NSString *value = nil; - - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (!breakpad || !key || !gKeyValueAllocator) - return nil; - - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - value = breakpad->KeyValue(key); - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadKeyValue() : error\n"); - } - - return value; -} - -//============================================================================= -void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key) { - try { - // Not called at exception time - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && key && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - breakpad->RemoveKeyValue(key); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadRemoveKeyValue() : error\n"); - } -} - -//============================================================================= -void BreakpadGenerateAndSendReport(BreakpadRef ref) { - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && gKeyValueAllocator) { - ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator); - - gBreakpadAllocator->Unprotect(); - breakpad->GenerateAndSendReport(); - gBreakpadAllocator->Protect(); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadGenerateAndSendReport() : error\n"); - } -} - -//============================================================================= -void BreakpadSetFilterCallback(BreakpadRef ref, - BreakpadFilterCallback callback, - void *context) { - - try { - Breakpad *breakpad = (Breakpad *)ref; - - if (breakpad && gBreakpadAllocator) { - // share the dictionary mutex here (we really don't need a mutex) - ProtectedMemoryLocker locker(&gDictionaryMutex, gBreakpadAllocator); - - breakpad->SetFilterCallback(callback, context); - } - } catch(...) { // don't let exceptions leave this C API - fprintf(stderr, "BreakpadSetFilterCallback() : error\n"); - } -} - -//============================================================================ -void BreakpadAddLogFile(BreakpadRef ref, NSString *logPathname) { - int logFileCounter = 0; - - NSString *logFileKey = [NSString stringWithFormat:@"%@%d", - @BREAKPAD_LOGFILE_KEY_PREFIX, - logFileCounter]; - - NSString *existingLogFilename = nil; - existingLogFilename = BreakpadKeyValue(ref, logFileKey); - // Find the first log file key that we can use by testing for existence - while (existingLogFilename) { - if ([existingLogFilename isEqualToString:logPathname]) { - return; - } - logFileCounter++; - logFileKey = [NSString stringWithFormat:@"%@%d", - @BREAKPAD_LOGFILE_KEY_PREFIX, - logFileCounter]; - existingLogFilename = BreakpadKeyValue(ref, logFileKey); - } - - BreakpadSetKeyValue(ref, logFileKey, logPathname); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad_Prefix.pch b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad_Prefix.pch deleted file mode 100644 index 729866635..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Breakpad_Prefix.pch +++ /dev/null @@ -1,8 +0,0 @@ -// -// Prefix header for all source files of the 'Breakpad' target in the -// 'Breakpad' project. -// - -#ifdef __OBJC__ - #import -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Info.plist deleted file mode 100644 index e43baddc0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleName - ${PRODUCT_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.googlecode.google-breakpad - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - FMWK - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSPrincipalClass - - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h deleted file mode 100644 index b8aabbe47..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include - -//============================================================================== -// class OnDemandServer : -// A basic on-demand server launcher supporting a single named service port -// -// Example Usage : -// -// kern_return_t result; -// OnDemandServer *server = OnDemandServer::Create("/tmp/myserver", -// "com.MyCompany.MyServiceName", -// true, -// &result); -// -// if (server) { -// server->LaunchOnDemand(); -// mach_port_t service_port = GetServicePort(); -// -// // Send a mach message to service_port and "myserver" will be launched -// } -// -// -// ---- Now in the server code ---- -// -// // "myserver" should get the service port and read the message which -// // launched it: -// mach_port_t service_rcv_port_; -// kern_return_t kr = bootstrap_check_in(bootstrap_port, -// "com.MyCompany.MyServiceName", -// &service_rcv_port_); -// // mach_msg() read service_rcv_port_ .... -// -// .... -// -// // Later "myserver" may want to unregister the service if it doesn't -// // want its bootstrap service to stick around after it exits. -// -// // DO NOT use mach_port_deallocate() here -- it will fail and the -// // following bootstrap_register() will also fail leaving our service -// // name hanging around forever (until reboot) -// kern_return_t kr = mach_port_destroy(mach_task_self(), service_rcv_port_); -// -// kr = bootstrap_register(bootstrap_port, -// "com.MyCompany.MyServiceName", -// MACH_PORT_NULL); - -class OnDemandServer { - public: - // must call Initialize() to be useful - OnDemandServer() - : server_port_(MACH_PORT_NULL), - service_port_(MACH_PORT_NULL), - unregister_on_cleanup_(true) { - } - - // Creates the bootstrap server and service - kern_return_t Initialize(const char *server_command, - const char *service_name, - bool unregister_on_cleanup); - - // Returns an OnDemandServer object if successful, or NULL if there's - // an error. The error result will be returned in out_result. - // - // server_command : the full path name including optional command-line - // arguments to the executable representing the server - // - // service_name : represents service name - // something like "com.company.ServiceName" - // - // unregister_on_cleanup : if true, unregisters the service name - // when the OnDemandServer is deleted -- unregistering will - // ONLY be possible if LaunchOnDemand() has NOT been called. - // If false, then the service will continue to be registered - // even after the current process quits. - // - // out_result : if non-NULL, returns the result - // this value will be KERN_SUCCESS if Create() returns non-NULL - // - static OnDemandServer *Create(const char *server_command, - const char *service_name, - bool unregister_on_cleanup, - kern_return_t *out_result); - - // Cleans up and if LaunchOnDemand() has not yet been called then - // the bootstrap service will be unregistered. - ~OnDemandServer(); - - // This must be called if we intend to commit to launching the server - // by sending a mach message to our service port. Do not call it otherwise - // or it will be difficult (impossible?) to unregister the service name. - void LaunchOnDemand(); - - // This is the port we need to send a mach message to after calling - // LaunchOnDemand(). Sending a message causing an immediate launch - // of the server - mach_port_t GetServicePort() { return service_port_; }; - - private: - // Disallow copy constructor - OnDemandServer(const OnDemandServer&); - - // Cleans up and if LaunchOnDemand() has not yet been called then - // the bootstrap service will be unregistered. - void Unregister(); - - name_t service_name_; - - mach_port_t server_port_; - mach_port_t service_port_; - bool unregister_on_cleanup_; -}; diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.mm deleted file mode 100644 index dbe601bb8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.mm +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import "OnDemandServer.h" - -#import "Breakpad.h" -#include "common/mac/bootstrap_compat.h" - -#if DEBUG - #define PRINT_MACH_RESULT(result_, message_) \ - printf(message_"%s (%d)\n", mach_error_string(result_), result_ ); -#if defined(MAC_OS_X_VERSION_10_5) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - #define PRINT_BOOTSTRAP_RESULT(result_, message_) \ - printf(message_"%s (%d)\n", bootstrap_strerror(result_), result_ ); -#else - #define PRINT_BOOTSTRAP_RESULT(result_, message_) \ - PRINT_MACH_RESULT(result_, message_) -#endif -#else - #define PRINT_MACH_RESULT(result_, message_) - #define PRINT_BOOTSTRAP_RESULT(result_, message_) -#endif - -//============================================================================== -OnDemandServer *OnDemandServer::Create(const char *server_command, - const char *service_name, - bool unregister_on_cleanup, - kern_return_t *out_result) { - OnDemandServer *server = new OnDemandServer(); - - if (!server) return NULL; - - kern_return_t result = server->Initialize(server_command, - service_name, - unregister_on_cleanup); - - if (out_result) { - *out_result = result; - } - - if (result == KERN_SUCCESS) { - return server; - } - - delete server; - return NULL; -}; - -//============================================================================== -kern_return_t OnDemandServer::Initialize(const char *server_command, - const char *service_name, - bool unregister_on_cleanup) { - unregister_on_cleanup_ = unregister_on_cleanup; - - mach_port_t self_task = mach_task_self(); - - mach_port_t bootstrap_port; - kern_return_t kr = task_get_bootstrap_port(self_task, &bootstrap_port); - if (kr != KERN_SUCCESS) { - PRINT_MACH_RESULT(kr, "task_get_bootstrap_port(): "); - return kr; - } - - mach_port_t bootstrap_subset_port; - kr = bootstrap_subset(bootstrap_port, self_task, &bootstrap_subset_port); - if (kr != BOOTSTRAP_SUCCESS) { - PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_subset(): "); - return kr; - } - - // The inspector will be invoked with its bootstrap port set to the subset, - // but the sender will need access to the original bootstrap port. Although - // the original port is the subset's parent, bootstrap_parent can't be used - // because it requires extra privileges. Stash the original bootstrap port - // in the subset by registering it under a known name. The inspector will - // recover this port and set it as its own bootstrap port in Inspector.mm - // Inspector::ResetBootstrapPort. - kr = breakpad::BootstrapRegister( - bootstrap_subset_port, - const_cast(BREAKPAD_BOOTSTRAP_PARENT_PORT), - bootstrap_port); - if (kr != BOOTSTRAP_SUCCESS) { - PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_register(): "); - return kr; - } - - kr = bootstrap_create_server(bootstrap_subset_port, - const_cast(server_command), - geteuid(), // server uid - true, - &server_port_); - if (kr != BOOTSTRAP_SUCCESS) { - PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_create_server(): "); - return kr; - } - - strlcpy(service_name_, service_name, sizeof(service_name_)); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - // Create a service called service_name, and return send rights to - // that port in service_port_. - kr = bootstrap_create_service(server_port_, - const_cast(service_name), - &service_port_); -#pragma clang diagnostic pop - if (kr != BOOTSTRAP_SUCCESS) { - PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_create_service(): "); - - // perhaps the service has already been created - try to look it up - kr = bootstrap_look_up(bootstrap_port, (char*)service_name, &service_port_); - - if (kr != BOOTSTRAP_SUCCESS) { - PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_look_up(): "); - Unregister(); // clean up server port - return kr; - } - } - - return KERN_SUCCESS; -} - -//============================================================================== -OnDemandServer::~OnDemandServer() { - if (unregister_on_cleanup_) { - Unregister(); - } -} - -//============================================================================== -void OnDemandServer::LaunchOnDemand() { - // We need to do this, since the launched server is another process - // and holding on to this port delays launching until the current process - // exits! - mach_port_deallocate(mach_task_self(), server_port_); - server_port_ = MACH_PORT_DEAD; - - // Now, the service is still registered and all we need to do is send - // a mach message to the service port in order to launch the server. -} - -//============================================================================== -void OnDemandServer::Unregister() { - if (service_port_ != MACH_PORT_NULL) { - mach_port_deallocate(mach_task_self(), service_port_); - service_port_ = MACH_PORT_NULL; - } - - if (server_port_ != MACH_PORT_NULL) { - // unregister the service - kern_return_t kr = breakpad::BootstrapRegister(server_port_, - service_name_, - MACH_PORT_NULL); - - if (kr != KERN_SUCCESS) { - PRINT_MACH_RESULT(kr, "Breakpad UNREGISTER : bootstrap_register() : "); - } - - mach_port_deallocate(mach_task_self(), server_port_); - server_port_ = MACH_PORT_NULL; - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/UnitTests-Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/UnitTests-Info.plist deleted file mode 100644 index 65013556d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/UnitTests-Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.h b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.h deleted file mode 100644 index 5662e8b09..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Utility class that can persist a SimpleStringDictionary to disk. - -#import - -#include "common/simple_string_dictionary.h" - -namespace google_breakpad { - -BOOL EnsureDirectoryPathExists(NSString *dirPath); - -//============================================================================= -class ConfigFile { - public: - ConfigFile() { - config_file_ = -1; - config_file_path_[0] = 0; - has_created_file_ = false; - }; - - ~ConfigFile() { - }; - - void WriteFile(const char* directory, - const SimpleStringDictionary *configurationParameters, - const char *dump_dir, - const char *minidump_id); - - const char *GetFilePath() { return config_file_path_; } - - void Unlink() { - if (config_file_ != -1) - unlink(config_file_path_); - - config_file_ = -1; - } - - private: - BOOL WriteData(const void *data, size_t length); - - BOOL AppendConfigData(const char *key, - const void *data, - size_t length); - - BOOL AppendConfigString(const char *key, - const char *value); - - BOOL AppendCrashTimeParameters(const char *processStartTimeString); - - int config_file_; // descriptor for config file - char config_file_path_[PATH_MAX]; // Path to configuration file - bool has_created_file_; -}; - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.mm deleted file mode 100644 index acab7de84..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.mm +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Utility class that can persist a SimpleStringDictionary to disk. - -#import "client/mac/crash_generation/ConfigFile.h" - -#import -#include -#include - -#import "client/apple/Framework/BreakpadDefines.h" -#import "common/mac/GTMDefines.h" - - -namespace google_breakpad { - -//============================================================================= -BOOL EnsureDirectoryPathExists(NSString *dirPath) { - NSFileManager *mgr = [NSFileManager defaultManager]; - - NSDictionary *attrs = - [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedLong:0750] - forKey:NSFilePosixPermissions]; - - return [mgr createDirectoryAtPath:dirPath - withIntermediateDirectories:YES - attributes:attrs - error:nil]; -} - -//============================================================================= -BOOL ConfigFile::WriteData(const void *data, size_t length) { - size_t result = write(config_file_, data, length); - - return result == length; -} - -//============================================================================= -BOOL ConfigFile::AppendConfigData(const char *key, - const void *data, size_t length) { - assert(config_file_ != -1); - - if (!key) { - return NO; - } - - if (!data) { - return NO; - } - - // Write the key, \n, length of data (ascii integer), \n, data - char buffer[16]; - char nl = '\n'; - BOOL result = WriteData(key, strlen(key)); - - snprintf(buffer, sizeof(buffer) - 1, "\n%lu\n", length); - result &= WriteData(buffer, strlen(buffer)); - result &= WriteData(data, length); - result &= WriteData(&nl, 1); - return result; -} - -//============================================================================= -BOOL ConfigFile::AppendConfigString(const char *key, - const char *value) { - return AppendConfigData(key, value, strlen(value)); -} - -//============================================================================= -BOOL ConfigFile::AppendCrashTimeParameters(const char *processStartTimeString) { - // Set process uptime parameter - struct timeval tv; - gettimeofday(&tv, NULL); - - char processUptimeString[32], processCrashtimeString[32]; - // Set up time if we've received the start time. - if (processStartTimeString) { - time_t processStartTime = strtol(processStartTimeString, NULL, 10); - time_t processUptime = tv.tv_sec - processStartTime; - // Store the uptime in milliseconds. - sprintf(processUptimeString, "%llu", - static_cast(processUptime) * 1000); - if (!AppendConfigString(BREAKPAD_PROCESS_UP_TIME, processUptimeString)) - return false; - } - - sprintf(processCrashtimeString, "%zd", tv.tv_sec); - return AppendConfigString(BREAKPAD_PROCESS_CRASH_TIME, - processCrashtimeString); -} - -//============================================================================= -void ConfigFile::WriteFile(const char* directory, - const SimpleStringDictionary *configurationParameters, - const char *dump_dir, - const char *minidump_id) { - - assert(config_file_ == -1); - - // Open and write out configuration file preamble - if (directory) { - snprintf(config_file_path_, sizeof(config_file_path_), "%s/Config-XXXXXX", - directory); - } else { - strlcpy(config_file_path_, "/tmp/Config-XXXXXX", - sizeof(config_file_path_)); - } - config_file_ = mkstemp(config_file_path_); - - if (config_file_ == -1) { - return; - } - - has_created_file_ = true; - - // Add the minidump dir - AppendConfigString(kReporterMinidumpDirectoryKey, dump_dir); - AppendConfigString(kReporterMinidumpIDKey, minidump_id); - - // Write out the configuration parameters - BOOL result = YES; - const SimpleStringDictionary &dictionary = *configurationParameters; - - const SimpleStringDictionary::Entry *entry = NULL; - SimpleStringDictionary::Iterator iter(dictionary); - - while ((entry = iter.Next())) { - result = AppendConfigString(entry->key, entry->value); - - if (!result) - break; - } - AppendCrashTimeParameters( - configurationParameters->GetValueForKey(BREAKPAD_PROCESS_START_TIME)); - - close(config_file_); - config_file_ = -1; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.h b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.h deleted file mode 100644 index 671235513..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.h +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Interface file between the Breakpad.framework and -// the Inspector process. - -#include "common/simple_string_dictionary.h" - -#import -#include - -#import "client/mac/crash_generation/ConfigFile.h" -#import "client/mac/handler/minidump_generator.h" - - -// Types of mach messsages (message IDs) -enum { - kMsgType_InspectorInitialInfo = 0, // data is InspectorInfo - kMsgType_InspectorKeyValuePair = 1, // data is KeyValueMessageData - kMsgType_InspectorAcknowledgement = 2 // no data sent -}; - -// Initial information sent from the crashed process by -// Breakpad.framework to the Inspector process -// The mach message with this struct as data will also include -// several descriptors for sending mach port rights to the crashed -// task, etc. -struct InspectorInfo { - int exception_type; - int exception_code; - int exception_subcode; - unsigned int parameter_count; // key-value pairs -}; - -// Key/value message data to be sent to the Inspector -struct KeyValueMessageData { - public: - KeyValueMessageData() {} - explicit KeyValueMessageData( - const google_breakpad::SimpleStringDictionary::Entry &inEntry) { - strlcpy(key, inEntry.key, sizeof(key) ); - strlcpy(value, inEntry.value, sizeof(value) ); - } - - char key[google_breakpad::SimpleStringDictionary::key_size]; - char value[google_breakpad::SimpleStringDictionary::value_size]; -}; - -using std::string; -using google_breakpad::MinidumpGenerator; - -namespace google_breakpad { - -//============================================================================= -class MinidumpLocation { - public: - MinidumpLocation(NSString *minidumpDir) { - // Ensure that the path exists. Fallback to /tmp if unable to locate path. - assert(minidumpDir); - if (!EnsureDirectoryPathExists(minidumpDir)) { - minidumpDir = @"/tmp"; - } - - strlcpy(minidump_dir_path_, [minidumpDir fileSystemRepresentation], - sizeof(minidump_dir_path_)); - - // now generate a unique ID - string dump_path(minidump_dir_path_); - string next_minidump_id; - - string next_minidump_path_ = - (MinidumpGenerator::UniqueNameInDirectory(dump_path, &next_minidump_id)); - - strlcpy(minidump_id_, next_minidump_id.c_str(), sizeof(minidump_id_)); - }; - - const char *GetPath() { return minidump_dir_path_; } - const char *GetID() { return minidump_id_; } - - private: - char minidump_dir_path_[PATH_MAX]; // Path to minidump directory - char minidump_id_[128]; -}; - -//============================================================================= -class Inspector { - public: - Inspector() {}; - - // given a bootstrap service name, receives mach messages - // from a crashed process, then inspects it, creates a minidump file - // and asks the user if he wants to upload it to a server. - void Inspect(const char *receive_port_name); - - private: - // The Inspector is invoked with its bootstrap port set to the bootstrap - // subset established in OnDemandServer.mm OnDemandServer::Initialize. - // For proper communication with the system, the sender (which will inherit - // the Inspector's bootstrap port) needs the per-session bootstrap namespace - // available directly in its bootstrap port. OnDemandServer stashed this - // port into the subset namespace under a special name. ResetBootstrapPort - // recovers this port and switches this task to use it as its own bootstrap - // (ensuring that children like the sender will inherit it), and saves the - // subset in bootstrap_subset_port_ for use by ServiceCheckIn and - // ServiceCheckOut. - kern_return_t ResetBootstrapPort(); - - kern_return_t ServiceCheckIn(const char *receive_port_name); - kern_return_t ServiceCheckOut(const char *receive_port_name); - - kern_return_t ReadMessages(); - - bool InspectTask(); - kern_return_t SendAcknowledgement(); - - // The bootstrap port in which the inspector is registered and into which it - // must check in. - mach_port_t bootstrap_subset_port_; - - mach_port_t service_rcv_port_; - - int exception_type_; - int exception_code_; - int exception_subcode_; - mach_port_t remote_task_; - mach_port_t crashing_thread_; - mach_port_t handler_thread_; - mach_port_t ack_port_; - - SimpleStringDictionary config_params_; - - ConfigFile config_file_; -}; - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.mm deleted file mode 100644 index dc6f48086..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.mm +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Utility that can inspect another process and write a crash dump - -#include -#include -#include -#include -#include -#include - -#import "client/mac/crash_generation/Inspector.h" - -#import "client/mac/Framework/Breakpad.h" -#import "client/mac/handler/minidump_generator.h" - -#import "common/mac/MachIPC.h" -#include "common/mac/bootstrap_compat.h" -#include "common/mac/launch_reporter.h" - -#import "GTMDefines.h" - -#import - -namespace google_breakpad { - -//============================================================================= -void Inspector::Inspect(const char *receive_port_name) { - kern_return_t result = ResetBootstrapPort(); - if (result != KERN_SUCCESS) { - return; - } - - result = ServiceCheckIn(receive_port_name); - - if (result == KERN_SUCCESS) { - result = ReadMessages(); - - if (result == KERN_SUCCESS) { - // Inspect the task and write a minidump file. - bool wrote_minidump = InspectTask(); - - // Send acknowledgement to the crashed process that the inspection - // has finished. It will then be able to cleanly exit. - // The return value is ignored because failure isn't fatal. If the process - // didn't get the message there's nothing we can do, and we still want to - // send the report. - SendAcknowledgement(); - - if (wrote_minidump) { - // Ask the user if he wants to upload the crash report to a server, - // and do so if he agrees. - LaunchReporter( - config_params_.GetValueForKey(BREAKPAD_REPORTER_EXE_LOCATION), - config_file_.GetFilePath()); - } else { - fprintf(stderr, "Inspection of crashed process failed\n"); - } - - // Now that we're done reading messages, cleanup the service, but only - // if there was an actual exception - // Otherwise, it means the dump was generated on demand and the process - // lives on, and we might be needed again in the future. - if (exception_code_) { - ServiceCheckOut(receive_port_name); - } - } else { - PRINT_MACH_RESULT(result, "Inspector: WaitForMessage()"); - } - } -} - -//============================================================================= -kern_return_t Inspector::ResetBootstrapPort() { - // A reasonable default, in case anything fails. - bootstrap_subset_port_ = bootstrap_port; - - mach_port_t self_task = mach_task_self(); - - kern_return_t kr = task_get_bootstrap_port(self_task, - &bootstrap_subset_port_); - if (kr != KERN_SUCCESS) { - NSLog(@"ResetBootstrapPort: task_get_bootstrap_port failed: %s (%d)", - mach_error_string(kr), kr); - return kr; - } - - mach_port_t bootstrap_parent_port; - kr = bootstrap_look_up(bootstrap_subset_port_, - const_cast(BREAKPAD_BOOTSTRAP_PARENT_PORT), - &bootstrap_parent_port); - if (kr != BOOTSTRAP_SUCCESS) { - NSLog(@"ResetBootstrapPort: bootstrap_look_up failed: %s (%d)", -#if defined(MAC_OS_X_VERSION_10_5) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - bootstrap_strerror(kr), -#else - mach_error_string(kr), -#endif - kr); - return kr; - } - - kr = task_set_bootstrap_port(self_task, bootstrap_parent_port); - if (kr != KERN_SUCCESS) { - NSLog(@"ResetBootstrapPort: task_set_bootstrap_port failed: %s (%d)", - mach_error_string(kr), kr); - return kr; - } - - // Some things access the bootstrap port through this global variable - // instead of calling task_get_bootstrap_port. - bootstrap_port = bootstrap_parent_port; - - return KERN_SUCCESS; -} - -//============================================================================= -kern_return_t Inspector::ServiceCheckIn(const char *receive_port_name) { - // We need to get the mach port representing this service, so we can - // get information from the crashed process. - kern_return_t kr = bootstrap_check_in(bootstrap_subset_port_, - (char*)receive_port_name, - &service_rcv_port_); - - if (kr != KERN_SUCCESS) { -#if VERBOSE - PRINT_MACH_RESULT(kr, "Inspector: bootstrap_check_in()"); -#endif - } - - return kr; -} - -//============================================================================= -kern_return_t Inspector::ServiceCheckOut(const char *receive_port_name) { - // We're done receiving mach messages from the crashed process, - // so clean up a bit. - kern_return_t kr; - - // DO NOT use mach_port_deallocate() here -- it will fail and the - // following bootstrap_register() will also fail leaving our service - // name hanging around forever (until reboot) - kr = mach_port_destroy(mach_task_self(), service_rcv_port_); - - if (kr != KERN_SUCCESS) { - PRINT_MACH_RESULT(kr, - "Inspector: UNREGISTERING: service_rcv_port mach_port_deallocate()"); - return kr; - } - - // Unregister the service associated with the receive port. - kr = breakpad::BootstrapRegister(bootstrap_subset_port_, - (char*)receive_port_name, - MACH_PORT_NULL); - - if (kr != KERN_SUCCESS) { - PRINT_MACH_RESULT(kr, "Inspector: UNREGISTERING: bootstrap_register()"); - } - - return kr; -} - -//============================================================================= -kern_return_t Inspector::ReadMessages() { - // Wait for an initial message from the crashed process containing basic - // information about the crash. - ReceivePort receive_port(service_rcv_port_); - - MachReceiveMessage message; - kern_return_t result = receive_port.WaitForMessage(&message, 1000); - - if (result == KERN_SUCCESS) { - InspectorInfo &info = (InspectorInfo &)*message.GetData(); - exception_type_ = info.exception_type; - exception_code_ = info.exception_code; - exception_subcode_ = info.exception_subcode; - -#if VERBOSE - printf("message ID = %d\n", message.GetMessageID()); -#endif - - remote_task_ = message.GetTranslatedPort(0); - crashing_thread_ = message.GetTranslatedPort(1); - handler_thread_ = message.GetTranslatedPort(2); - ack_port_ = message.GetTranslatedPort(3); - -#if VERBOSE - printf("exception_type = %d\n", exception_type_); - printf("exception_code = %d\n", exception_code_); - printf("exception_subcode = %d\n", exception_subcode_); - printf("remote_task = %d\n", remote_task_); - printf("crashing_thread = %d\n", crashing_thread_); - printf("handler_thread = %d\n", handler_thread_); - printf("ack_port_ = %d\n", ack_port_); - printf("parameter count = %d\n", info.parameter_count); -#endif - - // In certain situations where multiple crash requests come - // through quickly, we can end up with the mach IPC messages not - // coming through correctly. Since we don't know what parameters - // we've missed, we can't do much besides abort the crash dump - // situation in this case. - unsigned int parameters_read = 0; - // The initial message contains the number of key value pairs that - // we are expected to read. - // Read each key/value pair, one mach message per key/value pair. - for (unsigned int i = 0; i < info.parameter_count; ++i) { - MachReceiveMessage parameter_message; - result = receive_port.WaitForMessage(¶meter_message, 1000); - - if(result == KERN_SUCCESS) { - KeyValueMessageData &key_value_data = - (KeyValueMessageData&)*parameter_message.GetData(); - // If we get a blank key, make sure we don't increment the - // parameter count; in some cases (notably on-demand generation - // many times in a short period of time) caused the Mach IPC - // messages to not come through correctly. - if (strlen(key_value_data.key) == 0) { - continue; - } - parameters_read++; - - config_params_.SetKeyValue(key_value_data.key, key_value_data.value); - } else { - PRINT_MACH_RESULT(result, "Inspector: key/value message"); - break; - } - } - if (parameters_read != info.parameter_count) { - return KERN_FAILURE; - } - } - - return result; -} - -//============================================================================= -bool Inspector::InspectTask() { - // keep the task quiet while we're looking at it - task_suspend(remote_task_); - - NSString *minidumpDir; - - const char *minidumpDirectory = - config_params_.GetValueForKey(BREAKPAD_DUMP_DIRECTORY); - - // If the client app has not specified a minidump directory, - // use a default of Library// - if (!minidumpDirectory || 0 == strlen(minidumpDirectory)) { - NSArray *libraryDirectories = - NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, - NSUserDomainMask, - YES); - - NSString *applicationSupportDirectory = - [libraryDirectories objectAtIndex:0]; - NSString *library_subdirectory = [NSString - stringWithUTF8String:kDefaultLibrarySubdirectory]; - NSString *breakpad_product = [NSString - stringWithUTF8String:config_params_.GetValueForKey(BREAKPAD_PRODUCT)]; - - NSArray *path_components = [NSArray - arrayWithObjects:applicationSupportDirectory, - library_subdirectory, - breakpad_product, - nil]; - - minidumpDir = [NSString pathWithComponents:path_components]; - } else { - minidumpDir = [[NSString stringWithUTF8String:minidumpDirectory] - stringByExpandingTildeInPath]; - } - - MinidumpLocation minidumpLocation(minidumpDir); - - // Obscure bug alert: - // Don't use [NSString stringWithFormat] to build up the path here since it - // assumes system encoding and in RTL locales will prepend an LTR override - // character for paths beginning with '/' which fileSystemRepresentation does - // not remove. Filed as rdar://6889706 . - NSString *path_ns = [NSString - stringWithUTF8String:minidumpLocation.GetPath()]; - NSString *pathid_ns = [NSString - stringWithUTF8String:minidumpLocation.GetID()]; - NSString *minidumpPath = [path_ns stringByAppendingPathComponent:pathid_ns]; - minidumpPath = [minidumpPath - stringByAppendingPathExtension:@"dmp"]; - - config_file_.WriteFile( 0, - &config_params_, - minidumpLocation.GetPath(), - minidumpLocation.GetID()); - - - MinidumpGenerator generator(remote_task_, handler_thread_); - - if (exception_type_ && exception_code_) { - generator.SetExceptionInformation(exception_type_, - exception_code_, - exception_subcode_, - crashing_thread_); - } - - - bool result = generator.Write([minidumpPath fileSystemRepresentation]); - - // let the task continue - task_resume(remote_task_); - - return result; -} - -//============================================================================= -// The crashed task needs to be told that the inspection has finished. -// It will wait on a mach port (with timeout) until we send acknowledgement. -kern_return_t Inspector::SendAcknowledgement() { - if (ack_port_ != MACH_PORT_DEAD) { - MachPortSender sender(ack_port_); - MachSendMessage ack_message(kMsgType_InspectorAcknowledgement); - - kern_return_t result = sender.SendMessage(ack_message, 2000); - -#if VERBOSE - PRINT_MACH_RESULT(result, "Inspector: sent acknowledgement"); -#endif - - return result; - } - - return KERN_INVALID_NAME; -} - -} // namespace google_breakpad - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/InspectorMain.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/InspectorMain.mm deleted file mode 100644 index 137c6a1e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/InspectorMain.mm +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Main driver for Inspector - -#import "client/mac/crash_generation/Inspector.h" -#import - -namespace google_breakpad { - -//============================================================================= -extern "C" { - -int main(int argc, char *const argv[]) { -#if DEBUG - // Since we're launched on-demand, this is necessary to see debugging - // output in the console window. - freopen("/dev/console", "w", stdout); - freopen("/dev/console", "w", stderr); -#endif - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - if (argc != 2) { - exit(0); - } - // Our first command-line argument contains the name of the service - // that we're providing. - google_breakpad::Inspector inspector; - inspector.Inspect(argv[1]); - - [pool release]; - - return 0; -} - -} // extern "C" - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/client_info.h b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/client_info.h deleted file mode 100644 index a3a95dcac..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/client_info.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_ -#define CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_ - -namespace google_breakpad { - -class ClientInfo { - public: - explicit ClientInfo(pid_t pid) : pid_(pid) {} - - pid_t pid() const { return pid_; } - - private: - pid_t pid_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.cc deleted file mode 100644 index f6bf14f58..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/mac/crash_generation/crash_generation_client.h" - -#include "client/mac/crash_generation/crash_generation_server.h" -#include "common/mac/MachIPC.h" - -namespace google_breakpad { - -bool CrashGenerationClient::RequestDumpForException( - int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread) { - // The server will send a message to this port indicating that it - // has finished its work. - ReceivePort acknowledge_port; - - MachSendMessage message(kDumpRequestMessage); - message.AddDescriptor(mach_task_self()); // this task - message.AddDescriptor(crashing_thread); // crashing thread - message.AddDescriptor(MACH_PORT_NULL); // handler thread - message.AddDescriptor(acknowledge_port.GetPort()); // message receive port - - ExceptionInfo info; - info.exception_type = exception_type; - info.exception_code = exception_code; - info.exception_subcode = exception_subcode; - message.SetData(&info, sizeof(info)); - - const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000; - kern_return_t result = sender_.SendMessage(message, kSendTimeoutMs); - if (result != KERN_SUCCESS) - return false; - - // Give the server slightly longer to reply since it has to - // inspect this task and write the minidump. - const mach_msg_timeout_t kReceiveTimeoutMs = 5 * 1000; - MachReceiveMessage acknowledge_message; - result = acknowledge_port.WaitForMessage(&acknowledge_message, - kReceiveTimeoutMs); - return result == KERN_SUCCESS; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.h b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.h deleted file mode 100644 index 527f577a5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_client.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ -#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ - -#include "common/mac/MachIPC.h" - -namespace google_breakpad { - -class CrashGenerationClient { - public: - explicit CrashGenerationClient(const char* mach_port_name) - : sender_(mach_port_name) { - } - - // Request the crash server to generate a dump. - // - // Return true if the dump was successful; false otherwise. - bool RequestDumpForException(int exception_type, - int exception_code, - int exception_subcode, - mach_port_t crashing_thread); - - bool RequestDump() { - return RequestDumpForException(0, 0, 0, MACH_PORT_NULL); - } - - private: - MachPortSender sender_; - - // Prevent copy construction and assignment. - CrashGenerationClient(const CrashGenerationClient&); - CrashGenerationClient& operator=(const CrashGenerationClient&); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.cc deleted file mode 100644 index 451e8d9c2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.cc +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/mac/crash_generation/crash_generation_server.h" - -#include - -#include "client/mac/crash_generation/client_info.h" -#include "client/mac/handler/minidump_generator.h" -#include "common/mac/scoped_task_suspend-inl.h" - -namespace google_breakpad { - -CrashGenerationServer::CrashGenerationServer( - const char *mach_port_name, - FilterCallback filter, - void *filter_context, - OnClientDumpRequestCallback dump_callback, - void *dump_context, - OnClientExitingCallback exit_callback, - void *exit_context, - bool generate_dumps, - const std::string &dump_path) - : filter_(filter), - filter_context_(filter_context), - dump_callback_(dump_callback), - dump_context_(dump_context), - exit_callback_(exit_callback), - exit_context_(exit_context), - generate_dumps_(generate_dumps), - dump_dir_(dump_path.empty() ? "/tmp" : dump_path), - started_(false), - receive_port_(mach_port_name), - mach_port_name_(mach_port_name) { -} - -CrashGenerationServer::~CrashGenerationServer() { - if (started_) - Stop(); -} - -bool CrashGenerationServer::Start() { - int thread_create_result = pthread_create(&server_thread_, NULL, - &WaitForMessages, this); - started_ = thread_create_result == 0; - return started_; -} - -bool CrashGenerationServer::Stop() { - if (!started_) - return false; - - // Send a quit message to the background thread, and then join it. - MachPortSender sender(mach_port_name_.c_str()); - MachSendMessage quit_message(kQuitMessage); - const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000; - kern_return_t result = sender.SendMessage(quit_message, kSendTimeoutMs); - if (result == KERN_SUCCESS) { - int thread_join_result = pthread_join(server_thread_, NULL); - started_ = thread_join_result != 0; - } - - return !started_; -} - -// static -void *CrashGenerationServer::WaitForMessages(void *server) { - CrashGenerationServer *self = - reinterpret_cast(server); - while (self->WaitForOneMessage()) {} - return NULL; -} - -bool CrashGenerationServer::WaitForOneMessage() { - MachReceiveMessage message; - kern_return_t result = receive_port_.WaitForMessage(&message, - MACH_MSG_TIMEOUT_NONE); - if (result == KERN_SUCCESS) { - switch (message.GetMessageID()) { - case kDumpRequestMessage: { - ExceptionInfo &info = (ExceptionInfo &)*message.GetData(); - - mach_port_t remote_task = message.GetTranslatedPort(0); - mach_port_t crashing_thread = message.GetTranslatedPort(1); - mach_port_t handler_thread = message.GetTranslatedPort(2); - mach_port_t ack_port = message.GetTranslatedPort(3); - pid_t remote_pid = -1; - pid_for_task(remote_task, &remote_pid); - ClientInfo client(remote_pid); - - bool result; - std::string dump_path; - if (generate_dumps_ && (!filter_ || filter_(filter_context_))) { - ScopedTaskSuspend suspend(remote_task); - - MinidumpGenerator generator(remote_task, handler_thread); - dump_path = generator.UniqueNameInDirectory(dump_dir_, NULL); - - if (info.exception_type && info.exception_code) { - generator.SetExceptionInformation(info.exception_type, - info.exception_code, - info.exception_subcode, - crashing_thread); - } - result = generator.Write(dump_path.c_str()); - } else { - result = true; - } - - if (result && dump_callback_) { - dump_callback_(dump_context_, client, dump_path); - } - - // TODO(ted): support a way for the client to send additional data, - // perhaps with a callback so users of the server can read the data - // themselves? - - if (ack_port != MACH_PORT_DEAD && ack_port != MACH_PORT_NULL) { - MachPortSender sender(ack_port); - MachSendMessage ack_message(kAcknowledgementMessage); - const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000; - - sender.SendMessage(ack_message, kSendTimeoutMs); - } - - if (exit_callback_) { - exit_callback_(exit_context_, client); - } - break; - } - case kQuitMessage: - return false; - } - } else { // result != KERN_SUCCESS - return false; - } - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.h b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.h deleted file mode 100644 index 85bd5b5e3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/crash_generation_server.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ -#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ - -#include - -#include - -#include "common/mac/MachIPC.h" - -namespace google_breakpad { - -class ClientInfo; - -// Messages the server can read via its mach port -enum { - kDumpRequestMessage = 1, - kAcknowledgementMessage = 2, - kQuitMessage = 3 -}; - -// Exception details sent by the client when requesting a dump. -struct ExceptionInfo { - int32_t exception_type; - int32_t exception_code; - int32_t exception_subcode; -}; - -class CrashGenerationServer { - public: - // WARNING: callbacks may be invoked on a different thread - // than that which creates the CrashGenerationServer. They must - // be thread safe. - typedef void (*OnClientDumpRequestCallback)(void *context, - const ClientInfo &client_info, - const std::string &file_path); - - typedef void (*OnClientExitingCallback)(void *context, - const ClientInfo &client_info); - // If a FilterCallback returns false, the dump will not be written. - typedef bool (*FilterCallback)(void *context); - - // Create an instance with the given parameters. - // - // mach_port_name: Named server port to listen on. - // filter: Callback for a client to cancel writing a dump. - // filter_context: Context for the filter callback. - // dump_callback: Callback for a client crash dump request. - // dump_context: Context for client crash dump request callback. - // exit_callback: Callback for client process exit. - // exit_context: Context for client exit callback. - // generate_dumps: Whether to automatically generate dumps. - // Client code of this class might want to generate dumps explicitly - // in the crash dump request callback. In that case, false can be - // passed for this parameter. - // dump_path: Path for generating dumps; required only if true is - // passed for generateDumps parameter; NULL can be passed otherwise. - CrashGenerationServer(const char *mach_port_name, - FilterCallback filter, - void *filter_context, - OnClientDumpRequestCallback dump_callback, - void *dump_context, - OnClientExitingCallback exit_callback, - void *exit_context, - bool generate_dumps, - const std::string &dump_path); - - ~CrashGenerationServer(); - - // Perform initialization steps needed to start listening to clients. - // - // Return true if initialization is successful; false otherwise. - bool Start(); - - // Stop the server. - bool Stop(); - - private: - // Return a unique filename at which a minidump can be written. - bool MakeMinidumpFilename(std::string &outFilename); - - // Loop reading client messages and responding to them until - // a quit message is received. - static void *WaitForMessages(void *server); - - // Wait for a single client message and respond to it. Returns false - // if a quit message was received or if an error occurred. - bool WaitForOneMessage(); - - FilterCallback filter_; - void *filter_context_; - - OnClientDumpRequestCallback dump_callback_; - void *dump_context_; - - OnClientExitingCallback exit_callback_; - void *exit_context_; - - bool generate_dumps_; - - std::string dump_dir_; - - bool started_; - - // The mach port that receives requests to dump from child processes. - ReceivePort receive_port_; - - // The name of the mach port. Stored so the Stop method can message - // the background thread to shut it down. - std::string mach_port_name_; - - // The thread that waits on the receive port. - pthread_t server_thread_; - - // Disable copy constructor and operator=. - CrashGenerationServer(const CrashGenerationServer&); - CrashGenerationServer& operator=(const CrashGenerationServer&); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build deleted file mode 100644 index 79afa4504..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build +++ /dev/null @@ -1,19 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'crash_generation_client.cc', - 'crash_generation_server.cc', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../../..', -] - -if CONFIG['CLANG_CXX']: - CXXFLAGS += ['-Wno-shadow'] diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.cc deleted file mode 100644 index 3492b823d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -/* - * This file was copied from libc/gen/nlist.c from Darwin's source code - * The version of nlist used as a base is from 10.5.2, libc-498 - * http://www.opensource.apple.com/darwinsource/10.5.2/Libc-498/gen/nlist.c - * - * The full tarball is at: - * http://www.opensource.apple.com/darwinsource/tarballs/apsl/Libc-498.tar.gz - * - * I've modified it to be compatible with 64-bit images. -*/ - -#include "breakpad_nlist_64.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Stuff lifted from and since they are gone */ -/* - * Header prepended to each a.out file. - */ -struct exec { - unsigned short a_machtype; /* machine type */ - unsigned short a_magic; /* magic number */ - unsigned long a_text; /* size of text segment */ - unsigned long a_data; /* size of initialized data */ - unsigned long a_bss; /* size of uninitialized data */ - unsigned long a_syms; /* size of symbol table */ - unsigned long a_entry; /* entry point */ - unsigned long a_trsize; /* size of text relocation */ - unsigned long a_drsize; /* size of data relocation */ -}; - -#define OMAGIC 0407 /* old impure format */ -#define NMAGIC 0410 /* read-only text */ -#define ZMAGIC 0413 /* demand load format */ - -#define N_BADMAG(x) \ - (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) -#define N_TXTOFF(x) \ - ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec)) -#define N_SYMOFF(x) \ - (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize) - -// Traits structs for specializing function templates to handle -// 32-bit/64-bit Mach-O files. -template -struct MachBits {}; - -typedef struct nlist nlist32; -typedef struct nlist_64 nlist64; - -template<> -struct MachBits { - typedef mach_header mach_header_type; - typedef uint32_t word_type; - static const uint32_t magic = MH_MAGIC; -}; - -template<> -struct MachBits { - typedef mach_header_64 mach_header_type; - typedef uint64_t word_type; - static const uint32_t magic = MH_MAGIC_64; -}; - -template -int -__breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames, - cpu_type_t cpu_type); - -/* - * nlist - retreive attributes from name list (string table version) - */ - -template -int breakpad_nlist_common(const char *name, - nlist_type *list, - const char **symbolNames, - cpu_type_t cpu_type) { - int fd = open(name, O_RDONLY, 0); - if (fd < 0) - return -1; - int n = __breakpad_fdnlist(fd, list, symbolNames, cpu_type); - close(fd); - return n; -} - -int breakpad_nlist(const char *name, - struct nlist *list, - const char **symbolNames, - cpu_type_t cpu_type) { - return breakpad_nlist_common(name, list, symbolNames, cpu_type); -} - -int breakpad_nlist(const char *name, - struct nlist_64 *list, - const char **symbolNames, - cpu_type_t cpu_type) { - return breakpad_nlist_common(name, list, symbolNames, cpu_type); -} - -/* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */ - -template -int __breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames, - cpu_type_t cpu_type) { - typedef typename MachBits::mach_header_type mach_header_type; - typedef typename MachBits::word_type word_type; - - const uint32_t magic = MachBits::magic; - - int maxlen = 500; - int nreq = 0; - for (nlist_type* q = list; - symbolNames[q-list] && symbolNames[q-list][0]; - q++, nreq++) { - - q->n_type = 0; - q->n_value = 0; - q->n_desc = 0; - q->n_sect = 0; - q->n_un.n_strx = 0; - } - - struct exec buf; - if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf) || - (N_BADMAG(buf) && *((uint32_t *)&buf) != magic && - CFSwapInt32BigToHost(*((uint32_t *)&buf)) != FAT_MAGIC && - /* The following is the big-endian ppc64 check */ - (*((uint32_t*)&buf)) != FAT_MAGIC)) { - return -1; - } - - /* Deal with fat file if necessary */ - unsigned arch_offset = 0; - if (CFSwapInt32BigToHost(*((uint32_t *)&buf)) == FAT_MAGIC || - /* The following is the big-endian ppc64 check */ - *((unsigned int *)&buf) == FAT_MAGIC) { - /* Read in the fat header */ - struct fat_header fh; - if (lseek(fd, 0, SEEK_SET) == -1) { - return -1; - } - if (read(fd, (char *)&fh, sizeof(fh)) != sizeof(fh)) { - return -1; - } - - /* Convert fat_narchs to host byte order */ - fh.nfat_arch = CFSwapInt32BigToHost(fh.nfat_arch); - - /* Read in the fat archs */ - struct fat_arch *fat_archs = - (struct fat_arch *)malloc(fh.nfat_arch * sizeof(struct fat_arch)); - if (fat_archs == NULL) { - return -1; - } - if (read(fd, (char *)fat_archs, - sizeof(struct fat_arch) * fh.nfat_arch) != - (ssize_t)(sizeof(struct fat_arch) * fh.nfat_arch)) { - free(fat_archs); - return -1; - } - - /* - * Convert archs to host byte ordering (a constraint of - * cpusubtype_getbestarch() - */ - for (unsigned i = 0; i < fh.nfat_arch; i++) { - fat_archs[i].cputype = - CFSwapInt32BigToHost(fat_archs[i].cputype); - fat_archs[i].cpusubtype = - CFSwapInt32BigToHost(fat_archs[i].cpusubtype); - fat_archs[i].offset = - CFSwapInt32BigToHost(fat_archs[i].offset); - fat_archs[i].size = - CFSwapInt32BigToHost(fat_archs[i].size); - fat_archs[i].align = - CFSwapInt32BigToHost(fat_archs[i].align); - } - - struct fat_arch *fap = NULL; - for (unsigned i = 0; i < fh.nfat_arch; i++) { - if (fat_archs[i].cputype == cpu_type) { - fap = &fat_archs[i]; - break; - } - } - - if (!fap) { - free(fat_archs); - return -1; - } - arch_offset = fap->offset; - free(fat_archs); - - /* Read in the beginning of the architecture-specific file */ - if (lseek(fd, arch_offset, SEEK_SET) == -1) { - return -1; - } - if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf)) { - return -1; - } - } - - off_t sa; /* symbol address */ - off_t ss; /* start of strings */ - register_t n; - if (*((unsigned int *)&buf) == magic) { - if (lseek(fd, arch_offset, SEEK_SET) == -1) { - return -1; - } - mach_header_type mh; - if (read(fd, (char *)&mh, sizeof(mh)) != sizeof(mh)) { - return -1; - } - - struct load_command *load_commands = - (struct load_command *)malloc(mh.sizeofcmds); - if (load_commands == NULL) { - return -1; - } - if (read(fd, (char *)load_commands, mh.sizeofcmds) != - (ssize_t)mh.sizeofcmds) { - free(load_commands); - return -1; - } - struct symtab_command *stp = NULL; - struct load_command *lcp = load_commands; - // iterate through all load commands, looking for - // LC_SYMTAB load command - for (uint32_t i = 0; i < mh.ncmds; i++) { - if (lcp->cmdsize % sizeof(word_type) != 0 || - lcp->cmdsize <= 0 || - (char *)lcp + lcp->cmdsize > - (char *)load_commands + mh.sizeofcmds) { - free(load_commands); - return -1; - } - if (lcp->cmd == LC_SYMTAB) { - if (lcp->cmdsize != - sizeof(struct symtab_command)) { - free(load_commands); - return -1; - } - stp = (struct symtab_command *)lcp; - break; - } - lcp = (struct load_command *) - ((char *)lcp + lcp->cmdsize); - } - if (stp == NULL) { - free(load_commands); - return -1; - } - // sa points to the beginning of the symbol table - sa = stp->symoff + arch_offset; - // ss points to the beginning of the string table - ss = stp->stroff + arch_offset; - // n is the number of bytes in the symbol table - // each symbol table entry is an nlist structure - n = stp->nsyms * sizeof(nlist_type); - free(load_commands); - } else { - sa = N_SYMOFF(buf) + arch_offset; - ss = sa + buf.a_syms + arch_offset; - n = buf.a_syms; - } - - if (lseek(fd, sa, SEEK_SET) == -1) { - return -1; - } - - // the algorithm here is to read the nlist entries in m-sized - // chunks into q. q is then iterated over. for each entry in q, - // use the string table index(q->n_un.n_strx) to read the symbol - // name, then scan the nlist entries passed in by the user(via p), - // and look for a match - while (n) { - nlist_type space[BUFSIZ/sizeof (nlist_type)]; - register_t m = sizeof (space); - - if (n < m) - m = n; - if (read(fd, (char *)space, m) != m) - break; - n -= m; - off_t savpos = lseek(fd, 0, SEEK_CUR); - if (savpos == -1) { - return -1; - } - for (nlist_type* q = space; (m -= sizeof(nlist_type)) >= 0; q++) { - char nambuf[BUFSIZ]; - - if (q->n_un.n_strx == 0 || q->n_type & N_STAB) - continue; - - // seek to the location in the binary where the symbol - // name is stored & read it into memory - if (lseek(fd, ss+q->n_un.n_strx, SEEK_SET) == -1) { - return -1; - } - if (read(fd, nambuf, maxlen+1) == -1) { - return -1; - } - const char *s2 = nambuf; - for (nlist_type *p = list; - symbolNames[p-list] && symbolNames[p-list][0]; - p++) { - // get the symbol name the user has passed in that - // corresponds to the nlist entry that we're looking at - const char *s1 = symbolNames[p - list]; - while (*s1) { - if (*s1++ != *s2++) - goto cont; - } - if (*s2) - goto cont; - - p->n_value = q->n_value; - p->n_type = q->n_type; - p->n_desc = q->n_desc; - p->n_sect = q->n_sect; - p->n_un.n_strx = q->n_un.n_strx; - if (--nreq == 0) - return nreq; - - break; - cont: ; - } - } - if (lseek(fd, savpos, SEEK_SET) == -1) { - return -1; - } - } - return nreq; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.h deleted file mode 100644 index 1d2c63913..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// breakpad_nlist.h -// -// This file is meant to provide a header for clients of the modified -// nlist function implemented to work on 64-bit. - -#ifndef CLIENT_MAC_HANDLER_BREAKPAD_NLIST_H__ - -#include - -int breakpad_nlist(const char *name, - struct nlist *list, - const char **symbolNames, - cpu_type_t cpu_type); -int breakpad_nlist(const char *name, - struct nlist_64 *list, - const char **symbolNames, - cpu_type_t cpu_type); - -#endif /* CLIENT_MAC_HANDLER_BREAKPAD_NLIST_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.cc deleted file mode 100644 index cdba6df4a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.cc +++ /dev/null @@ -1,573 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/mac/handler/dynamic_images.h" - -extern "C" { // needed to compile on Leopard - #include - #include - #include -} - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "breakpad_nlist_64.h" - -#if !TARGET_OS_IPHONE -#include - -#ifndef MAC_OS_X_VERSION_10_6 -#define MAC_OS_X_VERSION_10_6 1060 -#endif - -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 - -// Fallback declarations for TASK_DYLD_INFO and friends, introduced in -// in the Mac OS X 10.6 SDK. -#define TASK_DYLD_INFO 17 -struct task_dyld_info { - mach_vm_address_t all_image_info_addr; - mach_vm_size_t all_image_info_size; -}; -typedef struct task_dyld_info task_dyld_info_data_t; -typedef struct task_dyld_info *task_dyld_info_t; -#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t)) - -#endif - -#endif // !TARGET_OS_IPHONE - -namespace google_breakpad { - -using std::string; -using std::vector; - -//============================================================================== -// Returns the size of the memory region containing |address| and the -// number of bytes from |address| to the end of the region. -// We potentially, will extend the size of the original -// region by the size of the following region if it's contiguous with the -// first in order to handle cases when we're reading strings and they -// straddle two vm regions. -// -static mach_vm_size_t GetMemoryRegionSize(task_port_t target_task, - const uint64_t address, - mach_vm_size_t *size_to_end) { - mach_vm_address_t region_base = (mach_vm_address_t)address; - mach_vm_size_t region_size; - natural_t nesting_level = 0; - vm_region_submap_info_64 submap_info; - mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64; - - // Get information about the vm region containing |address| - vm_region_recurse_info_t region_info; - region_info = reinterpret_cast(&submap_info); - - kern_return_t result = - mach_vm_region_recurse(target_task, - ®ion_base, - ®ion_size, - &nesting_level, - region_info, - &info_count); - - if (result == KERN_SUCCESS) { - // Get distance from |address| to the end of this region - *size_to_end = region_base + region_size -(mach_vm_address_t)address; - - // If we want to handle strings as long as 4096 characters we may need - // to check if there's a vm region immediately following the first one. - // If so, we need to extend |*size_to_end| to go all the way to the end - // of the second region. - if (*size_to_end < 4096) { - // Second region starts where the first one ends - mach_vm_address_t region_base2 = - (mach_vm_address_t)(region_base + region_size); - mach_vm_size_t region_size2; - - // Get information about the following vm region - result = - mach_vm_region_recurse(target_task, - ®ion_base2, - ®ion_size2, - &nesting_level, - region_info, - &info_count); - - // Extend region_size to go all the way to the end of the 2nd region - if (result == KERN_SUCCESS - && region_base2 == region_base + region_size) { - region_size += region_size2; - } - } - - *size_to_end = region_base + region_size -(mach_vm_address_t)address; - } else { - region_size = 0; - *size_to_end = 0; - } - - return region_size; -} - -#define kMaxStringLength 8192 -//============================================================================== -// Reads a NULL-terminated string from another task. -// -// Warning! This will not read any strings longer than kMaxStringLength-1 -// -static string ReadTaskString(task_port_t target_task, - const uint64_t address) { - // The problem is we don't know how much to read until we know how long - // the string is. And we don't know how long the string is, until we've read - // the memory! So, we'll try to read kMaxStringLength bytes - // (or as many bytes as we can until we reach the end of the vm region). - mach_vm_size_t size_to_end; - GetMemoryRegionSize(target_task, address, &size_to_end); - - if (size_to_end > 0) { - mach_vm_size_t size_to_read = - size_to_end > kMaxStringLength ? kMaxStringLength : size_to_end; - - vector bytes; - if (ReadTaskMemory(target_task, address, (size_t)size_to_read, bytes) != - KERN_SUCCESS) - return string(); - - return string(reinterpret_cast(&bytes[0])); - } - - return string(); -} - -//============================================================================== -// Reads an address range from another task. The bytes read will be returned -// in bytes, which will be resized as necessary. -kern_return_t ReadTaskMemory(task_port_t target_task, - const uint64_t address, - size_t length, - vector &bytes) { - int systemPageSize = getpagesize(); - - // use the negative of the page size for the mask to find the page address - mach_vm_address_t page_address = address & (-systemPageSize); - - mach_vm_address_t last_page_address = - (address + length + (systemPageSize - 1)) & (-systemPageSize); - - mach_vm_size_t page_size = last_page_address - page_address; - uint8_t* local_start; - uint32_t local_length; - - kern_return_t r = mach_vm_read(target_task, - page_address, - page_size, - reinterpret_cast(&local_start), - &local_length); - - if (r != KERN_SUCCESS) - return r; - - bytes.resize(length); - memcpy(&bytes[0], - &local_start[(mach_vm_address_t)address - page_address], - length); - mach_vm_deallocate(mach_task_self(), (uintptr_t)local_start, local_length); - return KERN_SUCCESS; -} - -#pragma mark - - -//============================================================================== -// Traits structs for specializing function templates to handle -// 32-bit/64-bit Mach-O files. -struct MachO32 { - typedef mach_header mach_header_type; - typedef segment_command mach_segment_command_type; - typedef dyld_image_info32 dyld_image_info; - typedef dyld_all_image_infos32 dyld_all_image_infos; - typedef struct nlist nlist_type; - static const uint32_t magic = MH_MAGIC; - static const uint32_t segment_load_command = LC_SEGMENT; -}; - -struct MachO64 { - typedef mach_header_64 mach_header_type; - typedef segment_command_64 mach_segment_command_type; - typedef dyld_image_info64 dyld_image_info; - typedef dyld_all_image_infos64 dyld_all_image_infos; - typedef struct nlist_64 nlist_type; - static const uint32_t magic = MH_MAGIC_64; - static const uint32_t segment_load_command = LC_SEGMENT_64; -}; - -template -bool FindTextSection(DynamicImage& image) { - typedef typename MachBits::mach_header_type mach_header_type; - typedef typename MachBits::mach_segment_command_type - mach_segment_command_type; - - const mach_header_type* header = - reinterpret_cast(&image.header_[0]); - - if(header->magic != MachBits::magic) { - return false; - } - - const struct load_command *cmd = - reinterpret_cast(header + 1); - - bool found_text_section = false; - bool found_dylib_id_command = false; - for (unsigned int i = 0; cmd && (i < header->ncmds); ++i) { - if (!found_text_section) { - if (cmd->cmd == MachBits::segment_load_command) { - const mach_segment_command_type *seg = - reinterpret_cast(cmd); - - if (!strcmp(seg->segname, "__TEXT")) { - image.vmaddr_ = static_cast(seg->vmaddr); - image.vmsize_ = static_cast(seg->vmsize); - image.slide_ = 0; - - if (seg->fileoff == 0 && seg->filesize != 0) { - image.slide_ = - (uintptr_t)image.GetLoadAddress() - (uintptr_t)seg->vmaddr; - } - found_text_section = true; - } - } - } - - if (!found_dylib_id_command) { - if (cmd->cmd == LC_ID_DYLIB) { - const struct dylib_command *dc = - reinterpret_cast(cmd); - - image.version_ = dc->dylib.current_version; - found_dylib_id_command = true; - } - } - - if (found_dylib_id_command && found_text_section) { - return true; - } - - cmd = reinterpret_cast - (reinterpret_cast(cmd) + cmd->cmdsize); - } - - return false; -} - -//============================================================================== -// Initializes vmaddr_, vmsize_, and slide_ -void DynamicImage::CalculateMemoryAndVersionInfo() { - // unless we can process the header, ensure that calls to - // IsValid() will return false - vmaddr_ = 0; - vmsize_ = 0; - slide_ = 0; - version_ = 0; - - // The function template above does all the real work. - if (Is64Bit()) - FindTextSection(*this); - else - FindTextSection(*this); -} - -//============================================================================== -// The helper function template abstracts the 32/64-bit differences. -template -uint32_t GetFileTypeFromHeader(DynamicImage& image) { - typedef typename MachBits::mach_header_type mach_header_type; - - const mach_header_type* header = - reinterpret_cast(&image.header_[0]); - return header->filetype; -} - -uint32_t DynamicImage::GetFileType() { - if (Is64Bit()) - return GetFileTypeFromHeader(*this); - - return GetFileTypeFromHeader(*this); -} - -#pragma mark - - -//============================================================================== -// Loads information about dynamically loaded code in the given task. -DynamicImages::DynamicImages(mach_port_t task) - : task_(task), - cpu_type_(DetermineTaskCPUType(task)), - image_list_() { - ReadImageInfoForTask(); -} - -template -static uint64_t LookupSymbol(const char* symbol_name, - const char* filename, - cpu_type_t cpu_type) { - typedef typename MachBits::nlist_type nlist_type; - - nlist_type symbol_info[8] = {}; - const char *symbolNames[2] = { symbol_name, "\0" }; - nlist_type &list = symbol_info[0]; - int invalidEntriesCount = breakpad_nlist(filename, - &list, - symbolNames, - cpu_type); - - if(invalidEntriesCount != 0) { - return 0; - } - - assert(list.n_value); - return list.n_value; -} - -#if TARGET_OS_IPHONE || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 -static bool HasTaskDyldInfo() { - return true; -} -#else -static SInt32 GetOSVersionInternal() { - SInt32 os_version = 0; - Gestalt(gestaltSystemVersion, &os_version); - return os_version; -} - -static SInt32 GetOSVersion() { - static SInt32 os_version = GetOSVersionInternal(); - return os_version; -} - -static bool HasTaskDyldInfo() { - return GetOSVersion() >= 0x1060; -} -#endif // TARGET_OS_IPHONE || MAC_OS_X_VERSION_MIN_REQUIRED >= 10_6 - -uint64_t DynamicImages::GetDyldAllImageInfosPointer() { - if (HasTaskDyldInfo()) { - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, - &count) != KERN_SUCCESS) { - return 0; - } - - return (uint64_t)task_dyld_info.all_image_info_addr; - } else { - const char *imageSymbolName = "_dyld_all_image_infos"; - const char *dyldPath = "/usr/lib/dyld"; - - if (Is64Bit()) - return LookupSymbol(imageSymbolName, dyldPath, cpu_type_); - return LookupSymbol(imageSymbolName, dyldPath, cpu_type_); - } -} - -//============================================================================== -// This code was written using dyld_debug.c (from Darwin) as a guide. - -template -void ReadImageInfo(DynamicImages& images, - uint64_t image_list_address) { - typedef typename MachBits::dyld_image_info dyld_image_info; - typedef typename MachBits::dyld_all_image_infos dyld_all_image_infos; - typedef typename MachBits::mach_header_type mach_header_type; - - // Read the structure inside of dyld that contains information about - // loaded images. We're reading from the desired task's address space. - - // Here we make the assumption that dyld loaded at the same address in - // the crashed process vs. this one. This is an assumption made in - // "dyld_debug.c" and is said to be nearly always valid. - vector dyld_all_info_bytes; - if (ReadTaskMemory(images.task_, - image_list_address, - sizeof(dyld_all_image_infos), - dyld_all_info_bytes) != KERN_SUCCESS) - return; - - dyld_all_image_infos *dyldInfo = - reinterpret_cast(&dyld_all_info_bytes[0]); - - // number of loaded images - int count = dyldInfo->infoArrayCount; - - // Read an array of dyld_image_info structures each containing - // information about a loaded image. - vector dyld_info_array_bytes; - if (ReadTaskMemory(images.task_, - dyldInfo->infoArray, - count * sizeof(dyld_image_info), - dyld_info_array_bytes) != KERN_SUCCESS) - return; - - dyld_image_info *infoArray = - reinterpret_cast(&dyld_info_array_bytes[0]); - images.image_list_.reserve(count); - - for (int i = 0; i < count; ++i) { - dyld_image_info &info = infoArray[i]; - - // First read just the mach_header from the image in the task. - vector mach_header_bytes; - if (ReadTaskMemory(images.task_, - info.load_address_, - sizeof(mach_header_type), - mach_header_bytes) != KERN_SUCCESS) - continue; // bail on this dynamic image - - mach_header_type *header = - reinterpret_cast(&mach_header_bytes[0]); - - // Now determine the total amount necessary to read the header - // plus all of the load commands. - size_t header_size = - sizeof(mach_header_type) + header->sizeofcmds; - - if (ReadTaskMemory(images.task_, - info.load_address_, - header_size, - mach_header_bytes) != KERN_SUCCESS) - continue; - - // Read the file name from the task's memory space. - string file_path; - if (info.file_path_) { - // Although we're reading kMaxStringLength bytes, it's copied in the - // the DynamicImage constructor below with the correct string length, - // so it's not really wasting memory. - file_path = ReadTaskString(images.task_, info.file_path_); - } - - // Create an object representing this image and add it to our list. - DynamicImage *new_image; - new_image = new DynamicImage(&mach_header_bytes[0], - header_size, - info.load_address_, - file_path, - static_cast(info.file_mod_date_), - images.task_, - images.cpu_type_); - - if (new_image->IsValid()) { - images.image_list_.push_back(DynamicImageRef(new_image)); - } else { - delete new_image; - } - } - - // sorts based on loading address - sort(images.image_list_.begin(), images.image_list_.end()); - // remove duplicates - this happens in certain strange cases - // You can see it in DashboardClient when Google Gadgets plugin - // is installed. Apple's crash reporter log and gdb "info shared" - // both show the same library multiple times at the same address - - vector::iterator it = unique(images.image_list_.begin(), - images.image_list_.end()); - images.image_list_.erase(it, images.image_list_.end()); -} - -void DynamicImages::ReadImageInfoForTask() { - uint64_t imageList = GetDyldAllImageInfosPointer(); - - if (imageList) { - if (Is64Bit()) - ReadImageInfo(*this, imageList); - else - ReadImageInfo(*this, imageList); - } -} - -//============================================================================== -DynamicImage *DynamicImages::GetExecutableImage() { - int executable_index = GetExecutableImageIndex(); - - if (executable_index >= 0) { - return GetImage(executable_index); - } - - return NULL; -} - -//============================================================================== -// returns -1 if failure to find executable -int DynamicImages::GetExecutableImageIndex() { - int image_count = GetImageCount(); - - for (int i = 0; i < image_count; ++i) { - DynamicImage *image = GetImage(i); - if (image->GetFileType() == MH_EXECUTE) { - return i; - } - } - - return -1; -} - -//============================================================================== -// static -cpu_type_t DynamicImages::DetermineTaskCPUType(task_t task) { - if (task == mach_task_self()) - return GetNativeCPUType(); - - int mib[CTL_MAXNAME]; - size_t mibLen = CTL_MAXNAME; - int err = sysctlnametomib("sysctl.proc_cputype", mib, &mibLen); - if (err == 0) { - assert(mibLen < CTL_MAXNAME); - pid_for_task(task, &mib[mibLen]); - mibLen += 1; - - cpu_type_t cpu_type; - size_t cpuTypeSize = sizeof(cpu_type); - sysctl(mib, static_cast(mibLen), &cpu_type, &cpuTypeSize, 0, 0); - return cpu_type; - } - - return GetNativeCPUType(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.h deleted file mode 100644 index 65147900b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/dynamic_images.h +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dynamic_images.h -// -// Implements most of the function of the dyld API, but allowing an -// arbitrary task to be introspected, unlike the dyld API which -// only allows operation on the current task. The current implementation -// is limited to use by 32-bit tasks. - -#ifndef CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ -#define CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ - -#include -#include -#include -#include - -#include -#include - -#include "mach_vm_compat.h" - -namespace google_breakpad { - -using std::string; -using std::vector; - -//============================================================================== -// The memory layout of this struct matches the dyld_image_info struct -// defined in "dyld_gdb.h" in the darwin source. -typedef struct dyld_image_info32 { - uint32_t load_address_; // struct mach_header* - uint32_t file_path_; // char* - uint32_t file_mod_date_; -} dyld_image_info32; - -typedef struct dyld_image_info64 { - uint64_t load_address_; // struct mach_header* - uint64_t file_path_; // char* - uint64_t file_mod_date_; -} dyld_image_info64; - -//============================================================================== -// This is as defined in "dyld_gdb.h" in the darwin source. -// _dyld_all_image_infos (in dyld) is a structure of this type -// which will be used to determine which dynamic code has been loaded. -typedef struct dyld_all_image_infos32 { - uint32_t version; // == 1 in Mac OS X 10.4 - uint32_t infoArrayCount; - uint32_t infoArray; // const struct dyld_image_info* - uint32_t notification; - bool processDetachedFromSharedRegion; -} dyld_all_image_infos32; - -typedef struct dyld_all_image_infos64 { - uint32_t version; // == 1 in Mac OS X 10.4 - uint32_t infoArrayCount; - uint64_t infoArray; // const struct dyld_image_info* - uint64_t notification; - bool processDetachedFromSharedRegion; -} dyld_all_image_infos64; - -// some typedefs to isolate 64/32 bit differences -#ifdef __LP64__ -typedef mach_header_64 breakpad_mach_header; -typedef segment_command_64 breakpad_mach_segment_command; -#else -typedef mach_header breakpad_mach_header; -typedef segment_command breakpad_mach_segment_command; -#endif - -// Helper functions to deal with 32-bit/64-bit Mach-O differences. -class DynamicImage; -template -bool FindTextSection(DynamicImage& image); - -template -uint32_t GetFileTypeFromHeader(DynamicImage& image); - -//============================================================================== -// Represents a single dynamically loaded mach-o image -class DynamicImage { - public: - DynamicImage(uint8_t *header, // data is copied - size_t header_size, // includes load commands - uint64_t load_address, - string file_path, - uintptr_t image_mod_date, - mach_port_t task, - cpu_type_t cpu_type) - : header_(header, header + header_size), - header_size_(header_size), - load_address_(load_address), - vmaddr_(0), - vmsize_(0), - slide_(0), - version_(0), - file_path_(file_path), - file_mod_date_(image_mod_date), - task_(task), - cpu_type_(cpu_type) { - CalculateMemoryAndVersionInfo(); - } - - // Size of mach_header plus load commands - size_t GetHeaderSize() const {return header_.size();} - - // Full path to mach-o binary - string GetFilePath() {return file_path_;} - - uint64_t GetModDate() const {return file_mod_date_;} - - // Actual address where the image was loaded - uint64_t GetLoadAddress() const {return load_address_;} - - // Address where the image should be loaded - mach_vm_address_t GetVMAddr() const {return vmaddr_;} - - // Difference between GetLoadAddress() and GetVMAddr() - ptrdiff_t GetVMAddrSlide() const {return slide_;} - - // Size of the image - mach_vm_size_t GetVMSize() const {return vmsize_;} - - // Task owning this loaded image - mach_port_t GetTask() {return task_;} - - // CPU type of the task - cpu_type_t GetCPUType() {return cpu_type_;} - - // filetype from the Mach-O header. - uint32_t GetFileType(); - - // Return true if the task is a 64-bit architecture. - bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; } - - uint32_t GetVersion() {return version_;} - // For sorting - bool operator<(const DynamicImage &inInfo) { - return GetLoadAddress() < inInfo.GetLoadAddress(); - } - - // Sanity checking - bool IsValid() {return GetVMSize() != 0;} - - private: - DynamicImage(const DynamicImage &); - DynamicImage &operator=(const DynamicImage &); - - friend class DynamicImages; - template - friend bool FindTextSection(DynamicImage& image); - template - friend uint32_t GetFileTypeFromHeader(DynamicImage& image); - - // Initializes vmaddr_, vmsize_, and slide_ - void CalculateMemoryAndVersionInfo(); - - const vector header_; // our local copy of the header - size_t header_size_; // mach_header plus load commands - uint64_t load_address_; // base address image is mapped into - mach_vm_address_t vmaddr_; - mach_vm_size_t vmsize_; - ptrdiff_t slide_; - uint32_t version_; // Dylib version - string file_path_; // path dyld used to load the image - uintptr_t file_mod_date_; // time_t of image file - - mach_port_t task_; - cpu_type_t cpu_type_; // CPU type of task_ -}; - -//============================================================================== -// DynamicImageRef is just a simple wrapper for a pointer to -// DynamicImage. The reason we use it instead of a simple typedef is so -// that we can use stl::sort() on a vector of DynamicImageRefs -// and simple class pointers can't implement operator<(). -// -class DynamicImageRef { - public: - explicit DynamicImageRef(DynamicImage *inP) : p(inP) {} - // The copy constructor is required by STL - DynamicImageRef(const DynamicImageRef &inRef) : p(inRef.p) {} - - bool operator<(const DynamicImageRef &inRef) const { - return (*const_cast(this)->p) - < (*const_cast(inRef).p); - } - - bool operator==(const DynamicImageRef &inInfo) const { - return (*const_cast(this)->p).GetLoadAddress() == - (*const_cast(inInfo)).GetLoadAddress(); - } - - // Be just like DynamicImage* - DynamicImage *operator->() {return p;} - operator DynamicImage*() {return p;} - - private: - DynamicImage *p; -}; - -// Helper function to deal with 32-bit/64-bit Mach-O differences. -class DynamicImages; -template -void ReadImageInfo(DynamicImages& images, uint64_t image_list_address); - -//============================================================================== -// An object of type DynamicImages may be created to allow introspection of -// an arbitrary task's dynamically loaded mach-o binaries. This makes the -// assumption that the current task has send rights to the target task. -class DynamicImages { - public: - explicit DynamicImages(mach_port_t task); - - ~DynamicImages() { - for (int i = 0; i < GetImageCount(); ++i) { - delete image_list_[i]; - } - } - - // Returns the number of dynamically loaded mach-o images. - int GetImageCount() const {return static_cast(image_list_.size());} - - // Returns an individual image. - DynamicImage *GetImage(int i) { - if (i < (int)image_list_.size()) { - return image_list_[i]; - } - return NULL; - } - - // Returns the image corresponding to the main executable. - DynamicImage *GetExecutableImage(); - int GetExecutableImageIndex(); - - // Returns the task which we're looking at. - mach_port_t GetTask() const {return task_;} - - // CPU type of the task - cpu_type_t GetCPUType() {return cpu_type_;} - - // Return true if the task is a 64-bit architecture. - bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; } - - // Determine the CPU type of the task being dumped. - static cpu_type_t DetermineTaskCPUType(task_t task); - - // Get the native CPU type of this task. - static cpu_type_t GetNativeCPUType() { -#if defined(__i386__) - return CPU_TYPE_I386; -#elif defined(__x86_64__) - return CPU_TYPE_X86_64; -#elif defined(__ppc__) - return CPU_TYPE_POWERPC; -#elif defined(__ppc64__) - return CPU_TYPE_POWERPC64; -#elif defined(__arm__) - return CPU_TYPE_ARM; -#elif defined(__aarch64__) - return CPU_TYPE_ARM64; -#else -#error "GetNativeCPUType not implemented for this architecture" -#endif - } - - private: - template - friend void ReadImageInfo(DynamicImages& images, uint64_t image_list_address); - - bool IsOurTask() {return task_ == mach_task_self();} - - // Initialization - void ReadImageInfoForTask(); - uint64_t GetDyldAllImageInfosPointer(); - - mach_port_t task_; - cpu_type_t cpu_type_; // CPU type of task_ - vector image_list_; -}; - -// Fill bytes with the contents of memory at a particular -// location in another task. -kern_return_t ReadTaskMemory(task_port_t target_task, - const uint64_t address, - size_t length, - vector &bytes); - -} // namespace google_breakpad - -#endif // CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.cc deleted file mode 100644 index dd0e1678c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.cc +++ /dev/null @@ -1,854 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include - -#include - -#include "client/mac/handler/exception_handler.h" -#include "client/mac/handler/minidump_generator.h" -#include "common/mac/macho_utilities.h" -#include "common/mac/scoped_task_suspend-inl.h" -#include "google_breakpad/common/minidump_exception_mac.h" - -#ifndef __EXCEPTIONS -// This file uses C++ try/catch (but shouldn't). Duplicate the macros from -// allowing this file to work properly with -// exceptions disabled even when other C++ libraries are used. #undef the try -// and catch macros first in case libstdc++ is in use and has already provided -// its own definitions. -#undef try -#define try if (true) -#undef catch -#define catch(X) if (false) -#endif // __EXCEPTIONS - -#ifndef USE_PROTECTED_ALLOCATIONS -#if TARGET_OS_IPHONE -#define USE_PROTECTED_ALLOCATIONS 1 -#else -#define USE_PROTECTED_ALLOCATIONS 0 -#endif -#endif - -// If USE_PROTECTED_ALLOCATIONS is activated then the -// gBreakpadAllocator needs to be setup in other code -// ahead of time. Please see ProtectedMemoryAllocator.h -// for more details. -#if USE_PROTECTED_ALLOCATIONS - #include "protected_memory_allocator.h" - extern ProtectedMemoryAllocator *gBreakpadAllocator; -#endif - -namespace google_breakpad { - -static union { -#if USE_PROTECTED_ALLOCATIONS -#if defined PAGE_MAX_SIZE - char protected_buffer[PAGE_MAX_SIZE] __attribute__((aligned(PAGE_MAX_SIZE))); -#else - char protected_buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); -#endif // defined PAGE_MAX_SIZE -#endif // USE_PROTECTED_ALLOCATIONS - google_breakpad::ExceptionHandler *handler; -} gProtectedData; - -using std::map; - -// These structures and techniques are illustrated in -// Mac OS X Internals, Amit Singh, ch 9.7 -struct ExceptionMessage { - mach_msg_header_t header; - mach_msg_body_t body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - NDR_record_t ndr; - exception_type_t exception; - mach_msg_type_number_t code_count; - integer_t code[EXCEPTION_CODE_MAX]; - char padding[512]; -}; - -struct ExceptionParameters { - ExceptionParameters() : count(0) {} - mach_msg_type_number_t count; - exception_mask_t masks[EXC_TYPES_COUNT]; - mach_port_t ports[EXC_TYPES_COUNT]; - exception_behavior_t behaviors[EXC_TYPES_COUNT]; - thread_state_flavor_t flavors[EXC_TYPES_COUNT]; -}; - -struct ExceptionReplyMessage { - mach_msg_header_t header; - NDR_record_t ndr; - kern_return_t return_code; -}; - -// Only catch these three exceptions. The other ones are nebulously defined -// and may result in treating a non-fatal exception as fatal. -exception_mask_t s_exception_mask = EXC_MASK_BAD_ACCESS | -EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT; - -#if !TARGET_OS_IPHONE -extern "C" { - // Forward declarations for functions that need "C" style compilation - boolean_t exc_server(mach_msg_header_t* request, - mach_msg_header_t* reply); - - // This symbol must be visible to dlsym() - see - // http://code.google.com/p/google-breakpad/issues/detail?id=345 for details. - kern_return_t catch_exception_raise(mach_port_t target_port, - mach_port_t failed_thread, - mach_port_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t code_count) - __attribute__((visibility("default"))); -} -#endif - -kern_return_t ForwardException(mach_port_t task, - mach_port_t failed_thread, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t code_count); - -#if TARGET_OS_IPHONE -// Implementation is based on the implementation generated by mig. -boolean_t breakpad_exc_server(mach_msg_header_t* InHeadP, - mach_msg_header_t* OutHeadP) { - OutHeadP->msgh_bits = - MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_remote_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if (InHeadP->msgh_id != 2401) { - ((mig_reply_error_t*)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t*)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - integer_t code[2]; - mach_msg_trailer_t trailer; - } Request; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - - Request* In0P = (Request*)InHeadP; - Reply* OutP = (Reply*)OutHeadP; - - if (In0P->task.name != mach_task_self()) { - return FALSE; - } - OutP->RetCode = ForwardException(In0P->task.name, - In0P->thread.name, - In0P->exception, - In0P->code, - In0P->codeCnt); - OutP->NDR = NDR_record; - return TRUE; -} -#else -boolean_t breakpad_exc_server(mach_msg_header_t* request, - mach_msg_header_t* reply) { - return exc_server(request, reply); -} - -// Callback from exc_server() -kern_return_t catch_exception_raise(mach_port_t port, mach_port_t failed_thread, - mach_port_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t code_count) { - if (task != mach_task_self()) { - return KERN_FAILURE; - } - return ForwardException(task, failed_thread, exception, code, code_count); -} -#endif - -ExceptionHandler::ExceptionHandler(const string &dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - bool install_handler, - const char* port_name) - : dump_path_(), - filter_(filter), - callback_(callback), - callback_context_(callback_context), - directCallback_(NULL), - handler_thread_(NULL), - handler_port_(MACH_PORT_NULL), - previous_(NULL), - installed_exception_handler_(false), - is_in_teardown_(false), - last_minidump_write_result_(false), - use_minidump_write_mutex_(false) { - // This will update to the ID and C-string pointers - set_dump_path(dump_path); - MinidumpGenerator::GatherSystemInformation(); -#if !TARGET_OS_IPHONE - if (port_name) - crash_generation_client_.reset(new CrashGenerationClient(port_name)); -#endif - Setup(install_handler); -} - -// special constructor if we want to bypass minidump writing and -// simply get a callback with the exception information -ExceptionHandler::ExceptionHandler(DirectCallback callback, - void* callback_context, - bool install_handler) - : dump_path_(), - filter_(NULL), - callback_(NULL), - callback_context_(callback_context), - directCallback_(callback), - handler_thread_(NULL), - handler_port_(MACH_PORT_NULL), - previous_(NULL), - installed_exception_handler_(false), - is_in_teardown_(false), - last_minidump_write_result_(false), - use_minidump_write_mutex_(false) { - MinidumpGenerator::GatherSystemInformation(); - Setup(install_handler); -} - -ExceptionHandler::~ExceptionHandler() { - Teardown(); -} - -bool ExceptionHandler::WriteMinidump(bool write_exception_stream) { - // If we're currently writing, just return - if (use_minidump_write_mutex_) - return false; - - use_minidump_write_mutex_ = true; - last_minidump_write_result_ = false; - - // Lock the mutex. Since we just created it, this will return immediately. - if (pthread_mutex_lock(&minidump_write_mutex_) == 0) { - // Send an empty message to the handle port so that a minidump will - // be written - bool result = SendMessageToHandlerThread(write_exception_stream ? - kWriteDumpWithExceptionMessage : - kWriteDumpMessage); - if (!result) { - pthread_mutex_unlock(&minidump_write_mutex_); - return false; - } - - // Wait for the minidump writer to complete its writing. It will unlock - // the mutex when completed - pthread_mutex_lock(&minidump_write_mutex_); - } - - use_minidump_write_mutex_ = false; - UpdateNextID(); - return last_minidump_write_result_; -} - -// static -bool ExceptionHandler::WriteMinidump(const string &dump_path, - bool write_exception_stream, - MinidumpCallback callback, - void* callback_context) { - ExceptionHandler handler(dump_path, NULL, callback, callback_context, false, - NULL); - return handler.WriteMinidump(write_exception_stream); -} - -// static -bool ExceptionHandler::WriteMinidumpForChild(mach_port_t child, - mach_port_t child_blamed_thread, - const string &dump_path, - MinidumpCallback callback, - void* callback_context) { - ScopedTaskSuspend suspend(child); - - MinidumpGenerator generator(child, MACH_PORT_NULL); - string dump_id; - string dump_filename = generator.UniqueNameInDirectory(dump_path, &dump_id); - - generator.SetExceptionInformation(EXC_BREAKPOINT, -#if defined(__i386__) || defined(__x86_64__) - EXC_I386_BPT, -#elif defined(__ppc__) || defined(__ppc64__) - EXC_PPC_BREAKPOINT, -#elif defined(__arm__) || defined(__aarch64__) - EXC_ARM_BREAKPOINT, -#else -#error architecture not supported -#endif - 0, - child_blamed_thread); - bool result = generator.Write(dump_filename.c_str()); - - if (callback) { - return callback(dump_path.c_str(), dump_id.c_str(), - callback_context, result); - } - return result; -} - -bool ExceptionHandler::WriteMinidumpWithException( - int exception_type, - int exception_code, - int exception_subcode, - breakpad_ucontext_t* task_context, - mach_port_t thread_name, - bool exit_after_write, - bool report_current_thread) { - bool result = false; - - if (directCallback_) { - if (directCallback_(callback_context_, - exception_type, - exception_code, - exception_subcode, - thread_name) ) { - if (exit_after_write) - _exit(exception_type); - } -#if !TARGET_OS_IPHONE - } else if (IsOutOfProcess()) { - if (exception_type && exception_code) { - // If this is a real exception, give the filter (if any) a chance to - // decide if this should be sent. - if (filter_ && !filter_(callback_context_)) - return false; - result = crash_generation_client_->RequestDumpForException( - exception_type, - exception_code, - exception_subcode, - thread_name); - if (result && exit_after_write) { - _exit(exception_type); - } - } -#endif - } else { - string minidump_id; - - // Putting the MinidumpGenerator in its own context will ensure that the - // destructor is executed, closing the newly created minidump file. - if (!dump_path_.empty()) { - MinidumpGenerator md(mach_task_self(), - report_current_thread ? MACH_PORT_NULL : - mach_thread_self()); - md.SetTaskContext(task_context); - if (exception_type && exception_code) { - // If this is a real exception, give the filter (if any) a chance to - // decide if this should be sent. - if (filter_ && !filter_(callback_context_)) - return false; - - md.SetExceptionInformation(exception_type, exception_code, - exception_subcode, thread_name); - } - - result = md.Write(next_minidump_path_c_); - } - - // Call user specified callback (if any) - if (callback_) { - // If the user callback returned true and we're handling an exception - // (rather than just writing out the file), then we should exit without - // forwarding the exception to the next handler. - if (callback_(dump_path_c_, next_minidump_id_c_, callback_context_, - result)) { - if (exit_after_write) - _exit(exception_type); - } - } - } - - return result; -} - -kern_return_t ForwardException(mach_port_t task, mach_port_t failed_thread, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t code_count) { - // At this time, we should have called Uninstall() on the exception handler - // so that the current exception ports are the ones that we should be - // forwarding to. - ExceptionParameters current; - - current.count = EXC_TYPES_COUNT; - mach_port_t current_task = mach_task_self(); - task_get_exception_ports(current_task, - s_exception_mask, - current.masks, - ¤t.count, - current.ports, - current.behaviors, - current.flavors); - - // Find the first exception handler that matches the exception - unsigned int found; - for (found = 0; found < current.count; ++found) { - if (current.masks[found] & (1 << exception)) { - break; - } - } - - // Nothing to forward - if (found == current.count) { - fprintf(stderr, "** No previous ports for forwarding!! \n"); - exit(KERN_FAILURE); - } - - mach_port_t target_port = current.ports[found]; - exception_behavior_t target_behavior = current.behaviors[found]; - - kern_return_t result; - // TODO: Handle the case where |target_behavior| has MACH_EXCEPTION_CODES - // set. https://code.google.com/p/google-breakpad/issues/detail?id=551 - switch (target_behavior) { - case EXCEPTION_DEFAULT: - result = exception_raise(target_port, failed_thread, task, exception, - code, code_count); - break; - default: - fprintf(stderr, "** Unknown exception behavior: %d\n", target_behavior); - result = KERN_FAILURE; - break; - } - - return result; -} - -// static -void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { - ExceptionHandler* self = - reinterpret_cast(exception_handler_class); - ExceptionMessage receive; - - // Wait for the exception info - while (1) { - receive.header.msgh_local_port = self->handler_port_; - receive.header.msgh_size = static_cast(sizeof(receive)); - kern_return_t result = mach_msg(&(receive.header), - MACH_RCV_MSG | MACH_RCV_LARGE, 0, - receive.header.msgh_size, - self->handler_port_, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - - if (result == KERN_SUCCESS) { - // Uninstall our handler so that we don't get in a loop if the process of - // writing out a minidump causes an exception. However, if the exception - // was caused by a fork'd process, don't uninstall things - - // If the actual exception code is zero, then we're calling this handler - // in a way that indicates that we want to either exit this thread or - // generate a minidump - // - // While reporting, all threads (except this one) must be suspended - // to avoid misleading stacks. If appropriate they will be resumed - // afterwards. - if (!receive.exception) { - // Don't touch self, since this message could have been sent - // from its destructor. - if (receive.header.msgh_id == kShutdownMessage) - return NULL; - - self->SuspendThreads(); - -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Unprotect(); -#endif - - mach_port_t thread = MACH_PORT_NULL; - int exception_type = 0; - int exception_code = 0; - if (receive.header.msgh_id == kWriteDumpWithExceptionMessage) { - thread = receive.thread.name; - exception_type = EXC_BREAKPOINT; -#if defined(__i386__) || defined(__x86_64__) - exception_code = EXC_I386_BPT; -#elif defined(__ppc__) || defined(__ppc64__) - exception_code = EXC_PPC_BREAKPOINT; -#elif defined(__arm__) || defined(__aarch64__) - exception_code = EXC_ARM_BREAKPOINT; -#else -#error architecture not supported -#endif - } - - // Write out the dump and save the result for later retrieval - self->last_minidump_write_result_ = - self->WriteMinidumpWithException(exception_type, exception_code, - 0, NULL, thread, - false, false); - -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Protect(); -#endif - - self->ResumeThreads(); - - if (self->use_minidump_write_mutex_) - pthread_mutex_unlock(&self->minidump_write_mutex_); - } else { - // When forking a child process with the exception handler installed, - // if the child crashes, it will send the exception back to the parent - // process. The check for task == self_task() ensures that only - // exceptions that occur in the parent process are caught and - // processed. If the exception was not caused by this task, we - // still need to call into the exception server and have it return - // KERN_FAILURE (see catch_exception_raise) in order for the kernel - // to move onto the host exception handler for the child task - if (receive.task.name == mach_task_self()) { - self->SuspendThreads(); - -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Unprotect(); -#endif - - int subcode = 0; - if (receive.exception == EXC_BAD_ACCESS && receive.code_count > 1) - subcode = receive.code[1]; - - // Generate the minidump with the exception data. - self->WriteMinidumpWithException(receive.exception, receive.code[0], - subcode, NULL, receive.thread.name, - true, false); - -#if USE_PROTECTED_ALLOCATIONS - // This may have become protected again within - // WriteMinidumpWithException, but it needs to be unprotected for - // UninstallHandler. - if (gBreakpadAllocator) - gBreakpadAllocator->Unprotect(); -#endif - - self->UninstallHandler(true); - -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Protect(); -#endif - } - // Pass along the exception to the server, which will setup the - // message and call catch_exception_raise() and put the return - // code into the reply. - ExceptionReplyMessage reply; - if (!breakpad_exc_server(&receive.header, &reply.header)) - exit(1); - - // Send a reply and exit - mach_msg(&(reply.header), MACH_SEND_MSG, - reply.header.msgh_size, 0, MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - } - } - } - - return NULL; -} - -// static -void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) { -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Unprotect(); -#endif - gProtectedData.handler->WriteMinidumpWithException( - EXC_SOFTWARE, - MD_EXCEPTION_CODE_MAC_ABORT, - 0, - static_cast(uc), - mach_thread_self(), - true, - true); -#if USE_PROTECTED_ALLOCATIONS - if (gBreakpadAllocator) - gBreakpadAllocator->Protect(); -#endif -} - -bool ExceptionHandler::InstallHandler() { - // If a handler is already installed, something is really wrong. - if (gProtectedData.handler != NULL) { - return false; - } - - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGABRT); - sa.sa_sigaction = ExceptionHandler::SignalHandler; - sa.sa_flags = SA_SIGINFO; - - scoped_ptr old(new struct sigaction); - if (sigaction(SIGABRT, &sa, old.get()) == -1) { - return false; - } - old_handler_.swap(old); - gProtectedData.handler = this; -#if USE_PROTECTED_ALLOCATIONS - assert(((size_t)(gProtectedData.protected_buffer) & PAGE_MASK) == 0); - mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ); -#endif - - try { -#if USE_PROTECTED_ALLOCATIONS - previous_ = new (gBreakpadAllocator->Allocate(sizeof(ExceptionParameters)) ) - ExceptionParameters(); -#else - previous_ = new ExceptionParameters(); -#endif - } - catch (std::bad_alloc) { - return false; - } - - // Save the current exception ports so that we can forward to them - previous_->count = EXC_TYPES_COUNT; - mach_port_t current_task = mach_task_self(); - kern_return_t result = task_get_exception_ports(current_task, - s_exception_mask, - previous_->masks, - &previous_->count, - previous_->ports, - previous_->behaviors, - previous_->flavors); - - // Setup the exception ports on this task - if (result == KERN_SUCCESS) - result = task_set_exception_ports(current_task, s_exception_mask, - handler_port_, EXCEPTION_DEFAULT, - THREAD_STATE_NONE); - - installed_exception_handler_ = (result == KERN_SUCCESS); - - return installed_exception_handler_; -} - -bool ExceptionHandler::UninstallHandler(bool in_exception) { - kern_return_t result = KERN_SUCCESS; - - if (old_handler_.get()) { - sigaction(SIGABRT, old_handler_.get(), NULL); -#if USE_PROTECTED_ALLOCATIONS - mprotect(gProtectedData.protected_buffer, PAGE_SIZE, - PROT_READ | PROT_WRITE); -#endif - old_handler_.reset(); - gProtectedData.handler = NULL; - } - - if (installed_exception_handler_) { - mach_port_t current_task = mach_task_self(); - - // Restore the previous ports - for (unsigned int i = 0; i < previous_->count; ++i) { - result = task_set_exception_ports(current_task, previous_->masks[i], - previous_->ports[i], - previous_->behaviors[i], - previous_->flavors[i]); - if (result != KERN_SUCCESS) - return false; - } - - // this delete should NOT happen if an exception just occurred! - if (!in_exception) { -#if USE_PROTECTED_ALLOCATIONS - previous_->~ExceptionParameters(); -#else - delete previous_; -#endif - } - - previous_ = NULL; - installed_exception_handler_ = false; - } - - return result == KERN_SUCCESS; -} - -bool ExceptionHandler::Setup(bool install_handler) { - if (pthread_mutex_init(&minidump_write_mutex_, NULL)) - return false; - - // Create a receive right - mach_port_t current_task = mach_task_self(); - kern_return_t result = mach_port_allocate(current_task, - MACH_PORT_RIGHT_RECEIVE, - &handler_port_); - // Add send right - if (result == KERN_SUCCESS) - result = mach_port_insert_right(current_task, handler_port_, handler_port_, - MACH_MSG_TYPE_MAKE_SEND); - - if (install_handler && result == KERN_SUCCESS) - if (!InstallHandler()) - return false; - - if (result == KERN_SUCCESS) { - // Install the handler in its own thread, detached as we won't be joining. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - int thread_create_result = pthread_create(&handler_thread_, &attr, - &WaitForMessage, this); - pthread_attr_destroy(&attr); - result = thread_create_result ? KERN_FAILURE : KERN_SUCCESS; - } - - return result == KERN_SUCCESS; -} - -bool ExceptionHandler::Teardown() { - kern_return_t result = KERN_SUCCESS; - is_in_teardown_ = true; - - if (!UninstallHandler(false)) - return false; - - // Send an empty message so that the handler_thread exits - if (SendMessageToHandlerThread(kShutdownMessage)) { - mach_port_t current_task = mach_task_self(); - result = mach_port_deallocate(current_task, handler_port_); - if (result != KERN_SUCCESS) - return false; - } else { - return false; - } - - handler_thread_ = NULL; - handler_port_ = MACH_PORT_NULL; - pthread_mutex_destroy(&minidump_write_mutex_); - - return result == KERN_SUCCESS; -} - -bool ExceptionHandler::SendMessageToHandlerThread( - HandlerThreadMessage message_id) { - ExceptionMessage msg; - memset(&msg, 0, sizeof(msg)); - msg.header.msgh_id = message_id; - if (message_id == kWriteDumpMessage || - message_id == kWriteDumpWithExceptionMessage) { - // Include this thread's port. - msg.thread.name = mach_thread_self(); - msg.thread.disposition = MACH_MSG_TYPE_PORT_SEND; - msg.thread.type = MACH_MSG_PORT_DESCRIPTOR; - } - msg.header.msgh_size = sizeof(msg) - sizeof(msg.padding); - msg.header.msgh_remote_port = handler_port_; - msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, - MACH_MSG_TYPE_MAKE_SEND_ONCE); - kern_return_t result = mach_msg(&(msg.header), - MACH_SEND_MSG | MACH_SEND_TIMEOUT, - msg.header.msgh_size, 0, 0, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - return result == KERN_SUCCESS; -} - -void ExceptionHandler::UpdateNextID() { - next_minidump_path_ = - (MinidumpGenerator::UniqueNameInDirectory(dump_path_, &next_minidump_id_)); - - next_minidump_path_c_ = next_minidump_path_.c_str(); - next_minidump_id_c_ = next_minidump_id_.c_str(); -} - -bool ExceptionHandler::SuspendThreads() { - thread_act_port_array_t threads_for_task; - mach_msg_type_number_t thread_count; - - if (task_threads(mach_task_self(), &threads_for_task, &thread_count)) - return false; - - // suspend all of the threads except for this one - for (unsigned int i = 0; i < thread_count; ++i) { - if (threads_for_task[i] != mach_thread_self()) { - if (thread_suspend(threads_for_task[i])) - return false; - } - } - - return true; -} - -bool ExceptionHandler::ResumeThreads() { - thread_act_port_array_t threads_for_task; - mach_msg_type_number_t thread_count; - - if (task_threads(mach_task_self(), &threads_for_task, &thread_count)) - return false; - - // resume all of the threads except for this one - for (unsigned int i = 0; i < thread_count; ++i) { - if (threads_for_task[i] != mach_thread_self()) { - if (thread_resume(threads_for_task[i])) - return false; - } - } - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.h deleted file mode 100644 index f1d9ae92d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/exception_handler.h +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exception_handler.h: MacOS exception handler -// This class can install a Mach exception port handler to trap most common -// programming errors. If an exception occurs, a minidump file will be -// generated which contains detailed information about the process and the -// exception. - -#ifndef CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ -#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ - -#include -#include - -#include - -#include "client/mac/handler/ucontext_compat.h" -#include "common/scoped_ptr.h" - -#if !TARGET_OS_IPHONE -#include "client/mac/crash_generation/crash_generation_client.h" -#endif - -namespace google_breakpad { - -using std::string; - -struct ExceptionParameters; - -enum HandlerThreadMessage { - // Message ID telling the handler thread to write a dump. - kWriteDumpMessage = 0, - // Message ID telling the handler thread to write a dump and include - // an exception stream. - kWriteDumpWithExceptionMessage = 1, - // Message ID telling the handler thread to quit. - kShutdownMessage = 2 -}; - -class ExceptionHandler { - public: - // A callback function to run before Breakpad performs any substantial - // processing of an exception. A FilterCallback is called before writing - // a minidump. context is the parameter supplied by the user as - // callback_context when the handler was created. - // - // If a FilterCallback returns true, Breakpad will continue processing, - // attempting to write a minidump. If a FilterCallback returns false, Breakpad - // will immediately report the exception as unhandled without writing a - // minidump, allowing another handler the opportunity to handle it. - typedef bool (*FilterCallback)(void *context); - - // A callback function to run after the minidump has been written. - // |minidump_id| is a unique id for the dump, so the minidump - // file is /.dmp. - // |context| is the value passed into the constructor. - // |succeeded| indicates whether a minidump file was successfully written. - // Return true if the exception was fully handled and breakpad should exit. - // Return false to allow any other exception handlers to process the - // exception. - typedef bool (*MinidumpCallback)(const char *dump_dir, - const char *minidump_id, - void *context, bool succeeded); - - // A callback function which will be called directly if an exception occurs. - // This bypasses the minidump file writing and simply gives the client - // the exception information. - typedef bool (*DirectCallback)( void *context, - int exception_type, - int exception_code, - int exception_subcode, - mach_port_t thread_name); - - // Creates a new ExceptionHandler instance to handle writing minidumps. - // Minidump files will be written to dump_path, and the optional callback - // is called after writing the dump file, as described above. - // If install_handler is true, then a minidump will be written whenever - // an unhandled exception occurs. If it is false, minidumps will only - // be written when WriteMinidump is called. - // If port_name is non-NULL, attempt to perform out-of-process dump generation - // If port_name is NULL, in-process dump generation will be used. - ExceptionHandler(const string &dump_path, - FilterCallback filter, MinidumpCallback callback, - void *callback_context, bool install_handler, - const char *port_name); - - // A special constructor if we want to bypass minidump writing and - // simply get a callback with the exception information. - ExceptionHandler(DirectCallback callback, - void *callback_context, - bool install_handler); - - ~ExceptionHandler(); - - // Get and set the minidump path. - string dump_path() const { return dump_path_; } - void set_dump_path(const string &dump_path) { - dump_path_ = dump_path; - dump_path_c_ = dump_path_.c_str(); - UpdateNextID(); // Necessary to put dump_path_ in next_minidump_path_. - } - - // Writes a minidump immediately. This can be used to capture the - // execution state independently of a crash. Returns true on success. - bool WriteMinidump() { - return WriteMinidump(false); - } - - bool WriteMinidump(bool write_exception_stream); - - // Convenience form of WriteMinidump which does not require an - // ExceptionHandler instance. - static bool WriteMinidump(const string &dump_path, MinidumpCallback callback, - void *callback_context) { - return WriteMinidump(dump_path, false, callback, callback_context); - } - - static bool WriteMinidump(const string &dump_path, - bool write_exception_stream, - MinidumpCallback callback, - void *callback_context); - - // Write a minidump of child immediately. This can be used to capture - // the execution state of a child process independently of a crash. - static bool WriteMinidumpForChild(mach_port_t child, - mach_port_t child_blamed_thread, - const std::string &dump_path, - MinidumpCallback callback, - void *callback_context); - - // Returns whether out-of-process dump generation is used or not. - bool IsOutOfProcess() const { -#if TARGET_OS_IPHONE - return false; -#else - return crash_generation_client_.get() != NULL; -#endif - } - - private: - // Install the mach exception handler - bool InstallHandler(); - - // Uninstall the mach exception handler (if any) - bool UninstallHandler(bool in_exception); - - // Setup the handler thread, and if |install_handler| is true, install the - // mach exception port handler - bool Setup(bool install_handler); - - // Uninstall the mach exception handler (if any) and terminate the helper - // thread - bool Teardown(); - - // Send a mach message to the exception handler. Return true on - // success, false otherwise. - bool SendMessageToHandlerThread(HandlerThreadMessage message_id); - - // All minidump writing goes through this one routine. - // |task_context| can be NULL. If not, it will be used to retrieve the - // context of the current thread, instead of using |thread_get_state|. - bool WriteMinidumpWithException(int exception_type, - int exception_code, - int exception_subcode, - breakpad_ucontext_t *task_context, - mach_port_t thread_name, - bool exit_after_write, - bool report_current_thread); - - // When installed, this static function will be call from a newly created - // pthread with |this| as the argument - static void *WaitForMessage(void *exception_handler_class); - - // Signal handler for SIGABRT. - static void SignalHandler(int sig, siginfo_t* info, void* uc); - - // disallow copy ctor and operator= - explicit ExceptionHandler(const ExceptionHandler &); - void operator=(const ExceptionHandler &); - - // Generates a new ID and stores it in next_minidump_id_, and stores the - // path of the next minidump to be written in next_minidump_path_. - void UpdateNextID(); - - // These functions will suspend/resume all threads except for the - // reporting thread - bool SuspendThreads(); - bool ResumeThreads(); - - // The destination directory for the minidump - string dump_path_; - - // The basename of the next minidump w/o extension - string next_minidump_id_; - - // The full path to the next minidump to be written, including extension - string next_minidump_path_; - - // Pointers to the UTF-8 versions of above - const char *dump_path_c_; - const char *next_minidump_id_c_; - const char *next_minidump_path_c_; - - // The callback function and pointer to be passed back after the minidump - // has been written - FilterCallback filter_; - MinidumpCallback callback_; - void *callback_context_; - - // The callback function to be passed back when we don't want a minidump - // file to be written - DirectCallback directCallback_; - - // The thread that is created for the handler - pthread_t handler_thread_; - - // The port that is waiting on an exception message to be sent, if the - // handler is installed - mach_port_t handler_port_; - - // These variables save the previous exception handler's data so that it - // can be re-installed when this handler is uninstalled - ExceptionParameters *previous_; - - // True, if we've installed the exception handler - bool installed_exception_handler_; - - // True, if we're in the process of uninstalling the exception handler and - // the thread. - bool is_in_teardown_; - - // Save the last result of the last minidump - bool last_minidump_write_result_; - - // A mutex for use when writing out a minidump that was requested on a - // thread other than the exception handler. - pthread_mutex_t minidump_write_mutex_; - - // True, if we're using the mutext to indicate when mindump writing occurs - bool use_minidump_write_mutex_; - - // Old signal handler for SIGABRT. Used to be able to restore it when - // uninstalling. - scoped_ptr old_handler_; - -#if !TARGET_OS_IPHONE - // Client for out-of-process dump generation. - scoped_ptr crash_generation_client_; -#endif -}; - -} // namespace google_breakpad - -#endif // CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/mach_vm_compat.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/mach_vm_compat.h deleted file mode 100644 index 9e9028b92..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/mach_vm_compat.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_ -#define CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_ - -#include - -// On iOS 5 and higher, mach/mach_vm.h is not supported. Use the corresponding -// vm_map functions instead. -#if TARGET_OS_IPHONE -#include -#define mach_vm_address_t vm_address_t -#define mach_vm_deallocate vm_deallocate -#define mach_vm_read vm_read -#define mach_vm_region_recurse vm_region_recurse_64 -#define mach_vm_size_t vm_size_t -#else -#include -#endif // TARGET_OS_IPHONE - -#endif // CLIENT_MAC_GENERATOR_MACH_VM_COMPAT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc deleted file mode 100644 index 48cd2e99b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc +++ /dev/null @@ -1,1604 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "client/mac/handler/minidump_generator.h" - -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) -#include -#endif -#ifdef HAS_PPC_SUPPORT -#include -#endif -#ifdef HAS_X86_SUPPORT -#include -#endif - -#include "client/minidump_file_writer-inl.h" -#include "common/mac/file_id.h" -#include "common/mac/macho_id.h" -#include "common/mac/string_utilities.h" - -using MacStringUtils::ConvertToString; -using MacStringUtils::IntegerValueAtIndex; - -namespace google_breakpad { - -#if defined(__LP64__) && __LP64__ -#define LC_SEGMENT_ARCH LC_SEGMENT_64 -#else -#define LC_SEGMENT_ARCH LC_SEGMENT -#endif - -// constructor when generating from within the crashed process -MinidumpGenerator::MinidumpGenerator() - : writer_(), - exception_type_(0), - exception_code_(0), - exception_subcode_(0), - exception_thread_(0), - crashing_task_(mach_task_self()), - handler_thread_(mach_thread_self()), - cpu_type_(DynamicImages::GetNativeCPUType()), - task_context_(NULL), - dynamic_images_(NULL), - memory_blocks_(&allocator_) { - GatherSystemInformation(); -} - -// constructor when generating from a different process than the -// crashed process -MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, - mach_port_t handler_thread) - : writer_(), - exception_type_(0), - exception_code_(0), - exception_subcode_(0), - exception_thread_(0), - crashing_task_(crashing_task), - handler_thread_(handler_thread), - cpu_type_(DynamicImages::GetNativeCPUType()), - task_context_(NULL), - dynamic_images_(NULL), - memory_blocks_(&allocator_) { - if (crashing_task != mach_task_self()) { - dynamic_images_ = new DynamicImages(crashing_task_); - cpu_type_ = dynamic_images_->GetCPUType(); - } else { - dynamic_images_ = NULL; - cpu_type_ = DynamicImages::GetNativeCPUType(); - } - - GatherSystemInformation(); -} - -MinidumpGenerator::~MinidumpGenerator() { - delete dynamic_images_; -} - -char MinidumpGenerator::build_string_[16]; -int MinidumpGenerator::os_major_version_ = 0; -int MinidumpGenerator::os_minor_version_ = 0; -int MinidumpGenerator::os_build_number_ = 0; - -// static -void MinidumpGenerator::GatherSystemInformation() { - // If this is non-zero, then we've already gathered the information - if (os_major_version_) - return; - - // This code extracts the version and build information from the OS - CFStringRef vers_path = - CFSTR("/System/Library/CoreServices/SystemVersion.plist"); - CFURLRef sys_vers = - CFURLCreateWithFileSystemPath(NULL, - vers_path, - kCFURLPOSIXPathStyle, - false); - CFReadStreamRef read_stream = CFReadStreamCreateWithFile(NULL, sys_vers); - CFRelease(sys_vers); - if (!read_stream) { - return; - } - if (!CFReadStreamOpen(read_stream)) { - CFRelease(read_stream); - return; - } - CFMutableDataRef data = NULL; - while (true) { - // Actual data file tests: Mac at 480 bytes and iOS at 413 bytes. - const CFIndex kMaxBufferLength = 1024; - UInt8 data_bytes[kMaxBufferLength]; - CFIndex num_bytes_read = - CFReadStreamRead(read_stream, data_bytes, kMaxBufferLength); - if (num_bytes_read < 0) { - if (data) { - CFRelease(data); - data = NULL; - } - break; - } else if (num_bytes_read == 0) { - break; - } else if (!data) { - data = CFDataCreateMutable(NULL, 0); - } - CFDataAppendBytes(data, data_bytes, num_bytes_read); - } - CFReadStreamClose(read_stream); - CFRelease(read_stream); - if (!data) { - return; - } - CFDictionaryRef list = - static_cast(CFPropertyListCreateWithData( - NULL, data, kCFPropertyListImmutable, NULL, NULL)); - CFRelease(data); - if (!list) { - return; - } - CFStringRef build_version = static_cast - (CFDictionaryGetValue(list, CFSTR("ProductBuildVersion"))); - CFStringRef product_version = static_cast - (CFDictionaryGetValue(list, CFSTR("ProductVersion"))); - string build_str = ConvertToString(build_version); - string product_str = ConvertToString(product_version); - - CFRelease(list); - - strlcpy(build_string_, build_str.c_str(), sizeof(build_string_)); - - // Parse the string that looks like "10.4.8" - os_major_version_ = IntegerValueAtIndex(product_str, 0); - os_minor_version_ = IntegerValueAtIndex(product_str, 1); - os_build_number_ = IntegerValueAtIndex(product_str, 2); -} - -void MinidumpGenerator::SetTaskContext(breakpad_ucontext_t *task_context) { - task_context_ = task_context; -} - -string MinidumpGenerator::UniqueNameInDirectory(const string &dir, - string *unique_name) { - CFUUIDRef uuid = CFUUIDCreate(NULL); - CFStringRef uuid_cfstr = CFUUIDCreateString(NULL, uuid); - CFRelease(uuid); - string file_name(ConvertToString(uuid_cfstr)); - CFRelease(uuid_cfstr); - string path(dir); - - // Ensure that the directory (if non-empty) has a trailing slash so that - // we can append the file name and have a valid pathname. - if (!dir.empty()) { - if (dir.at(dir.size() - 1) != '/') - path.append(1, '/'); - } - - path.append(file_name); - path.append(".dmp"); - - if (unique_name) - *unique_name = file_name; - - return path; -} - -bool MinidumpGenerator::Write(const char *path) { - WriteStreamFN writers[] = { - &MinidumpGenerator::WriteThreadListStream, - &MinidumpGenerator::WriteMemoryListStream, - &MinidumpGenerator::WriteSystemInfoStream, - &MinidumpGenerator::WriteModuleListStream, - &MinidumpGenerator::WriteMiscInfoStream, - &MinidumpGenerator::WriteBreakpadInfoStream, - // Exception stream needs to be the last entry in this array as it may - // be omitted in the case where the minidump is written without an - // exception. - &MinidumpGenerator::WriteExceptionStream, - }; - bool result = false; - - // If opening was successful, create the header, directory, and call each - // writer. The destructor for the TypedMDRVAs will cause the data to be - // flushed. The destructor for the MinidumpFileWriter will close the file. - if (writer_.Open(path)) { - TypedMDRVA header(&writer_); - TypedMDRVA dir(&writer_); - - if (!header.Allocate()) - return false; - - int writer_count = static_cast(sizeof(writers) / sizeof(writers[0])); - - // If we don't have exception information, don't write out the - // exception stream - if (!exception_thread_ && !exception_type_) - --writer_count; - - // Add space for all writers - if (!dir.AllocateArray(writer_count)) - return false; - - MDRawHeader *header_ptr = header.get(); - header_ptr->signature = MD_HEADER_SIGNATURE; - header_ptr->version = MD_HEADER_VERSION; - time(reinterpret_cast(&(header_ptr->time_date_stamp))); - header_ptr->stream_count = writer_count; - header_ptr->stream_directory_rva = dir.position(); - - MDRawDirectory local_dir; - result = true; - for (int i = 0; (result) && (i < writer_count); ++i) { - result = (this->*writers[i])(&local_dir); - - if (result) - dir.CopyIndex(i, &local_dir); - } - } - return result; -} - -size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) { - mach_vm_address_t stack_region_base = start_addr; - mach_vm_size_t stack_region_size; - natural_t nesting_level = 0; - vm_region_submap_info_64 submap_info; - mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64; - - vm_region_recurse_info_t region_info; - region_info = reinterpret_cast(&submap_info); - - if (start_addr == 0) { - return 0; - } - - kern_return_t result = - mach_vm_region_recurse(crashing_task_, &stack_region_base, - &stack_region_size, &nesting_level, - region_info, &info_count); - - if (result != KERN_SUCCESS || start_addr < stack_region_base) { - // Failure or stack corruption, since mach_vm_region had to go - // higher in the process address space to find a valid region. - return 0; - } - - unsigned int tag = submap_info.user_tag; - - // If the user tag is VM_MEMORY_STACK, look for more readable regions with - // the same tag placed immediately above the computed stack region. Under - // some circumstances, the stack for thread 0 winds up broken up into - // multiple distinct abutting regions. This can happen for several reasons, - // including user code that calls setrlimit(RLIMIT_STACK, ...) or changes - // the access on stack pages by calling mprotect. - if (tag == VM_MEMORY_STACK) { - while (true) { - mach_vm_address_t next_region_base = stack_region_base + - stack_region_size; - mach_vm_address_t proposed_next_region_base = next_region_base; - mach_vm_size_t next_region_size; - nesting_level = 0; - info_count = VM_REGION_SUBMAP_INFO_COUNT_64; - result = mach_vm_region_recurse(crashing_task_, &next_region_base, - &next_region_size, &nesting_level, - region_info, &info_count); - if (result != KERN_SUCCESS || - next_region_base != proposed_next_region_base || - submap_info.user_tag != tag || - (submap_info.protection & VM_PROT_READ) == 0) { - break; - } - - stack_region_size += next_region_size; - } - } - - return stack_region_base + stack_region_size - start_addr; -} - -bool MinidumpGenerator::WriteStackFromStartAddress( - mach_vm_address_t start_addr, - MDMemoryDescriptor *stack_location) { - UntypedMDRVA memory(&writer_); - - bool result = false; - size_t size = CalculateStackSize(start_addr); - - if (size == 0) { - // In some situations the stack address for the thread can come back 0. - // In these cases we skip over the threads in question and stuff the - // stack with a clearly borked value. - start_addr = 0xDEADBEEF; - size = 16; - if (!memory.Allocate(size)) - return false; - - unsigned long long dummy_stack[2]; // Fill dummy stack with 16 bytes of - // junk. - dummy_stack[0] = 0xDEADBEEF; - dummy_stack[1] = 0xDEADBEEF; - - result = memory.Copy(dummy_stack, size); - } else { - - if (!memory.Allocate(size)) - return false; - - if (dynamic_images_) { - vector stack_memory; - if (ReadTaskMemory(crashing_task_, - start_addr, - size, - stack_memory) != KERN_SUCCESS) { - return false; - } - - result = memory.Copy(&stack_memory[0], size); - } else { - result = memory.Copy(reinterpret_cast(start_addr), size); - } - } - - stack_location->start_of_memory_range = start_addr; - stack_location->memory = memory.location(); - - return result; -} - -bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - return WriteStackARM(state, stack_location); -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: - return WriteStackARM64(state, stack_location); -#endif -#ifdef HAS_PPC_SUPPORT - case CPU_TYPE_POWERPC: - return WriteStackPPC(state, stack_location); - case CPU_TYPE_POWERPC64: - return WriteStackPPC64(state, stack_location); -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - return WriteStackX86(state, stack_location); - case CPU_TYPE_X86_64: - return WriteStackX86_64(state, stack_location); -#endif - default: - return false; - } -} - -bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) { - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - return WriteContextARM(state, register_location); -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: - return WriteContextARM64(state, register_location); -#endif -#ifdef HAS_PPC_SUPPORT - case CPU_TYPE_POWERPC: - return WriteContextPPC(state, register_location); - case CPU_TYPE_POWERPC64: - return WriteContextPPC64(state, register_location); -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - return WriteContextX86(state, register_location); - case CPU_TYPE_X86_64: - return WriteContextX86_64(state, register_location); -#endif - default: - return false; - } -} - -uint64_t MinidumpGenerator::CurrentPCForStack( - breakpad_thread_state_data_t state) { - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - return CurrentPCForStackARM(state); -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: - return CurrentPCForStackARM64(state); -#endif -#ifdef HAS_PPC_SUPPORT - case CPU_TYPE_POWERPC: - return CurrentPCForStackPPC(state); - case CPU_TYPE_POWERPC64: - return CurrentPCForStackPPC64(state); -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - return CurrentPCForStackX86(state); - case CPU_TYPE_X86_64: - return CurrentPCForStackX86_64(state); -#endif - default: - assert(0 && "Unknown CPU type!"); - return 0; - } -} - -#ifdef HAS_ARM_SUPPORT -bool MinidumpGenerator::WriteStackARM(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - arm_thread_state_t *machine_state = - reinterpret_cast(state); - mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) { - arm_thread_state_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, pc); -} - -bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) -{ - TypedMDRVA context(&writer_); - arm_thread_state_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextARM *context_ptr = context.get(); - context_ptr->context_flags = MD_CONTEXT_ARM_FULL; - -#define AddGPR(a) context_ptr->iregs[a] = REGISTER_FROM_THREADSTATE(machine_state, r[a]) - - context_ptr->iregs[13] = REGISTER_FROM_THREADSTATE(machine_state, sp); - context_ptr->iregs[14] = REGISTER_FROM_THREADSTATE(machine_state, lr); - context_ptr->iregs[15] = REGISTER_FROM_THREADSTATE(machine_state, pc); - context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr); - - AddGPR(0); - AddGPR(1); - AddGPR(2); - AddGPR(3); - AddGPR(4); - AddGPR(5); - AddGPR(6); - AddGPR(7); - AddGPR(8); - AddGPR(9); - AddGPR(10); - AddGPR(11); - AddGPR(12); -#undef AddGPR - - return true; -} -#endif - -#ifdef HAS_ARM64_SUPPORT -bool MinidumpGenerator::WriteStackARM64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - arm_thread_state64_t *machine_state = - reinterpret_cast(state); - mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackARM64(breakpad_thread_state_data_t state) { - arm_thread_state64_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, pc); -} - -bool -MinidumpGenerator::WriteContextARM64(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) -{ - TypedMDRVA context(&writer_); - arm_thread_state64_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextARM64 *context_ptr = context.get(); - context_ptr->context_flags = MD_CONTEXT_ARM64_FULL; - -#define AddGPR(a) context_ptr->iregs[a] = \ - REGISTER_FROM_THREADSTATE(machine_state, x[a]) - - context_ptr->iregs[29] = REGISTER_FROM_THREADSTATE(machine_state, fp); - context_ptr->iregs[30] = REGISTER_FROM_THREADSTATE(machine_state, lr); - context_ptr->iregs[31] = REGISTER_FROM_THREADSTATE(machine_state, sp); - context_ptr->iregs[32] = REGISTER_FROM_THREADSTATE(machine_state, pc); - context_ptr->cpsr = REGISTER_FROM_THREADSTATE(machine_state, cpsr); - - AddGPR(0); - AddGPR(1); - AddGPR(2); - AddGPR(3); - AddGPR(4); - AddGPR(5); - AddGPR(6); - AddGPR(7); - AddGPR(8); - AddGPR(9); - AddGPR(10); - AddGPR(11); - AddGPR(12); - AddGPR(13); - AddGPR(14); - AddGPR(15); - AddGPR(16); - AddGPR(17); - AddGPR(18); - AddGPR(19); - AddGPR(20); - AddGPR(21); - AddGPR(22); - AddGPR(23); - AddGPR(24); - AddGPR(25); - AddGPR(26); - AddGPR(27); - AddGPR(28); -#undef AddGPR - - return true; -} -#endif - -#ifdef HAS_PCC_SUPPORT -bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - ppc_thread_state_t *machine_state = - reinterpret_cast(state); - mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - ppc_thread_state64_t *machine_state = - reinterpret_cast(state); - mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackPPC(breakpad_thread_state_data_t state) { - ppc_thread_state_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, srr0); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackPPC64(breakpad_thread_state_data_t state) { - ppc_thread_state64_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, srr0); -} - -bool MinidumpGenerator::WriteContextPPC(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) -{ - TypedMDRVA context(&writer_); - ppc_thread_state_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextPPC *context_ptr = context.get(); - context_ptr->context_flags = MD_CONTEXT_PPC_BASE; - -#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, a)) -#define AddGPR(a) context_ptr->gpr[a] = \ - static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, r ## a) - - AddReg(srr0); - AddReg(cr); - AddReg(xer); - AddReg(ctr); - AddReg(lr); - AddReg(vrsave); - - AddGPR(0); - AddGPR(1); - AddGPR(2); - AddGPR(3); - AddGPR(4); - AddGPR(5); - AddGPR(6); - AddGPR(7); - AddGPR(8); - AddGPR(9); - AddGPR(10); - AddGPR(11); - AddGPR(12); - AddGPR(13); - AddGPR(14); - AddGPR(15); - AddGPR(16); - AddGPR(17); - AddGPR(18); - AddGPR(19); - AddGPR(20); - AddGPR(21); - AddGPR(22); - AddGPR(23); - AddGPR(24); - AddGPR(25); - AddGPR(26); - AddGPR(27); - AddGPR(28); - AddGPR(29); - AddGPR(30); - AddGPR(31); - AddReg(mq); -#undef AddReg -#undef AddGPR - - return true; -} - -bool MinidumpGenerator::WriteContextPPC64( - breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) { - TypedMDRVA context(&writer_); - ppc_thread_state64_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextPPC64 *context_ptr = context.get(); - context_ptr->context_flags = MD_CONTEXT_PPC_BASE; - -#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, a)) -#define AddGPR(a) context_ptr->gpr[a] = \ - static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, r ## a) - - AddReg(srr0); - AddReg(cr); - AddReg(xer); - AddReg(ctr); - AddReg(lr); - AddReg(vrsave); - - AddGPR(0); - AddGPR(1); - AddGPR(2); - AddGPR(3); - AddGPR(4); - AddGPR(5); - AddGPR(6); - AddGPR(7); - AddGPR(8); - AddGPR(9); - AddGPR(10); - AddGPR(11); - AddGPR(12); - AddGPR(13); - AddGPR(14); - AddGPR(15); - AddGPR(16); - AddGPR(17); - AddGPR(18); - AddGPR(19); - AddGPR(20); - AddGPR(21); - AddGPR(22); - AddGPR(23); - AddGPR(24); - AddGPR(25); - AddGPR(26); - AddGPR(27); - AddGPR(28); - AddGPR(29); - AddGPR(30); - AddGPR(31); -#undef AddReg -#undef AddGPR - - return true; -} - -#endif - -#ifdef HAS_X86_SUPPORT -bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - i386_thread_state_t *machine_state = - reinterpret_cast(state); - - mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location) { - x86_thread_state64_t *machine_state = - reinterpret_cast(state); - - mach_vm_address_t start_addr = static_cast( - REGISTER_FROM_THREADSTATE(machine_state, rsp)); - return WriteStackFromStartAddress(start_addr, stack_location); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackX86(breakpad_thread_state_data_t state) { - i386_thread_state_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, eip); -} - -uint64_t -MinidumpGenerator::CurrentPCForStackX86_64(breakpad_thread_state_data_t state) { - x86_thread_state64_t *machine_state = - reinterpret_cast(state); - - return REGISTER_FROM_THREADSTATE(machine_state, rip); -} - -bool MinidumpGenerator::WriteContextX86(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) -{ - TypedMDRVA context(&writer_); - i386_thread_state_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextX86 *context_ptr = context.get(); - -#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, a)) - - context_ptr->context_flags = MD_CONTEXT_X86; - AddReg(eax); - AddReg(ebx); - AddReg(ecx); - AddReg(edx); - AddReg(esi); - AddReg(edi); - AddReg(ebp); - AddReg(esp); - - AddReg(cs); - AddReg(ds); - AddReg(ss); - AddReg(es); - AddReg(fs); - AddReg(gs); - AddReg(eflags); - - AddReg(eip); -#undef AddReg - - return true; -} - -bool MinidumpGenerator::WriteContextX86_64( - breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location) { - TypedMDRVA context(&writer_); - x86_thread_state64_t *machine_state = - reinterpret_cast(state); - - if (!context.Allocate()) - return false; - - *register_location = context.location(); - MDRawContextAMD64 *context_ptr = context.get(); - -#define AddReg(a) context_ptr->a = static_cast<__typeof__(context_ptr->a)>( \ - REGISTER_FROM_THREADSTATE(machine_state, a)) - - context_ptr->context_flags = MD_CONTEXT_AMD64; - AddReg(rax); - AddReg(rbx); - AddReg(rcx); - AddReg(rdx); - AddReg(rdi); - AddReg(rsi); - AddReg(rbp); - AddReg(rsp); - AddReg(r8); - AddReg(r9); - AddReg(r10); - AddReg(r11); - AddReg(r12); - AddReg(r13); - AddReg(r14); - AddReg(r15); - AddReg(rip); - // according to AMD's software developer guide, bits above 18 are - // not used in the flags register. Since the minidump format - // specifies 32 bits for the flags register, we can truncate safely - // with no loss. - context_ptr->eflags = static_cast(REGISTER_FROM_THREADSTATE(machine_state, rflags)); - AddReg(cs); - AddReg(fs); - AddReg(gs); -#undef AddReg - - return true; -} -#endif - -bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, - thread_state_t state, - mach_msg_type_number_t *count) { - if (task_context_ && target_thread == mach_thread_self()) { - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - size_t final_size = - std::min(static_cast(*count), sizeof(arm_thread_state_t)); - memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size); - *count = static_cast(final_size); - return true; -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: { - size_t final_size = - std::min(static_cast(*count), sizeof(arm_thread_state64_t)); - memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size); - *count = static_cast(final_size); - return true; - } -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - case CPU_TYPE_X86_64: { - size_t state_size = cpu_type_ == CPU_TYPE_I386 ? - sizeof(i386_thread_state_t) : sizeof(x86_thread_state64_t); - size_t final_size = - std::min(static_cast(*count), state_size); - memcpy(state, &task_context_->breakpad_uc_mcontext->__ss, final_size); - *count = static_cast(final_size); - return true; - } -#endif - } - } - - thread_state_flavor_t flavor; - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - flavor = ARM_THREAD_STATE; - break; -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: - flavor = ARM_THREAD_STATE64; - break; -#endif -#ifdef HAS_PPC_SUPPORT - case CPU_TYPE_POWERPC: - flavor = PPC_THREAD_STATE; - break; - case CPU_TYPE_POWERPC64: - flavor = PPC_THREAD_STATE64; - break; -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - flavor = i386_THREAD_STATE; - break; - case CPU_TYPE_X86_64: - flavor = x86_THREAD_STATE64; - break; -#endif - default: - return false; - } - return thread_get_state(target_thread, flavor, - state, count) == KERN_SUCCESS; -} - -bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id, - MDRawThread *thread) { - breakpad_thread_state_data_t state; - mach_msg_type_number_t state_count - = static_cast(sizeof(state)); - - if (GetThreadState(thread_id, state, &state_count)) { - if (!WriteStack(state, &thread->stack)) - return false; - - memory_blocks_.push_back(thread->stack); - - if (!WriteContext(state, &thread->thread_context)) - return false; - - thread->thread_id = thread_id; - } else { - return false; - } - - return true; -} - -bool MinidumpGenerator::WriteThreadListStream( - MDRawDirectory *thread_list_stream) { - TypedMDRVA list(&writer_); - thread_act_port_array_t threads_for_task; - mach_msg_type_number_t thread_count; - int non_generator_thread_count; - - if (task_threads(crashing_task_, &threads_for_task, &thread_count)) - return false; - - // Don't include the generator thread - if (handler_thread_ != MACH_PORT_NULL) - non_generator_thread_count = thread_count - 1; - else - non_generator_thread_count = thread_count; - if (!list.AllocateObjectAndArray(non_generator_thread_count, - sizeof(MDRawThread))) - return false; - - thread_list_stream->stream_type = MD_THREAD_LIST_STREAM; - thread_list_stream->location = list.location(); - - list.get()->number_of_threads = non_generator_thread_count; - - MDRawThread thread; - int thread_idx = 0; - - for (unsigned int i = 0; i < thread_count; ++i) { - memset(&thread, 0, sizeof(MDRawThread)); - - if (threads_for_task[i] != handler_thread_) { - if (!WriteThreadStream(threads_for_task[i], &thread)) - return false; - - list.CopyIndexAfterObject(thread_idx++, &thread, sizeof(MDRawThread)); - } - } - - return true; -} - -bool MinidumpGenerator::WriteMemoryListStream( - MDRawDirectory *memory_list_stream) { - TypedMDRVA list(&writer_); - - // If the dump has an exception, include some memory around the - // instruction pointer. - const size_t kIPMemorySize = 256; // bytes - bool have_ip_memory = false; - MDMemoryDescriptor ip_memory_d; - if (exception_thread_ && exception_type_) { - breakpad_thread_state_data_t state; - mach_msg_type_number_t stateCount - = static_cast(sizeof(state)); - - if (GetThreadState(exception_thread_, state, &stateCount)) { - uint64_t ip = CurrentPCForStack(state); - // Bound it to the upper and lower bounds of the region - // it's contained within. If it's not in a known memory region, - // don't bother trying to write it. - mach_vm_address_t addr = static_cast(ip); - mach_vm_size_t size; - natural_t nesting_level = 0; - vm_region_submap_info_64 info; - mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64; - vm_region_recurse_info_t recurse_info; - recurse_info = reinterpret_cast(&info); - - kern_return_t ret = - mach_vm_region_recurse(crashing_task_, - &addr, - &size, - &nesting_level, - recurse_info, - &info_count); - if (ret == KERN_SUCCESS && ip >= addr && ip < (addr + size)) { - // Try to get 128 bytes before and after the IP, but - // settle for whatever's available. - ip_memory_d.start_of_memory_range = - std::max(uintptr_t(addr), - uintptr_t(ip - (kIPMemorySize / 2))); - uintptr_t end_of_range = - std::min(uintptr_t(ip + (kIPMemorySize / 2)), - uintptr_t(addr + size)); - uintptr_t range_diff = end_of_range - - static_cast(ip_memory_d.start_of_memory_range); - ip_memory_d.memory.data_size = static_cast(range_diff); - have_ip_memory = true; - // This needs to get appended to the list even though - // the memory bytes aren't filled in yet so the entire - // list can be written first. The memory bytes will get filled - // in after the memory list is written. - memory_blocks_.push_back(ip_memory_d); - } - } - } - - // Now fill in the memory list and write it. - size_t memory_count = memory_blocks_.size(); - if (!list.AllocateObjectAndArray(memory_count, - sizeof(MDMemoryDescriptor))) - return false; - - memory_list_stream->stream_type = MD_MEMORY_LIST_STREAM; - memory_list_stream->location = list.location(); - - list.get()->number_of_memory_ranges = static_cast(memory_count); - - unsigned int i; - for (i = 0; i < memory_count; ++i) { - list.CopyIndexAfterObject(i, &memory_blocks_[i], - sizeof(MDMemoryDescriptor)); - } - - if (have_ip_memory) { - // Now read the memory around the instruction pointer. - UntypedMDRVA ip_memory(&writer_); - if (!ip_memory.Allocate(ip_memory_d.memory.data_size)) - return false; - - if (dynamic_images_) { - // Out-of-process. - vector memory; - if (ReadTaskMemory(crashing_task_, - ip_memory_d.start_of_memory_range, - ip_memory_d.memory.data_size, - memory) != KERN_SUCCESS) { - return false; - } - - ip_memory.Copy(&memory[0], ip_memory_d.memory.data_size); - } else { - // In-process, just copy from local memory. - ip_memory.Copy( - reinterpret_cast(ip_memory_d.start_of_memory_range), - ip_memory_d.memory.data_size); - } - - ip_memory_d.memory = ip_memory.location(); - // Write this again now that the data location is filled in. - list.CopyIndexAfterObject(i - 1, &ip_memory_d, - sizeof(MDMemoryDescriptor)); - } - - return true; -} - -bool -MinidumpGenerator::WriteExceptionStream(MDRawDirectory *exception_stream) { - TypedMDRVA exception(&writer_); - - if (!exception.Allocate()) - return false; - - exception_stream->stream_type = MD_EXCEPTION_STREAM; - exception_stream->location = exception.location(); - MDRawExceptionStream *exception_ptr = exception.get(); - exception_ptr->thread_id = exception_thread_; - - // This naming is confusing, but it is the proper translation from - // mach naming to minidump naming. - exception_ptr->exception_record.exception_code = exception_type_; - exception_ptr->exception_record.exception_flags = exception_code_; - - breakpad_thread_state_data_t state; - mach_msg_type_number_t state_count - = static_cast(sizeof(state)); - - if (!GetThreadState(exception_thread_, state, &state_count)) - return false; - - if (!WriteContext(state, &exception_ptr->thread_context)) - return false; - - if (exception_type_ == EXC_BAD_ACCESS) - exception_ptr->exception_record.exception_address = exception_subcode_; - else - exception_ptr->exception_record.exception_address = CurrentPCForStack(state); - - return true; -} - -bool MinidumpGenerator::WriteSystemInfoStream( - MDRawDirectory *system_info_stream) { - TypedMDRVA info(&writer_); - - if (!info.Allocate()) - return false; - - system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM; - system_info_stream->location = info.location(); - - // CPU Information - uint32_t number_of_processors; - size_t len = sizeof(number_of_processors); - sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0); - MDRawSystemInfo *info_ptr = info.get(); - - switch (cpu_type_) { -#ifdef HAS_ARM_SUPPORT - case CPU_TYPE_ARM: - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM; - break; -#endif -#ifdef HAS_ARM64_SUPPORT - case CPU_TYPE_ARM64: - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM64; - break; -#endif -#ifdef HAS_PPC_SUPPORT - case CPU_TYPE_POWERPC: - case CPU_TYPE_POWERPC64: - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC; - break; -#endif -#ifdef HAS_X86_SUPPORT - case CPU_TYPE_I386: - case CPU_TYPE_X86_64: - if (cpu_type_ == CPU_TYPE_I386) - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86; - else - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64; -#ifdef __i386__ - // ebx is used for PIC code, so we need - // to preserve it. -#define cpuid(op,eax,ebx,ecx,edx) \ - asm ("pushl %%ebx \n\t" \ - "cpuid \n\t" \ - "movl %%ebx,%1 \n\t" \ - "popl %%ebx" \ - : "=a" (eax), \ - "=g" (ebx), \ - "=c" (ecx), \ - "=d" (edx) \ - : "0" (op)) -#elif defined(__x86_64__) - -#define cpuid(op,eax,ebx,ecx,edx) \ - asm ("cpuid \n\t" \ - : "=a" (eax), \ - "=b" (ebx), \ - "=c" (ecx), \ - "=d" (edx) \ - : "0" (op)) -#endif - -#if defined(__i386__) || defined(__x86_64__) - int unused, unused2; - // get vendor id - cpuid(0, unused, info_ptr->cpu.x86_cpu_info.vendor_id[0], - info_ptr->cpu.x86_cpu_info.vendor_id[2], - info_ptr->cpu.x86_cpu_info.vendor_id[1]); - // get version and feature info - cpuid(1, info_ptr->cpu.x86_cpu_info.version_information, unused, unused2, - info_ptr->cpu.x86_cpu_info.feature_information); - - // family - info_ptr->processor_level = - (info_ptr->cpu.x86_cpu_info.version_information & 0xF00) >> 8; - // 0xMMSS (Model, Stepping) - info_ptr->processor_revision = static_cast( - (info_ptr->cpu.x86_cpu_info.version_information & 0xF) | - ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0) << 4)); - - // decode extended model info - if (info_ptr->processor_level == 0xF || - info_ptr->processor_level == 0x6) { - info_ptr->processor_revision |= - ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0000) >> 4); - } - - // decode extended family info - if (info_ptr->processor_level == 0xF) { - info_ptr->processor_level += - ((info_ptr->cpu.x86_cpu_info.version_information & 0xFF00000) >> 20); - } - -#endif // __i386__ || __x86_64_ - break; -#endif // HAS_X86_SUPPORT - default: - info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN; - break; - } - - info_ptr->number_of_processors = static_cast(number_of_processors); -#if TARGET_OS_IPHONE - info_ptr->platform_id = MD_OS_IOS; -#else - info_ptr->platform_id = MD_OS_MAC_OS_X; -#endif // TARGET_OS_IPHONE - - MDLocationDescriptor build_string_loc; - - if (!writer_.WriteString(build_string_, 0, - &build_string_loc)) - return false; - - info_ptr->csd_version_rva = build_string_loc.rva; - info_ptr->major_version = os_major_version_; - info_ptr->minor_version = os_minor_version_; - info_ptr->build_number = os_build_number_; - - return true; -} - -bool MinidumpGenerator::WriteModuleStream(unsigned int index, - MDRawModule *module) { - if (dynamic_images_) { - // we're in a different process than the crashed process - DynamicImage *image = dynamic_images_->GetImage(index); - - if (!image) - return false; - - memset(module, 0, sizeof(MDRawModule)); - - MDLocationDescriptor string_location; - - string name = image->GetFilePath(); - if (!writer_.WriteString(name.c_str(), 0, &string_location)) - return false; - - module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide(); - module->size_of_image = static_cast(image->GetVMSize()); - module->module_name_rva = string_location.rva; - - // We'll skip the executable module, because they don't have - // LC_ID_DYLIB load commands, and the crash processing server gets - // version information from the Plist file, anyway. - if (index != static_cast(FindExecutableModule())) { - module->version_info.signature = MD_VSFIXEDFILEINFO_SIGNATURE; - module->version_info.struct_version |= MD_VSFIXEDFILEINFO_VERSION; - // Convert MAC dylib version format, which is a 32 bit number, to the - // format used by minidump. The mac format is <16 bits>.<8 bits>.<8 bits> - // so it fits nicely into the windows version with some massaging - // The mapping is: - // 1) upper 16 bits of MAC version go to lower 16 bits of product HI - // 2) Next most significant 8 bits go to upper 16 bits of product LO - // 3) Least significant 8 bits go to lower 16 bits of product LO - uint32_t modVersion = image->GetVersion(); - module->version_info.file_version_hi = 0; - module->version_info.file_version_hi = modVersion >> 16; - module->version_info.file_version_lo |= (modVersion & 0xff00) << 8; - module->version_info.file_version_lo |= (modVersion & 0xff); - } - - if (!WriteCVRecord(module, image->GetCPUType(), name.c_str(), false)) { - return false; - } - } else { - // Getting module info in the crashed process - const breakpad_mach_header *header; - header = (breakpad_mach_header*)_dyld_get_image_header(index); - if (!header) - return false; - -#ifdef __LP64__ - assert(header->magic == MH_MAGIC_64); - - if(header->magic != MH_MAGIC_64) - return false; -#else - assert(header->magic == MH_MAGIC); - - if(header->magic != MH_MAGIC) - return false; -#endif - - int cpu_type = header->cputype; - unsigned long slide = _dyld_get_image_vmaddr_slide(index); - const char* name = _dyld_get_image_name(index); - const struct load_command *cmd = - reinterpret_cast(header + 1); - - memset(module, 0, sizeof(MDRawModule)); - - for (unsigned int i = 0; cmd && (i < header->ncmds); i++) { - if (cmd->cmd == LC_SEGMENT_ARCH) { - - const breakpad_mach_segment_command *seg = - reinterpret_cast(cmd); - - if (!strcmp(seg->segname, "__TEXT")) { - MDLocationDescriptor string_location; - - if (!writer_.WriteString(name, 0, &string_location)) - return false; - - module->base_of_image = seg->vmaddr + slide; - module->size_of_image = static_cast(seg->vmsize); - module->module_name_rva = string_location.rva; - - bool in_memory = false; -#if TARGET_OS_IPHONE - in_memory = true; -#endif - if (!WriteCVRecord(module, cpu_type, name, in_memory)) - return false; - - return true; - } - } - - cmd = reinterpret_cast((char *)cmd + cmd->cmdsize); - } - } - - return true; -} - -int MinidumpGenerator::FindExecutableModule() { - if (dynamic_images_) { - int index = dynamic_images_->GetExecutableImageIndex(); - - if (index >= 0) { - return index; - } - } else { - int image_count = _dyld_image_count(); - const struct mach_header *header; - - for (int index = 0; index < image_count; ++index) { - header = _dyld_get_image_header(index); - - if (header->filetype == MH_EXECUTE) - return index; - } - } - - // failed - just use the first image - return 0; -} - -bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type, - const char *module_path, bool in_memory) { - TypedMDRVA cv(&writer_); - - // Only return the last path component of the full module path - const char *module_name = strrchr(module_path, '/'); - - // Increment past the slash - if (module_name) - ++module_name; - else - module_name = ""; - - size_t module_name_length = strlen(module_name); - - if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t))) - return false; - - if (!cv.CopyIndexAfterObject(0, module_name, module_name_length)) - return false; - - module->cv_record = cv.location(); - MDCVInfoPDB70 *cv_ptr = cv.get(); - cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE; - cv_ptr->age = 0; - - // Get the module identifier - unsigned char identifier[16]; - bool result = false; - if (in_memory) { - MacFileUtilities::MachoID macho(module_path, - reinterpret_cast(module->base_of_image), - static_cast(module->size_of_image)); - result = macho.UUIDCommand(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier); - if (!result) - result = macho.MD5(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier); - } - - if (!result) { - FileID file_id(module_path); - result = file_id.MachoIdentifier(cpu_type, CPU_SUBTYPE_MULTIPLE, - identifier); - } - - if (result) { - cv_ptr->signature.data1 = - static_cast(identifier[0]) << 24 | - static_cast(identifier[1]) << 16 | - static_cast(identifier[2]) << 8 | - static_cast(identifier[3]); - cv_ptr->signature.data2 = - static_cast(identifier[4] << 8) | identifier[5]; - cv_ptr->signature.data3 = - static_cast(identifier[6] << 8) | identifier[7]; - cv_ptr->signature.data4[0] = identifier[8]; - cv_ptr->signature.data4[1] = identifier[9]; - cv_ptr->signature.data4[2] = identifier[10]; - cv_ptr->signature.data4[3] = identifier[11]; - cv_ptr->signature.data4[4] = identifier[12]; - cv_ptr->signature.data4[5] = identifier[13]; - cv_ptr->signature.data4[6] = identifier[14]; - cv_ptr->signature.data4[7] = identifier[15]; - } - - return true; -} - -bool MinidumpGenerator::WriteModuleListStream( - MDRawDirectory *module_list_stream) { - TypedMDRVA list(&writer_); - - uint32_t image_count = dynamic_images_ ? - dynamic_images_->GetImageCount() : - _dyld_image_count(); - - if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE)) - return false; - - module_list_stream->stream_type = MD_MODULE_LIST_STREAM; - module_list_stream->location = list.location(); - list.get()->number_of_modules = static_cast(image_count); - - // Write out the executable module as the first one - MDRawModule module; - uint32_t executableIndex = FindExecutableModule(); - - if (!WriteModuleStream(static_cast(executableIndex), &module)) { - return false; - } - - list.CopyIndexAfterObject(0, &module, MD_MODULE_SIZE); - int destinationIndex = 1; // Write all other modules after this one - - for (uint32_t i = 0; i < image_count; ++i) { - if (i != executableIndex) { - if (!WriteModuleStream(static_cast(i), &module)) { - return false; - } - - list.CopyIndexAfterObject(destinationIndex++, &module, MD_MODULE_SIZE); - } - } - - return true; -} - -bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory *misc_info_stream) { - TypedMDRVA info(&writer_); - - if (!info.Allocate()) - return false; - - misc_info_stream->stream_type = MD_MISC_INFO_STREAM; - misc_info_stream->location = info.location(); - - MDRawMiscInfo *info_ptr = info.get(); - info_ptr->size_of_info = static_cast(sizeof(MDRawMiscInfo)); - info_ptr->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID | - MD_MISCINFO_FLAGS1_PROCESS_TIMES | - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO; - - // Process ID - info_ptr->process_id = getpid(); - - // Times - struct rusage usage; - if (getrusage(RUSAGE_SELF, &usage) != -1) { - // Omit the fractional time since the MDRawMiscInfo only wants seconds - info_ptr->process_user_time = - static_cast(usage.ru_utime.tv_sec); - info_ptr->process_kernel_time = - static_cast(usage.ru_stime.tv_sec); - } - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, - static_cast(info_ptr->process_id) }; - uint mibsize = static_cast(sizeof(mib) / sizeof(mib[0])); - struct kinfo_proc proc; - size_t size = sizeof(proc); - if (sysctl(mib, mibsize, &proc, &size, NULL, 0) == 0) { - info_ptr->process_create_time = - static_cast(proc.kp_proc.p_starttime.tv_sec); - } - - // Speed - uint64_t speed; - const uint64_t kOneMillion = 1000 * 1000; - size = sizeof(speed); - sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0); - info_ptr->processor_max_mhz = static_cast(speed / kOneMillion); - info_ptr->processor_mhz_limit = static_cast(speed / kOneMillion); - size = sizeof(speed); - sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0); - info_ptr->processor_current_mhz = static_cast(speed / kOneMillion); - - return true; -} - -bool MinidumpGenerator::WriteBreakpadInfoStream( - MDRawDirectory *breakpad_info_stream) { - TypedMDRVA info(&writer_); - - if (!info.Allocate()) - return false; - - breakpad_info_stream->stream_type = MD_BREAKPAD_INFO_STREAM; - breakpad_info_stream->location = info.location(); - MDRawBreakpadInfo *info_ptr = info.get(); - - if (exception_thread_ && exception_type_) { - info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; - info_ptr->dump_thread_id = handler_thread_; - info_ptr->requesting_thread_id = exception_thread_; - } else { - info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID; - info_ptr->dump_thread_id = handler_thread_; - info_ptr->requesting_thread_id = 0; - } - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h deleted file mode 100644 index 4e4b4a684..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_generator.h: Create a minidump of the current MacOS process. - -#ifndef CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__ -#define CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__ - -#include -#include - -#include - -#include "client/mac/handler/ucontext_compat.h" -#include "client/minidump_file_writer.h" -#include "common/memory.h" -#include "common/mac/macho_utilities.h" -#include "google_breakpad/common/minidump_format.h" - -#include "dynamic_images.h" -#include "mach_vm_compat.h" - -#if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) - #define HAS_PPC_SUPPORT -#endif -#if defined(__arm__) -#define HAS_ARM_SUPPORT -#elif defined(__aarch64__) -#define HAS_ARM64_SUPPORT -#elif defined(__i386__) || defined(__x86_64__) - #define HAS_X86_SUPPORT -#endif - -namespace google_breakpad { - -using std::string; - -// Use the REGISTER_FROM_THREADSTATE to access a register name from the -// breakpad_thread_state_t structure. -#if __DARWIN_UNIX03 || TARGET_CPU_X86_64 || TARGET_CPU_PPC64 || TARGET_CPU_ARM -// In The 10.5 SDK Headers Apple prepended __ to the variable names in the -// i386_thread_state_t structure. There's no good way to tell what version of -// the SDK we're compiling against so we just toggle on the same preprocessor -// symbol Apple's headers use. -#define REGISTER_FROM_THREADSTATE(a, b) ((a)->__ ## b) -#else -#define REGISTER_FROM_THREADSTATE(a, b) (a->b) -#endif - -// Creates a minidump file of the current process. If there is exception data, -// use SetExceptionInformation() to add this to the minidump. The minidump -// file is generated by the Write() function. -// Usage: -// MinidumpGenerator minidump(); -// minidump.Write("/tmp/minidump"); -// -class MinidumpGenerator { - public: - MinidumpGenerator(); - MinidumpGenerator(mach_port_t crashing_task, mach_port_t handler_thread); - - virtual ~MinidumpGenerator(); - - // Return /.dmp - // Sets |unique_name| (if requested) to the unique name for the minidump - static string UniqueNameInDirectory(const string &dir, string *unique_name); - - // Write out the minidump into |path| - // All of the components of |path| must exist and be writable - // Return true if successful, false otherwise - bool Write(const char *path); - - // Specify some exception information, if applicable - void SetExceptionInformation(int type, int code, int subcode, - mach_port_t thread_name) { - exception_type_ = type; - exception_code_ = code; - exception_subcode_ = subcode; - exception_thread_ = thread_name; - } - - // Specify the task context. If |task_context| is not NULL, it will be used - // to retrieve the context of the current thread, instead of using - // |thread_get_state|. - void SetTaskContext(breakpad_ucontext_t *task_context); - - // Gather system information. This should be call at least once before using - // the MinidumpGenerator class. - static void GatherSystemInformation(); - - protected: - // Overridable Stream writers - virtual bool WriteExceptionStream(MDRawDirectory *exception_stream); - - // Overridable Helper - virtual bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread); - - private: - typedef bool (MinidumpGenerator::*WriteStreamFN)(MDRawDirectory *); - - // Stream writers - bool WriteThreadListStream(MDRawDirectory *thread_list_stream); - bool WriteMemoryListStream(MDRawDirectory *memory_list_stream); - bool WriteSystemInfoStream(MDRawDirectory *system_info_stream); - bool WriteModuleListStream(MDRawDirectory *module_list_stream); - bool WriteMiscInfoStream(MDRawDirectory *misc_info_stream); - bool WriteBreakpadInfoStream(MDRawDirectory *breakpad_info_stream); - - // Helpers - uint64_t CurrentPCForStack(breakpad_thread_state_data_t state); - bool GetThreadState(thread_act_t target_thread, thread_state_t state, - mach_msg_type_number_t *count); - bool WriteStackFromStartAddress(mach_vm_address_t start_addr, - MDMemoryDescriptor *stack_location); - bool WriteStack(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContext(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - bool WriteCVRecord(MDRawModule *module, int cpu_type, - const char *module_path, bool in_memory); - bool WriteModuleStream(unsigned int index, MDRawModule *module); - size_t CalculateStackSize(mach_vm_address_t start_addr); - int FindExecutableModule(); - - // Per-CPU implementations of these methods -#ifdef HAS_ARM_SUPPORT - bool WriteStackARM(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextARM(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackARM(breakpad_thread_state_data_t state); -#endif -#ifdef HAS_ARM64_SUPPORT - bool WriteStackARM64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextARM64(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackARM64(breakpad_thread_state_data_t state); -#endif -#ifdef HAS_PPC_SUPPORT - bool WriteStackPPC(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextPPC(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackPPC(breakpad_thread_state_data_t state); - bool WriteStackPPC64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextPPC64(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state); -#endif -#ifdef HAS_X86_SUPPORT - bool WriteStackX86(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextX86(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackX86(breakpad_thread_state_data_t state); - bool WriteStackX86_64(breakpad_thread_state_data_t state, - MDMemoryDescriptor *stack_location); - bool WriteContextX86_64(breakpad_thread_state_data_t state, - MDLocationDescriptor *register_location); - uint64_t CurrentPCForStackX86_64(breakpad_thread_state_data_t state); -#endif - - // disallow copy ctor and operator= - explicit MinidumpGenerator(const MinidumpGenerator &); - void operator=(const MinidumpGenerator &); - - protected: - // Use this writer to put the data to disk - MinidumpFileWriter writer_; - - private: - // Exception information - int exception_type_; - int exception_code_; - int exception_subcode_; - mach_port_t exception_thread_; - mach_port_t crashing_task_; - mach_port_t handler_thread_; - - // CPU type of the task being dumped. - cpu_type_t cpu_type_; - - // System information - static char build_string_[16]; - static int os_major_version_; - static int os_minor_version_; - static int os_build_number_; - - // Context of the task to dump. - breakpad_ucontext_t *task_context_; - - // Information about dynamically loaded code - DynamicImages *dynamic_images_; - - // PageAllocator makes it possible to allocate memory - // directly from the system, even while handling an exception. - mutable PageAllocator allocator_; - - protected: - // Blocks of memory written to the dump. These are all currently - // written while writing the thread list stream, but saved here - // so a memory list stream can be written afterwards. - wasteful_vector memory_blocks_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_MAC_GENERATOR_MINIDUMP_GENERATOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj deleted file mode 100644 index 2a597d502..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj +++ /dev/null @@ -1,841 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 8BFC813F11FF9A58002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814411FF9A9C002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814511FF9A9D002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814811FF9B13002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814911FF9B13002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814A11FF9B13002CB4DC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */; }; - 8BFC814B11FF9B3F002CB4DC /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9721FA10E8B0E2300D7E813 /* SenTestingKit.framework */; }; - 8BFC814C11FF9B3F002CB4DC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9721F6B0E8B0D7000D7E813 /* Cocoa.framework */; }; - 8BFC81A211FF9C2E002CB4DC /* CPlusTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC819211FF9C23002CB4DC /* CPlusTest.framework */; }; - 8BFC81A311FF9C2F002CB4DC /* CPlusTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BFC819211FF9C23002CB4DC /* CPlusTest.framework */; }; - 8BFC81AD11FF9C8A002CB4DC /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */; }; - 8BFC81AE11FF9C8C002CB4DC /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */; }; - 8BFC81AF11FF9C8C002CB4DC /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */; }; - 8BFC81B011FF9C8D002CB4DC /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */; }; - 9B35FF5A0B267D5F008DE8C7 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF560B267D5F008DE8C7 /* convert_UTF.c */; }; - 9B35FF5B0B267D5F008DE8C7 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF580B267D5F008DE8C7 /* string_conversion.cc */; }; - 9B37CEEC0AF98ECD00FA4BD4 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B37CEEB0AF98ECD00FA4BD4 /* CoreFoundation.framework */; }; - 9B7CA7700B12873A00CD3A1D /* minidump_file_writer-inl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BE3C01E0B0CE329009892DF /* minidump_file_writer-inl.h */; }; - 9B7CA8540B12989000CD3A1D /* minidump_file_writer_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B7CA8530B12989000CD3A1D /* minidump_file_writer_unittest.cc */; }; - 9B7CA8550B1298A100CD3A1D /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C230B01344C0055103E /* minidump_file_writer.cc */; }; - 9BC1D2940B336F2300F2A2B4 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF560B267D5F008DE8C7 /* convert_UTF.c */; }; - 9BC1D2950B336F2500F2A2B4 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF580B267D5F008DE8C7 /* string_conversion.cc */; }; - 9BD82AC10B0029DF0055103E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B37CEEB0AF98ECD00FA4BD4 /* CoreFoundation.framework */; }; - 9BD82BFF0B01333D0055103E /* exception_handler_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82BFD0B01333D0055103E /* exception_handler_test.cc */; }; - 9BD82C020B01333D0055103E /* minidump_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82BFE0B01333D0055103E /* minidump_generator_test.cc */; }; - 9BD82C0D0B0133520055103E /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C090B0133520055103E /* exception_handler.cc */; }; - 9BD82C0E0B0133520055103E /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C0B0B0133520055103E /* minidump_generator.cc */; }; - 9BD82C0F0B0133520055103E /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C090B0133520055103E /* exception_handler.cc */; }; - 9BD82C100B0133520055103E /* exception_handler.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD82C0A0B0133520055103E /* exception_handler.h */; }; - 9BD82C110B0133520055103E /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C0B0B0133520055103E /* minidump_generator.cc */; }; - 9BD82C120B0133520055103E /* minidump_generator.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD82C0C0B0133520055103E /* minidump_generator.h */; }; - 9BD82C250B01344C0055103E /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C230B01344C0055103E /* minidump_file_writer.cc */; }; - 9BD82C260B01344C0055103E /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C230B01344C0055103E /* minidump_file_writer.cc */; }; - 9BD82C270B01344C0055103E /* minidump_file_writer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD82C240B01344C0055103E /* minidump_file_writer.h */; }; - 9BD82C2D0B01345E0055103E /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C2B0B01345E0055103E /* string_utilities.cc */; }; - 9BD82C2E0B01345E0055103E /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BD82C2B0B01345E0055103E /* string_utilities.cc */; }; - 9BD82C2F0B01345E0055103E /* string_utilities.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD82C2C0B01345E0055103E /* string_utilities.h */; }; - D2F651000BEF947200920385 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FA0BEF947200920385 /* file_id.cc */; }; - D2F651010BEF947200920385 /* file_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D2F650FB0BEF947200920385 /* file_id.h */; }; - D2F651020BEF947200920385 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FC0BEF947200920385 /* macho_id.cc */; }; - D2F651030BEF947200920385 /* macho_id.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D2F650FD0BEF947200920385 /* macho_id.h */; }; - D2F651040BEF947200920385 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FE0BEF947200920385 /* macho_utilities.cc */; }; - D2F651050BEF947200920385 /* macho_utilities.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D2F650FF0BEF947200920385 /* macho_utilities.h */; }; - D2F651090BEF949A00920385 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F651070BEF949A00920385 /* dynamic_images.cc */; }; - D2F6510A0BEF949A00920385 /* dynamic_images.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D2F651080BEF949A00920385 /* dynamic_images.h */; }; - D2F6510E0BEF94EB00920385 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F6510C0BEF94EB00920385 /* macho_walker.cc */; }; - D2F6510F0BEF94EB00920385 /* macho_walker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D2F6510D0BEF94EB00920385 /* macho_walker.h */; }; - D2F651110BEF951700920385 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF580B267D5F008DE8C7 /* string_conversion.cc */; }; - D2F651130BEF951C00920385 /* string_conversion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FF590B267D5F008DE8C7 /* string_conversion.h */; }; - D2F651150BEF953000920385 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FF560B267D5F008DE8C7 /* convert_UTF.c */; }; - D2F651160BEF953100920385 /* convert_UTF.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B35FF570B267D5F008DE8C7 /* convert_UTF.h */; }; - D2F6511B0BEF970E00920385 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F651070BEF949A00920385 /* dynamic_images.cc */; }; - D2F6511D0BEF973500920385 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FA0BEF947200920385 /* file_id.cc */; }; - D2F6511E0BEF973600920385 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FC0BEF947200920385 /* macho_id.cc */; }; - D2F6511F0BEF973900920385 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FE0BEF947200920385 /* macho_utilities.cc */; }; - D2F651210BEF975400920385 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F6510C0BEF94EB00920385 /* macho_walker.cc */; }; - F93A887D0E8B4C8C0026AF89 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F6510C0BEF94EB00920385 /* macho_walker.cc */; }; - F93A887E0E8B4C8C0026AF89 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FC0BEF947200920385 /* macho_id.cc */; }; - F93A887F0E8B4C8C0026AF89 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FE0BEF947200920385 /* macho_utilities.cc */; }; - F93A88800E8B4C8C0026AF89 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F650FA0BEF947200920385 /* file_id.cc */; }; - F93A88860E8B4C9A0026AF89 /* dwarftests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9721F310E8B07E800D7E813 /* dwarftests.mm */; }; - F93A88870E8B4C9A0026AF89 /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9721F390E8B0D0D00D7E813 /* dump_syms.mm */; }; - F93A88880E8B4C9A0026AF89 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9721F760E8B0DC700D7E813 /* bytereader.cc */; }; - F93A88890E8B4C9A0026AF89 /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9721F770E8B0DC700D7E813 /* dwarf2reader.cc */; }; - F93A888A0E8B4C9A0026AF89 /* functioninfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9721F780E8B0DC700D7E813 /* functioninfo.cc */; }; - F93A888B0E8B4C9A0026AF89 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9721FA80E8B0E4800D7E813 /* md5.cc */; }; - F9721F6C0E8B0D7000D7E813 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9721F6B0E8B0D7000D7E813 /* Cocoa.framework */; }; - F9721FA20E8B0E2300D7E813 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9721FA10E8B0E2300D7E813 /* SenTestingKit.framework */; }; - F982089C0DB3280D0017AECA /* breakpad_nlist_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F982089B0DB3280D0017AECA /* breakpad_nlist_test.cc */; }; - F98208A30DB32CAE0017AECA /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */; }; - F9AE5B390DBFDBDB00505983 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F651070BEF949A00920385 /* dynamic_images.cc */; }; - F9AE5B3A0DBFDBDB00505983 /* DynamicImagesTests.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C5A4210DB82DD800209C76 /* DynamicImagesTests.cc */; }; - F9B34E870DBC1E1600306484 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F651070BEF949A00920385 /* dynamic_images.cc */; }; - F9C5A4220DB82DD800209C76 /* DynamicImagesTests.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C5A4210DB82DD800209C76 /* DynamicImagesTests.cc */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 8DD76F690486A84900D96B5E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - 9BD82C100B0133520055103E /* exception_handler.h in CopyFiles */, - 9BD82C120B0133520055103E /* minidump_generator.h in CopyFiles */, - 9BD82C270B01344C0055103E /* minidump_file_writer.h in CopyFiles */, - 9BD82C2F0B01345E0055103E /* string_utilities.h in CopyFiles */, - 9B7CA7700B12873A00CD3A1D /* minidump_file_writer-inl.h in CopyFiles */, - D2F651010BEF947200920385 /* file_id.h in CopyFiles */, - D2F651030BEF947200920385 /* macho_id.h in CopyFiles */, - D2F651050BEF947200920385 /* macho_utilities.h in CopyFiles */, - D2F6510A0BEF949A00920385 /* dynamic_images.h in CopyFiles */, - D2F6510F0BEF94EB00920385 /* macho_walker.h in CopyFiles */, - D2F651130BEF951C00920385 /* string_conversion.h in CopyFiles */, - D2F651160BEF953100920385 /* convert_UTF.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 8BFC812011FF99D5002CB4DC /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; - 8BFC812111FF99D5002CB4DC /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; - 8BFC812211FF99D5002CB4DC /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; - 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; - 8BFC815411FF9B7F002CB4DC /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; - 8BFC819211FF9C23002CB4DC /* CPlusTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CPlusTest.framework; path = Library/Frameworks/CPlusTest.framework; sourceTree = DEVELOPER_DIR; }; - 8DD76F6C0486A84900D96B5E /* generator_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = generator_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 9B35FF560B267D5F008DE8C7 /* convert_UTF.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = convert_UTF.c; path = ../../../common/convert_UTF.c; sourceTree = SOURCE_ROOT; }; - 9B35FF570B267D5F008DE8C7 /* convert_UTF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = convert_UTF.h; path = ../../../common/convert_UTF.h; sourceTree = SOURCE_ROOT; }; - 9B35FF580B267D5F008DE8C7 /* string_conversion.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = string_conversion.cc; path = ../../../common/string_conversion.cc; sourceTree = SOURCE_ROOT; }; - 9B35FF590B267D5F008DE8C7 /* string_conversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = string_conversion.h; path = ../../../common/string_conversion.h; sourceTree = SOURCE_ROOT; }; - 9B37CEEB0AF98ECD00FA4BD4 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 9B7CA84E0B1297F200CD3A1D /* unit_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = unit_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 9B7CA8530B12989000CD3A1D /* minidump_file_writer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_file_writer_unittest.cc; path = ../../minidump_file_writer_unittest.cc; sourceTree = ""; }; - 9BD82A9B0B00267E0055103E /* handler_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = handler_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 9BD82BFD0B01333D0055103E /* exception_handler_test.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = exception_handler_test.cc; sourceTree = SOURCE_ROOT; }; - 9BD82BFE0B01333D0055103E /* minidump_generator_test.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = minidump_generator_test.cc; sourceTree = SOURCE_ROOT; }; - 9BD82C090B0133520055103E /* exception_handler.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = exception_handler.cc; sourceTree = SOURCE_ROOT; }; - 9BD82C0A0B0133520055103E /* exception_handler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = exception_handler.h; sourceTree = SOURCE_ROOT; }; - 9BD82C0B0B0133520055103E /* minidump_generator.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = minidump_generator.cc; sourceTree = SOURCE_ROOT; }; - 9BD82C0C0B0133520055103E /* minidump_generator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_generator.h; sourceTree = SOURCE_ROOT; }; - 9BD82C230B01344C0055103E /* minidump_file_writer.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_file_writer.cc; path = ../../minidump_file_writer.cc; sourceTree = SOURCE_ROOT; }; - 9BD82C240B01344C0055103E /* minidump_file_writer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = minidump_file_writer.h; path = ../../minidump_file_writer.h; sourceTree = SOURCE_ROOT; }; - 9BD82C2B0B01345E0055103E /* string_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = string_utilities.cc; path = ../../../common/mac/string_utilities.cc; sourceTree = SOURCE_ROOT; }; - 9BD82C2C0B01345E0055103E /* string_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = string_utilities.h; path = ../../../common/mac/string_utilities.h; sourceTree = SOURCE_ROOT; }; - 9BE3C01E0B0CE329009892DF /* minidump_file_writer-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "minidump_file_writer-inl.h"; path = "../../minidump_file_writer-inl.h"; sourceTree = SOURCE_ROOT; }; - D2F650FA0BEF947200920385 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; }; - D2F650FB0BEF947200920385 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; }; - D2F650FC0BEF947200920385 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; }; - D2F650FD0BEF947200920385 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; - D2F650FE0BEF947200920385 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; }; - D2F650FF0BEF947200920385 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; }; - D2F651070BEF949A00920385 /* dynamic_images.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dynamic_images.cc; sourceTree = ""; }; - D2F651080BEF949A00920385 /* dynamic_images.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dynamic_images.h; sourceTree = ""; }; - D2F6510C0BEF94EB00920385 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; - D2F6510D0BEF94EB00920385 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; - F917C4F70E03265A00F86017 /* breakpad_exc_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = breakpad_exc_server.c; sourceTree = ""; }; - F917C4F80E03265A00F86017 /* breakpad_exc_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = breakpad_exc_server.h; sourceTree = ""; }; - F93A88750E8B4C700026AF89 /* octestcases.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = octestcases.octest; sourceTree = BUILT_PRODUCTS_DIR; }; - F93A88760E8B4C700026AF89 /* obj-cTestCases-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "obj-cTestCases-Info.plist"; sourceTree = ""; }; - F9721F300E8B07E800D7E813 /* dwarftests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dwarftests.h; sourceTree = ""; }; - F9721F310E8B07E800D7E813 /* dwarftests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dwarftests.mm; sourceTree = ""; }; - F9721F380E8B0CFC00D7E813 /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; }; - F9721F390E8B0D0D00D7E813 /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = SOURCE_ROOT; }; - F9721F6B0E8B0D7000D7E813 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - F9721F760E8B0DC700D7E813 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; - F9721F770E8B0DC700D7E813 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; - F9721F780E8B0DC700D7E813 /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; }; - F9721FA10E8B0E2300D7E813 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; - F9721FA80E8B0E4800D7E813 /* md5.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; }; - F982089A0DB3280D0017AECA /* breakpad_nlist_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = breakpad_nlist_test.h; sourceTree = ""; }; - F982089B0DB3280D0017AECA /* breakpad_nlist_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = breakpad_nlist_test.cc; sourceTree = ""; }; - F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = breakpad_nlist_64.cc; sourceTree = ""; }; - F98208A20DB32CAE0017AECA /* breakpad_nlist_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = breakpad_nlist_64.h; sourceTree = ""; }; - F9AE19B50DB040E300C98454 /* minidump_tests32-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "minidump_tests32-Info.plist"; sourceTree = ""; }; - F9AE19C30DB04A9500C98454 /* minidump_tests64.cptest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = minidump_tests64.cptest; sourceTree = BUILT_PRODUCTS_DIR; }; - F9AE5B330DBFDBA300505983 /* minidump_tests32.cptest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = minidump_tests32.cptest; sourceTree = BUILT_PRODUCTS_DIR; }; - F9AE5B340DBFDBA300505983 /* minidump_tests64-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "minidump_tests64-Info.plist"; sourceTree = ""; }; - F9C5A4200DB82DD800209C76 /* DynamicImagesTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicImagesTests.h; sourceTree = ""; }; - F9C5A4210DB82DD800209C76 /* DynamicImagesTests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicImagesTests.cc; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DD76F660486A84900D96B5E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9B37CEEC0AF98ECD00FA4BD4 /* CoreFoundation.framework in Frameworks */, - 8BFC813F11FF9A58002CB4DC /* libcrypto.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9B7CA84C0B1297F200CD3A1D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8BFC814511FF9A9D002CB4DC /* libcrypto.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9BD82A990B00267E0055103E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9BD82AC10B0029DF0055103E /* CoreFoundation.framework in Frameworks */, - 8BFC814411FF9A9C002CB4DC /* libcrypto.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93A88720E8B4C700026AF89 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8BFC814A11FF9B13002CB4DC /* libcrypto.dylib in Frameworks */, - 8BFC814B11FF9B3F002CB4DC /* SenTestingKit.framework in Frameworks */, - 8BFC814C11FF9B3F002CB4DC /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE19C00DB04A9500C98454 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8BFC814811FF9B13002CB4DC /* libcrypto.dylib in Frameworks */, - 8BFC81A211FF9C2E002CB4DC /* CPlusTest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE5B300DBFDBA300505983 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F9721F6C0E8B0D7000D7E813 /* Cocoa.framework in Frameworks */, - F9721FA20E8B0E2300D7E813 /* SenTestingKit.framework in Frameworks */, - 8BFC814911FF9B13002CB4DC /* libcrypto.dylib in Frameworks */, - 8BFC81A311FF9C2F002CB4DC /* CPlusTest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* MinidumpWriter */ = { - isa = PBXGroup; - children = ( - 8BFC812011FF99D5002CB4DC /* Breakpad.xcconfig */, - 8BFC812111FF99D5002CB4DC /* BreakpadDebug.xcconfig */, - 8BFC812211FF99D5002CB4DC /* BreakpadRelease.xcconfig */, - F9721FA80E8B0E4800D7E813 /* md5.cc */, - F9721F760E8B0DC700D7E813 /* bytereader.cc */, - F9721F770E8B0DC700D7E813 /* dwarf2reader.cc */, - F9721F780E8B0DC700D7E813 /* functioninfo.cc */, - F9721F390E8B0D0D00D7E813 /* dump_syms.mm */, - F9721F380E8B0CFC00D7E813 /* dump_syms.h */, - F917C4F70E03265A00F86017 /* breakpad_exc_server.c */, - F917C4F80E03265A00F86017 /* breakpad_exc_server.h */, - F98208A10DB32CAE0017AECA /* breakpad_nlist_64.cc */, - F98208A20DB32CAE0017AECA /* breakpad_nlist_64.h */, - D2F6510C0BEF94EB00920385 /* macho_walker.cc */, - D2F6510D0BEF94EB00920385 /* macho_walker.h */, - D2F651070BEF949A00920385 /* dynamic_images.cc */, - D2F651080BEF949A00920385 /* dynamic_images.h */, - D2F650FA0BEF947200920385 /* file_id.cc */, - D2F650FB0BEF947200920385 /* file_id.h */, - D2F650FC0BEF947200920385 /* macho_id.cc */, - D2F650FD0BEF947200920385 /* macho_id.h */, - D2F650FE0BEF947200920385 /* macho_utilities.cc */, - D2F650FF0BEF947200920385 /* macho_utilities.h */, - F9C5A41F0DB82DB000209C76 /* testcases */, - 9BD82C040B0133420055103E /* Breakpad */, - 08FB7795FE84155DC02AAC07 /* Source */, - 9B37CEEA0AF98EB600FA4BD4 /* Frameworks */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - F9AE19B50DB040E300C98454 /* minidump_tests32-Info.plist */, - F9AE5B340DBFDBA300505983 /* minidump_tests64-Info.plist */, - F93A88760E8B4C700026AF89 /* obj-cTestCases-Info.plist */, - ); - name = MinidumpWriter; - sourceTree = ""; - }; - 08FB7795FE84155DC02AAC07 /* Source */ = { - isa = PBXGroup; - children = ( - 9BD82BFD0B01333D0055103E /* exception_handler_test.cc */, - 9BD82BFE0B01333D0055103E /* minidump_generator_test.cc */, - 9B7CA8530B12989000CD3A1D /* minidump_file_writer_unittest.cc */, - ); - name = Source; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8DD76F6C0486A84900D96B5E /* generator_test */, - 9BD82A9B0B00267E0055103E /* handler_test */, - 9B7CA84E0B1297F200CD3A1D /* unit_test */, - F9AE19C30DB04A9500C98454 /* minidump_tests64.cptest */, - F9AE5B330DBFDBA300505983 /* minidump_tests32.cptest */, - F93A88750E8B4C700026AF89 /* octestcases.octest */, - ); - name = Products; - sourceTree = ""; - }; - 9B37CEEA0AF98EB600FA4BD4 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8BFC813E11FF9A58002CB4DC /* libcrypto.dylib */, - 8BFC815411FF9B7F002CB4DC /* Carbon.framework */, - F9721FA10E8B0E2300D7E813 /* SenTestingKit.framework */, - F9721F6B0E8B0D7000D7E813 /* Cocoa.framework */, - 9B37CEEB0AF98ECD00FA4BD4 /* CoreFoundation.framework */, - 8BFC819211FF9C23002CB4DC /* CPlusTest.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9BD82C040B0133420055103E /* Breakpad */ = { - isa = PBXGroup; - children = ( - 9B35FF560B267D5F008DE8C7 /* convert_UTF.c */, - 9B35FF570B267D5F008DE8C7 /* convert_UTF.h */, - 9B35FF580B267D5F008DE8C7 /* string_conversion.cc */, - 9B35FF590B267D5F008DE8C7 /* string_conversion.h */, - 9BD82C090B0133520055103E /* exception_handler.cc */, - 9BD82C0A0B0133520055103E /* exception_handler.h */, - 9BD82C0B0B0133520055103E /* minidump_generator.cc */, - 9BD82C0C0B0133520055103E /* minidump_generator.h */, - 9BD82C230B01344C0055103E /* minidump_file_writer.cc */, - 9BE3C01E0B0CE329009892DF /* minidump_file_writer-inl.h */, - 9BD82C240B01344C0055103E /* minidump_file_writer.h */, - 9BD82C2B0B01345E0055103E /* string_utilities.cc */, - 9BD82C2C0B01345E0055103E /* string_utilities.h */, - ); - name = Breakpad; - sourceTree = ""; - }; - F9C5A41F0DB82DB000209C76 /* testcases */ = { - isa = PBXGroup; - children = ( - F982089A0DB3280D0017AECA /* breakpad_nlist_test.h */, - F982089B0DB3280D0017AECA /* breakpad_nlist_test.cc */, - F9C5A4200DB82DD800209C76 /* DynamicImagesTests.h */, - F9C5A4210DB82DD800209C76 /* DynamicImagesTests.cc */, - F9721F300E8B07E800D7E813 /* dwarftests.h */, - F9721F310E8B07E800D7E813 /* dwarftests.mm */, - ); - path = testcases; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8DD76F620486A84900D96B5E /* generator_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "generator_test" */; - buildPhases = ( - 8DD76F640486A84900D96B5E /* Sources */, - 8DD76F660486A84900D96B5E /* Frameworks */, - 8DD76F690486A84900D96B5E /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = generator_test; - productInstallPath = "$(HOME)/bin"; - productName = MinidumpWriter; - productReference = 8DD76F6C0486A84900D96B5E /* generator_test */; - productType = "com.apple.product-type.tool"; - }; - 9B7CA84D0B1297F200CD3A1D /* unit_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9B7CA8500B12984300CD3A1D /* Build configuration list for PBXNativeTarget "unit_test" */; - buildPhases = ( - 9B7CA84B0B1297F200CD3A1D /* Sources */, - 9B7CA84C0B1297F200CD3A1D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = unit_test; - productName = "filewriter unit test"; - productReference = 9B7CA84E0B1297F200CD3A1D /* unit_test */; - productType = "com.apple.product-type.tool"; - }; - 9BD82A9A0B00267E0055103E /* handler_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9BD82AA60B0026BF0055103E /* Build configuration list for PBXNativeTarget "handler_test" */; - buildPhases = ( - 9BD82A980B00267E0055103E /* Sources */, - 9BD82A990B00267E0055103E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = handler_test; - productName = ExceptionTester; - productReference = 9BD82A9B0B00267E0055103E /* handler_test */; - productType = "com.apple.product-type.tool"; - }; - F93A88740E8B4C700026AF89 /* obj-c_TestCases */ = { - isa = PBXNativeTarget; - buildConfigurationList = F93A88790E8B4C700026AF89 /* Build configuration list for PBXNativeTarget "obj-c_TestCases" */; - buildPhases = ( - F93A88700E8B4C700026AF89 /* Resources */, - F93A88710E8B4C700026AF89 /* Sources */, - F93A88720E8B4C700026AF89 /* Frameworks */, - F93A88730E8B4C700026AF89 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "obj-c_TestCases"; - productName = octestcases; - productReference = F93A88750E8B4C700026AF89 /* octestcases.octest */; - productType = "com.apple.product-type.bundle"; - }; - F9AE19C20DB04A9500C98454 /* minidump_tests64 */ = { - isa = PBXNativeTarget; - buildConfigurationList = F9AE19C70DB04AA200C98454 /* Build configuration list for PBXNativeTarget "minidump_tests64" */; - buildPhases = ( - F9AE19BE0DB04A9500C98454 /* Resources */, - F9AE19BF0DB04A9500C98454 /* Sources */, - F9AE19C00DB04A9500C98454 /* Frameworks */, - F9AE19C10DB04A9500C98454 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = minidump_tests64; - productName = minidump_tests; - productReference = F9AE19C30DB04A9500C98454 /* minidump_tests64.cptest */; - productType = "com.apple.product-type.bundle"; - }; - F9AE5B320DBFDBA300505983 /* minidump_tests32 */ = { - isa = PBXNativeTarget; - buildConfigurationList = F9AE5B380DBFDBA300505983 /* Build configuration list for PBXNativeTarget "minidump_tests32" */; - buildPhases = ( - F9AE5B2E0DBFDBA300505983 /* Resources */, - F9AE5B2F0DBFDBA300505983 /* Sources */, - F9AE5B300DBFDBA300505983 /* Frameworks */, - F9AE5B310DBFDBA300505983 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = minidump_tests32; - productName = Untitled; - productReference = F9AE5B330DBFDBA300505983 /* minidump_tests32.cptest */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "minidump_test" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* MinidumpWriter */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8DD76F620486A84900D96B5E /* generator_test */, - 9BD82A9A0B00267E0055103E /* handler_test */, - 9B7CA84D0B1297F200CD3A1D /* unit_test */, - F9AE19C20DB04A9500C98454 /* minidump_tests64 */, - F9AE5B320DBFDBA300505983 /* minidump_tests32 */, - F93A88740E8B4C700026AF89 /* obj-c_TestCases */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - F93A88700E8B4C700026AF89 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE19BE0DB04A9500C98454 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE5B2E0DBFDBA300505983 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - F93A88730E8B4C700026AF89 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; - }; - F9AE19C10DB04A9500C98454 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n# Run gcov on the framework getting tested\nif [ \"${CONFIGURATION}\" = 'Coverage' ];\nthen\n FRAMEWORK_NAME=minidump_tests64\n FRAMEWORK_OBJ_DIR=${OBJROOT}/${PROJECT_NAME}.build/${CONFIGURATION}/${FRAMEWORK_NAME}.build/Objects-normal/${NATIVE_ARCH_ACTUAL}\n mkdir -p coverage\n pushd coverage\n echo find ${OBJROOT} -name *.gcda -exec gcov -o ${FRAMEWORK_OBJ_DIR} {} \\;\n find ${OBJROOT} -name *.gcda -exec gcov -o ${FRAMEWORK_OBJ_DIR} {} \\;\n popd\nfi "; - }; - F9AE5B310DBFDBA300505983 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DD76F640486A84900D96B5E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9BD82C020B01333D0055103E /* minidump_generator_test.cc in Sources */, - 9BD82C0F0B0133520055103E /* exception_handler.cc in Sources */, - 9BD82C110B0133520055103E /* minidump_generator.cc in Sources */, - 9BD82C260B01344C0055103E /* minidump_file_writer.cc in Sources */, - 9BD82C2E0B01345E0055103E /* string_utilities.cc in Sources */, - D2F651000BEF947200920385 /* file_id.cc in Sources */, - D2F651020BEF947200920385 /* macho_id.cc in Sources */, - D2F651040BEF947200920385 /* macho_utilities.cc in Sources */, - D2F651090BEF949A00920385 /* dynamic_images.cc in Sources */, - D2F6510E0BEF94EB00920385 /* macho_walker.cc in Sources */, - D2F651110BEF951700920385 /* string_conversion.cc in Sources */, - D2F651150BEF953000920385 /* convert_UTF.c in Sources */, - 8BFC81B011FF9C8D002CB4DC /* breakpad_nlist_64.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9B7CA84B0B1297F200CD3A1D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9B7CA8540B12989000CD3A1D /* minidump_file_writer_unittest.cc in Sources */, - 9B7CA8550B1298A100CD3A1D /* minidump_file_writer.cc in Sources */, - 9BC1D2940B336F2300F2A2B4 /* convert_UTF.c in Sources */, - 9BC1D2950B336F2500F2A2B4 /* string_conversion.cc in Sources */, - 8BFC81AE11FF9C8C002CB4DC /* breakpad_nlist_64.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9BD82A980B00267E0055103E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9BD82BFF0B01333D0055103E /* exception_handler_test.cc in Sources */, - 9BD82C0D0B0133520055103E /* exception_handler.cc in Sources */, - 9BD82C0E0B0133520055103E /* minidump_generator.cc in Sources */, - 9BD82C250B01344C0055103E /* minidump_file_writer.cc in Sources */, - 9BD82C2D0B01345E0055103E /* string_utilities.cc in Sources */, - 9B35FF5A0B267D5F008DE8C7 /* convert_UTF.c in Sources */, - 9B35FF5B0B267D5F008DE8C7 /* string_conversion.cc in Sources */, - D2F6511B0BEF970E00920385 /* dynamic_images.cc in Sources */, - D2F6511D0BEF973500920385 /* file_id.cc in Sources */, - D2F6511E0BEF973600920385 /* macho_id.cc in Sources */, - D2F6511F0BEF973900920385 /* macho_utilities.cc in Sources */, - D2F651210BEF975400920385 /* macho_walker.cc in Sources */, - 8BFC81AF11FF9C8C002CB4DC /* breakpad_nlist_64.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F93A88710E8B4C700026AF89 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F93A88860E8B4C9A0026AF89 /* dwarftests.mm in Sources */, - F93A88870E8B4C9A0026AF89 /* dump_syms.mm in Sources */, - F93A88880E8B4C9A0026AF89 /* bytereader.cc in Sources */, - F93A88890E8B4C9A0026AF89 /* dwarf2reader.cc in Sources */, - F93A888A0E8B4C9A0026AF89 /* functioninfo.cc in Sources */, - F93A888B0E8B4C9A0026AF89 /* md5.cc in Sources */, - F93A887D0E8B4C8C0026AF89 /* macho_walker.cc in Sources */, - F93A887E0E8B4C8C0026AF89 /* macho_id.cc in Sources */, - F93A887F0E8B4C8C0026AF89 /* macho_utilities.cc in Sources */, - F93A88800E8B4C8C0026AF89 /* file_id.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE19BF0DB04A9500C98454 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9B34E870DBC1E1600306484 /* dynamic_images.cc in Sources */, - F982089C0DB3280D0017AECA /* breakpad_nlist_test.cc in Sources */, - F98208A30DB32CAE0017AECA /* breakpad_nlist_64.cc in Sources */, - F9C5A4220DB82DD800209C76 /* DynamicImagesTests.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F9AE5B2F0DBFDBA300505983 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F9AE5B390DBFDBDB00505983 /* dynamic_images.cc in Sources */, - F9AE5B3A0DBFDBDB00505983 /* DynamicImagesTests.cc in Sources */, - 8BFC81AD11FF9C8A002CB4DC /* breakpad_nlist_64.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB923208733DC60010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", - ); - PRODUCT_NAME = generator_test; - USER_HEADER_SEARCH_PATHS = "../../../** $(inherited)"; - }; - name = Debug; - }; - 1DEB923308733DC60010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", - ); - PRODUCT_NAME = generator_test; - USER_HEADER_SEARCH_PATHS = "../../../** $(inherited)"; - }; - name = Release; - }; - 1DEB923608733DC60010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8BFC812111FF99D5002CB4DC /* BreakpadDebug.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 1DEB923708733DC60010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8BFC812211FF99D5002CB4DC /* BreakpadRelease.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 9B7CA8510B12984300CD3A1D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = unit_test; - USER_HEADER_SEARCH_PATHS = "../../../** $(inherited)"; - }; - name = Debug; - }; - 9B7CA8520B12984300CD3A1D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = unit_test; - USER_HEADER_SEARCH_PATHS = "../../../** $(inherited)"; - }; - name = Release; - }; - 9BD82AA70B0026BF0055103E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = handler_test; - USER_HEADER_SEARCH_PATHS = "../../.. $(inherited)"; - }; - name = Debug; - }; - 9BD82AA80B0026BF0055103E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = handler_test; - USER_HEADER_SEARCH_PATHS = "../../.. $(inherited)"; - }; - name = Release; - }; - F93A88770E8B4C700026AF89 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "obj-cTestCases-Info.plist"; - PRODUCT_NAME = octestcases; - USER_HEADER_SEARCH_PATHS = "../../../..//**"; - WRAPPER_EXTENSION = octest; - }; - name = Debug; - }; - F93A88780E8B4C700026AF89 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "obj-cTestCases-Info.plist"; - PRODUCT_NAME = octestcases; - USER_HEADER_SEARCH_PATHS = "../../../..//**"; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; - F9AE19C40DB04A9500C98454 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "minidump_tests64-Info.plist"; - PRODUCT_NAME = minidump_tests64; - USER_HEADER_SEARCH_PATHS = "../../../**"; - WRAPPER_EXTENSION = cptest; - }; - name = Debug; - }; - F9AE19C50DB04A9500C98454 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "minidump_tests64-Info.plist"; - PRODUCT_NAME = minidump_tests64; - USER_HEADER_SEARCH_PATHS = "../../../**"; - WRAPPER_EXTENSION = cptest; - }; - name = Release; - }; - F9AE5B350DBFDBA300505983 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "minidump_tests32-Info.plist"; - PRODUCT_NAME = minidump_tests32; - USER_HEADER_SEARCH_PATHS = "../../../**"; - WRAPPER_EXTENSION = cptest; - }; - name = Debug; - }; - F9AE5B370DBFDBA300505983 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; - INFOPLIST_FILE = "minidump_tests32-Info.plist"; - PRODUCT_NAME = minidump_tests32; - USER_HEADER_SEARCH_PATHS = "../../../**"; - WRAPPER_EXTENSION = cptest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "generator_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB923208733DC60010E9CD /* Debug */, - 1DEB923308733DC60010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "minidump_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB923608733DC60010E9CD /* Debug */, - 1DEB923708733DC60010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9B7CA8500B12984300CD3A1D /* Build configuration list for PBXNativeTarget "unit_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9B7CA8510B12984300CD3A1D /* Debug */, - 9B7CA8520B12984300CD3A1D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9BD82AA60B0026BF0055103E /* Build configuration list for PBXNativeTarget "handler_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9BD82AA70B0026BF0055103E /* Debug */, - 9BD82AA80B0026BF0055103E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F93A88790E8B4C700026AF89 /* Build configuration list for PBXNativeTarget "obj-c_TestCases" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F93A88770E8B4C700026AF89 /* Debug */, - F93A88780E8B4C700026AF89 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F9AE19C70DB04AA200C98454 /* Build configuration list for PBXNativeTarget "minidump_tests64" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F9AE19C40DB04A9500C98454 /* Debug */, - F9AE19C50DB04A9500C98454 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F9AE5B380DBFDBA300505983 /* Build configuration list for PBXNativeTarget "minidump_tests32" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F9AE5B350DBFDBA300505983 /* Debug */, - F9AE5B370DBFDBA300505983 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests32-Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests32-Info.plist deleted file mode 100644 index 921ebf357..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests32-Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.google.breakpad.minidump_tests32 - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests64-Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests64-Info.plist deleted file mode 100644 index acfbd3091..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_tests64-Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.google.breakpad.minidump_tests64 - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - CSResourcesFileMapped - yes - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build deleted file mode 100644 index 7b3260808..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build +++ /dev/null @@ -1,22 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'breakpad_nlist_64.cc', - 'dynamic_images.cc', - 'exception_handler.cc', - 'minidump_generator.cc', -] - -# We allow warnings for third-party code that can be updated from upstream. -ALLOW_COMPILER_WARNINGS = True - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../../..', -] - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/obj-cTestCases-Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/obj-cTestCases-Info.plist deleted file mode 100644 index 65013556d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/obj-cTestCases-Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.cc deleted file mode 100644 index 6142ad124..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ProtectedMemoryAllocator -// -// See the header file for documentation - -#include "protected_memory_allocator.h" -#include - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -ProtectedMemoryAllocator::ProtectedMemoryAllocator(vm_size_t pool_size) - : pool_size_(pool_size), - next_alloc_offset_(0), - valid_(false) { - - kern_return_t result = vm_allocate(mach_task_self(), - &base_address_, - pool_size, - TRUE - ); - - valid_ = (result == KERN_SUCCESS); - assert(valid_); -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -ProtectedMemoryAllocator::~ProtectedMemoryAllocator() { - vm_deallocate(mach_task_self(), - base_address_, - pool_size_ - ); -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -char *ProtectedMemoryAllocator::Allocate(vm_size_t bytes) { - if (valid_ && next_alloc_offset_ + bytes <= pool_size_) { - char *p = (char*)base_address_ + next_alloc_offset_; - next_alloc_offset_ += bytes; - return p; - } - - return NULL; // ran out of memory in our allocation block -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -kern_return_t ProtectedMemoryAllocator::Protect() { - kern_return_t result = vm_protect(mach_task_self(), - base_address_, - pool_size_, - FALSE, - VM_PROT_READ); - - return result; -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -kern_return_t ProtectedMemoryAllocator::Unprotect() { - kern_return_t result = vm_protect(mach_task_self(), - base_address_, - pool_size_, - FALSE, - VM_PROT_READ | VM_PROT_WRITE); - - return result; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.h deleted file mode 100644 index 7e188db26..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ProtectedMemoryAllocator -// -// A very simple allocator class which allows allocation, but not deallocation. -// The allocations can be made read-only with the Protect() method. -// This class is NOT useful as a general-purpose memory allocation system, -// since it does not allow deallocation. It is useful to use for a group -// of allocations which are created in the same time-frame and destroyed -// in the same time-frame. It is useful for making allocations of memory -// which will not need to change often once initialized. This memory can then -// be protected from memory smashers by calling the Protect() method. - -#ifndef PROTECTED_MEMORY_ALLOCATOR_H__ -#define PROTECTED_MEMORY_ALLOCATOR_H__ - -#include - -// -class ProtectedMemoryAllocator { - public: - ProtectedMemoryAllocator(vm_size_t pool_size); - ~ProtectedMemoryAllocator(); - - // Returns a pointer to an allocation of size n within the pool. - // Fails by returning NULL is no more space is available. - // Please note that the pointers returned from this method should not - // be freed in any way (for example by calling free() on them ). - char * Allocate(vm_size_t n); - - // Returns the base address of the allocation pool. - char * GetBaseAddress() { return (char*)base_address_; } - - // Returns the size of the allocation pool, including allocated - // plus free space. - vm_size_t GetTotalSize() { return pool_size_; } - - // Returns the number of bytes already allocated in the pool. - vm_size_t GetAllocatedSize() { return next_alloc_offset_; } - - // Returns the number of bytes available for allocation. - vm_size_t GetFreeSize() { return pool_size_ - next_alloc_offset_; } - - // Makes the entire allocation pool read-only including, of course, - // all allocations made from the pool. - kern_return_t Protect(); - - // Makes the entire allocation pool read/write. - kern_return_t Unprotect(); - - private: - vm_size_t pool_size_; - vm_address_t base_address_; - vm_size_t next_alloc_offset_; - bool valid_; -}; - -#endif // PROTECTED_MEMORY_ALLOCATOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.cc deleted file mode 100644 index 0fc7825b2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// DynamicImagesTests.cpp -// minidump_test -// -// Created by Neal Sidhwaney on 4/17/08. -// Copyright 2008 Google Inc. All rights reserved. -// - -#include "client/mac/handler/testcases/DynamicImagesTests.h" -#include "client/mac/handler/dynamic_images.h" - -DynamicImagesTests test2(TEST_INVOCATION(DynamicImagesTests, - ReadTaskMemoryTest)); -DynamicImagesTests test3(TEST_INVOCATION(DynamicImagesTests, - ReadLibrariesFromLocalTaskTest)); - -DynamicImagesTests::DynamicImagesTests(TestInvocation *invocation) - : TestCase(invocation) { -} - -DynamicImagesTests::~DynamicImagesTests() { -} - -void DynamicImagesTests::ReadTaskMemoryTest() { - kern_return_t kr; - - // pick test2 as a symbol we know to be valid to read - // anything will work, really - void *addr = reinterpret_cast(&test2); - std::vector buf(getpagesize()); - - fprintf(stderr, "reading 0x%p\n", addr); - kr = google_breakpad::ReadTaskMemory(mach_task_self(), - (uint64_t)addr, - getpagesize(), - buf); - - CPTAssert(kr == KERN_SUCCESS); - - CPTAssert(0 == memcmp(&buf[0], (const void*)addr, getpagesize())); -} - -void DynamicImagesTests::ReadLibrariesFromLocalTaskTest() { - - mach_port_t me = mach_task_self(); - google_breakpad::DynamicImages *d = new google_breakpad::DynamicImages(me); - - fprintf(stderr,"Local task image count: %d\n", d->GetImageCount()); - - CPTAssert(d->GetImageCount() > 0); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.h deleted file mode 100644 index e1e79993b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// DynamicImagesTests.h -// minidump_test -// -// Created by Neal Sidhwaney on 4/17/08. -// Copyright 2008 Google Inc. All rights reserved. -// -// - -#ifndef _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__ -#define _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__ - -#include - -class DynamicImagesTests : public TestCase { - public: - explicit DynamicImagesTests(TestInvocation* invocation); - virtual ~DynamicImagesTests(); - - void ReadTaskMemoryTest(); - void ReadLibrariesFromLocalTaskTest(); -}; - -#endif /* _CLIENT_MAC_HANDLER_TESTCASES_DYNAMICIMAGESTESTS_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.cc deleted file mode 100644 index e7332bfb6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// breakpad_nlist_test.cc -// minidump_test -// -// Created by Neal Sidhwaney on 4/13/08. -// Copyright 2008 Google Inc. All rights reserved. -// - -#include "client/mac/handler/testcases/breakpad_nlist_test.h" -#include -#include "client/mac/handler/breakpad_nlist_64.h" - -BreakpadNlistTest test1(TEST_INVOCATION(BreakpadNlistTest, CompareToNM)); - -BreakpadNlistTest::BreakpadNlistTest(TestInvocation *invocation) - : TestCase(invocation) { -} - - -BreakpadNlistTest::~BreakpadNlistTest() { -} - -void BreakpadNlistTest::CompareToNM() { -#if TARGET_CPU_X86_64 - system("/usr/bin/nm -arch x86_64 /usr/lib/dyld > /tmp/dyld-namelist.txt"); -#elif TARGET_CPU_PPC64 - system("/usr/bin/nm -arch ppc64 /usr/lib/dyld > /tmp/dyld-namelist.txt"); -#endif - - FILE *fd = fopen("/tmp/dyld-namelist.txt", "rt"); - - char oneNMAddr[30]; - char symbolType; - char symbolName[500]; - while (!feof(fd)) { - fscanf(fd, "%s %c %s", oneNMAddr, &symbolType, symbolName); - breakpad_nlist symbolList[2]; - breakpad_nlist &list = symbolList[0]; - - memset(symbolList, 0, sizeof(breakpad_nlist)*2); - const char *symbolNames[2]; - symbolNames[0] = (const char*)symbolName; - symbolNames[1] = "\0"; - breakpad_nlist_64("/usr/lib/dyld", &list, symbolNames); - uint64_t nmAddr = strtol(oneNMAddr, NULL, 16); - if (!IsSymbolMoreThanOnceInDyld(symbolName)) { - CPTAssert(nmAddr == symbolList[0].n_value); - } - } - - fclose(fd); -} - -bool BreakpadNlistTest::IsSymbolMoreThanOnceInDyld(const char *symbolName) { - // These are the symbols that occur more than once when nm dumps - // the symbol table of /usr/lib/dyld. Our nlist program returns - // the first address because it's doing a search so we need to exclude - // these from causing the test to fail - const char *multipleSymbols[] = { - "__Z41__static_initialization_and_destruction_0ii", - "___tcf_0", - "___tcf_1", - "_read_encoded_value_with_base", - "_read_sleb128", - "_read_uleb128", - "\0"}; - - bool found = false; - - for (int i = 0; multipleSymbols[i][0]; i++) { - if (!strcmp(multipleSymbols[i], symbolName)) { - found = true; - break; - } - } - - return found; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.h deleted file mode 100644 index e93657cc9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// breakpad_nlist_test.h -// minidump_test -// -// Created by Neal Sidhwaney on 4/13/08. -// Copyright 2008 Google Inc. All rights reserved. -// -// - -#ifndef CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__ -#define CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__ - -#include - -class BreakpadNlistTest : public TestCase { - private: - - // nm dumps multiple addresses for the same symbol in - // /usr/lib/dyld. So we track those so we don't report failures - // in mismatches between what our nlist returns and what nm has - // for the duplicate symbols. - bool IsSymbolMoreThanOnceInDyld(const char *symbolName); - - public: - explicit BreakpadNlistTest(TestInvocation* invocation); - virtual ~BreakpadNlistTest(); - - - /* This test case runs nm on /usr/lib/dyld and then compares the - output of every symbol to what our nlist implementation returns */ - void CompareToNM(); -}; - -#endif /* CLIENT_MAC_HANDLER_TESTCASES_BREAKPAD_NLIST_TEST_H__*/ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.h deleted file mode 100644 index 21ff7a44f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// dwarftests.h -// minidump_test -// -// Created by Neal Sidhwaney on 9/24/08. -// Copyright 2008 Google Inc. All rights reserved. -// - -#import - - -@interface dwarftests : SenTestCase { - -} - -- (void) testDWARFSymbolFileGeneration; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.mm deleted file mode 100644 index 40c69aff2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.mm +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// dwarftests.m -// minidump_test -// -// Created by Neal Sidhwaney on 9/24/08. -// Copyright 2008 Google Inc. All rights reserved. -// - -#import "dwarftests.h" -#import "dump_syms.h" - -@implementation dwarftests -- (void) testDWARFSymbolFileGeneration { - NSString *inputBreakpadSymbolFile = @"testcases/testdata/dump_syms_i386_breakpad.sym"; - NSString *outputBreakpadSymbolFile = @"/tmp/dump_syms_i386.breakpad"; - - DumpSymbols *dump = [[DumpSymbols alloc] initWithContentsOfFile:@"testcases/testdata/dump_syms_dwarf_data"]; - - STAssertNotNil(dump, @"DumpSymbols is nil"); - [dump setArchitecture:@"i386"]; - [dump writeSymbolFile:outputBreakpadSymbolFile]; - - NSData *d = [[NSData alloc] initWithContentsOfFile:inputBreakpadSymbolFile]; - STAssertNotNil(d, @"Input breakpad symbol file not found"); - - NSData *d1 = [[NSData alloc] initWithContentsOfFile:outputBreakpadSymbolFile]; - STAssertNotNil(d1, @"Output breakpad symbol file not found"); - - STAssertTrue([d isEqualToData:d1], - @"Symbol files were not equal!",nil); -} -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_dwarf_data b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_dwarf_data deleted file mode 100644 index 5be17aeed..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_dwarf_data and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym deleted file mode 100644 index bca43c103..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym +++ /dev/null @@ -1,5300 +0,0 @@ -MODULE mac x86 94BF873C47A73BC07125291390B4C5F10 dump_syms_dwarf_data -FILE 1 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/libkern/i386/OSByteOrder.h -FILE 2 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/architecture/byte_order.h -FILE 3 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/dump_syms.mm -FILE 4 /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSRange.h -FILE 5 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/new -FILE 6 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/hash_fun.h -FILE 7 ../../../common/mac/dwarf/dwarf2reader.h -FILE 8 ../../../common/mac/file_id.h -FILE 9 ../../../common/mac/dwarf/functioninfo.h -FILE 10 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_tree.h -FILE 11 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_iterator.h -FILE 12 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/hashtable.h -FILE 13 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_pair.h -FILE 14 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h -FILE 15 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/allocator.h -FILE 16 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_vector.h -FILE 17 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_iterator_base_types.h -FILE 18 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_iterator_base_funcs.h -FILE 19 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algo.h -FILE 20 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_map.h -FILE 21 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h -FILE 22 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_function.h -FILE 23 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/hash_map -FILE 24 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/basic_string.h -FILE 25 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algobase.h -FILE 26 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_list.h -FILE 27 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/list.tcc -FILE 28 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_uninitialized.h -FILE 29 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/vector.tcc -FILE 30 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/dwarf/functioninfo.cc -FILE 31 ../../../common/mac/dwarf/dwarf2reader.h -FILE 32 ../../../common/mac/dwarf/functioninfo.h -FILE 33 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_pair.h -FILE 34 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/hashtable.h -FILE 35 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/memory -FILE 36 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h -FILE 37 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/basic_string.h -FILE 38 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_iterator.h -FILE 39 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_vector.h -FILE 40 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_tree.h -FILE 41 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_function.h -FILE 42 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/hash_map -FILE 43 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h -FILE 44 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algobase.h -FILE 45 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_map.h -FILE 46 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_uninitialized.h -FILE 47 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/vector.tcc -FILE 48 /g/code/breakpad-staging/src/tools/mac/dump_syms/dump_syms_tool.mm -FILE 49 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/file_id.cc -FILE 50 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/architecture/byte_order.h -FILE 51 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/macho_id.cc -FILE 52 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/libkern/i386/OSByteOrder.h -FILE 53 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/architecture/byte_order.h -FILE 54 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/macho_walker.cc -FILE 55 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/libkern/i386/OSByteOrder.h -FILE 56 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/architecture/byte_order.h -FILE 57 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/macho_utilities.cc -FILE 58 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/dwarf/bytereader.cc -FILE 59 ../../../common/mac/dwarf/bytereader-inl.h -FILE 60 /g/code/breakpad-staging/src/tools/mac/dump_syms/../../../common/mac/dwarf/dwarf2reader.cc -FILE 61 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algobase.h -FILE 62 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_deque.h -FILE 63 ../../../common/mac/dwarf/bytereader.h -FILE 64 ../../../common/mac/dwarf/bytereader-inl.h -FILE 65 ../../../common/mac/dwarf/line_state_machine.h -FILE 66 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_list.h -FILE 67 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/memory -FILE 68 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h -FILE 69 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/allocator.h -FILE 70 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_pair.h -FILE 71 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_vector.h -FILE 72 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_iterator.h -FILE 73 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h -FILE 74 ../../../common/mac/dwarf/dwarf2reader.h -FILE 75 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_stack.h -FILE 76 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/deque.tcc -FILE 77 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/list.tcc -FILE 78 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/vector.tcc -FILE 79 /Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_uninitialized.h -FILE 80 /var/tmp/gcc/gcc-5484~1/src/gcc/libgcc2.c -FUNC 162a 28 0 _OSSwapInt16 -162a 10 44 55 -163a 16 46 55 -1650 2 47 55 -FUNC 1652 1c 0 _OSSwapInt32 -1652 f 53 55 -1661 8 55 55 -1669 3 56 55 -166c 2 57 55 -FUNC 166e 2b 0 _OSSwapInt64 -166e 12 64 55 -1680 11 69 55 -1691 6 70 55 -1697 2 71 55 -1699 1 71 55 -FUNC 169a 1e 0 NXSwapShort -169a 10 43 56 -16aa c 45 56 -16b6 2 46 56 -FUNC 16b8 19 0 NXSwapInt -16b8 f 52 56 -16c7 8 54 56 -16cf 2 55 56 -16d1 1 55 56 -FUNC 16d2 19 0 NXSwapLong -16d2 f 61 56 -16e1 8 63 56 -16e9 2 64 56 -16eb 1 64 56 -FUNC 16ec 1f 0 NXSwapLongLong -16ec 12 70 56 -16fe b 72 56 -1709 2 73 56 -170b 1 73 56 -FUNC 170c 181 0 -[DumpSymbols convertCPlusPlusSymbols:] -170c 14 128 3 -1720 54 130 3 -1774 f 132 3 -1783 7 133 3 -178a 1a 136 3 -17a4 5 138 3 -17a9 1a 139 3 -17c3 23 140 3 -17e6 7 141 3 -17ed 44 142 3 -1831 1e 145 3 -184f 29 138 3 -1878 b 148 3 -1883 3 150 3 -1886 7 151 3 -188d 1 151 3 -FUNC 188e 323 0 -[DumpSymbols convertSymbols] -188e 14 154 3 -18a2 1f 155 3 -18c1 3e 156 3 -18ff 2b 160 3 -192a c 162 3 -1936 43 164 3 -1979 2a 165 3 -19a3 20 168 3 -19c3 d 169 3 -19d0 1e 171 3 -19ee 11 162 3 -19ff 7 181 3 -1a06 6 182 3 -1a0c 5 184 3 -1a11 15 185 3 -1a26 6 18 4 -1a2c 6 19 4 -1a32 6 20 4 -1a38 6 185 3 -1a3e 28 186 3 -1a66 21 187 3 -1a87 1a 188 3 -1aa1 a 190 3 -1aab c 194 3 -1ab7 43 198 3 -1afa 21 199 3 -1b1b 20 202 3 -1b3b 2e 203 3 -1b69 1e 194 3 -1b87 c 184 3 -1b93 17 207 3 -1baa 7 208 3 -1bb1 1 208 3 -FUNC 1bb2 4a2 0 -[DumpSymbols addFunction:line:address:section:] -1bb2 21 211 3 -1bd3 2f 212 3 -1c02 e 214 3 -1c10 4 219 3 -1c14 2a 221 3 -1c3e 22 223 3 -1c60 6 224 3 -1c66 2a 225 3 -1c90 4 226 3 -1c94 2e 230 3 -1cc2 2e 233 3 -1cf0 2e 236 3 -1d1e a 239 3 -1d28 2b 253 3 -1d53 e 254 3 -1d61 3c 255 3 -1d9d 22 32 4 -1dbf 3 256 3 -1dc2 6 259 3 -1dc8 a 260 3 -1dd2 3c 261 3 -1e0e 25 262 3 -1e33 2a 263 3 -1e5d 22 265 3 -1e7f 26 270 3 -1ea5 6 272 3 -1eab 37 273 3 -1ee2 2a 274 3 -1f0c 17 275 3 -1f23 43 278 3 -1f66 2e 279 3 -1f94 23 282 3 -1fb7 43 285 3 -1ffa 52 287 3 -204c 8 289 3 -FUNC 2054 5a4 0 -[DumpSymbols processSymbolItem:stringTable:] -2054 18 292 3 -206c 8 293 3 -2074 4 294 3 -2078 16 297 3 -208e c 298 3 -209a f 300 3 -20a9 b 301 3 -20b4 16 303 3 -20ca 4d 309 3 -2117 38 311 3 -214f 30 315 3 -217f 60 317 3 -21df d 322 3 -21ec 2b 325 3 -2217 3a 327 3 -2251 f 332 3 -2260 2d 333 3 -228d 1a 334 3 -22a7 32 335 3 -22d9 20 342 3 -22f9 c 343 3 -2305 24 348 3 -2329 a 349 3 -2333 3c 350 3 -236f 2a 352 3 -2399 1c 353 3 -23b5 9 354 3 -23be f 356 3 -23cd 2d 357 3 -23fa 2f 358 3 -2429 20 360 3 -2449 c 361 3 -2455 7 363 3 -245c 21 365 3 -247d 4a 368 3 -24c7 9 370 3 -24d0 1a 371 3 -24ea 4b 372 3 -2535 4 373 3 -2539 5 371 3 -253e 29 374 3 -2567 2d 376 3 -2594 4b 378 3 -25df 4 379 3 -25e3 a 382 3 -25ed b 383 3 -FUNC 25f8 c9 0 -[DumpSymbols loadSymbolInfo:offset:] -25f8 13 391 3 -260b 2b 392 3 -2636 2a 393 3 -2660 2d 395 3 -268d 2e 398 3 -26bb 6 399 3 -26c1 1 399 3 -FUNC 26c2 2be 0 -[DumpSymbols loadSTABSSymbolInfo:offset:] -26c2 16 537 3 -26d8 9 538 3 -26e1 10 539 3 -26f1 2e 540 3 -271f 9 542 3 -2728 22 543 3 -274a 4 544 3 -274e a 546 3 -2758 3c 547 3 -2794 c 549 3 -27a0 e 550 3 -27ae 6 551 3 -27b4 25 552 3 -27d9 25 553 3 -27fe 25 554 3 -2823 c 555 3 -282f c 556 3 -283b c 559 3 -2847 23 562 3 -286a a 563 3 -2874 a 564 3 -287e 2e 565 3 -28ac 39 566 3 -28e5 2e 570 3 -2913 4 571 3 -2917 17 559 3 -292e 25 575 3 -2953 9 576 3 -295c 17 549 3 -2973 4 579 3 -2977 9 580 3 -FUNC 2980 28a 0 -[DumpSymbols loadSymbolInfo64:offset:] -2980 16 583 3 -2996 9 585 3 -299f 10 586 3 -29af 2e 587 3 -29dd 9 589 3 -29e6 22 590 3 -2a08 4 591 3 -2a0c c 593 3 -2a18 e 594 3 -2a26 6 595 3 -2a2c 25 596 3 -2a51 25 597 3 -2a76 25 598 3 -2a9b 9 599 3 -2aa4 c 600 3 -2ab0 c 603 3 -2abc 17 604 3 -2ad3 23 609 3 -2af6 a 610 3 -2b00 a 611 3 -2b0a 2e 612 3 -2b38 37 613 3 -2b6f 2e 615 3 -2b9d 4 616 3 -2ba1 17 603 3 -2bb8 25 620 3 -2bdd 9 621 3 -2be6 17 593 3 -2bfd 4 624 3 -2c01 9 625 3 -FUNC 2c0a 199 0 -[DumpSymbols loadSymbolInfoForArchitecture] -2c0a 13 628 3 -2c1d 41 630 3 -2c5e 2b 631 3 -2c89 1a 632 3 -2ca3 40 634 3 -2ce3 40 635 3 -2d23 5f 637 3 -2d82 17 639 3 -2d99 4 640 3 -2d9d 6 641 3 -2da3 1 641 3 -FUNC 2da4 3e5 0 -[DumpSymbols loadHeader:offset:] -2da4 18 728 3 -2dbc 9 729 3 -2dc5 10 730 3 -2dd5 2e 731 3 -2e03 9 733 3 -2e0c 2b 734 3 -2e37 1e 736 3 -2e55 c 738 3 -2e61 e 739 3 -2e6f 6 740 3 -2e75 50 742 3 -2ec5 2e 743 3 -2ef3 2e 744 3 -2f21 2e 745 3 -2f4f 20 746 3 -2f6f 1b7 755 3 -3126 9 757 3 -312f 25 761 3 -3154 9 762 3 -315d 17 738 3 -3174 a 765 3 -317e b 766 3 -3189 1 766 3 -FUNC 318a 41d 0 -[DumpSymbols loadHeader64:offset:] -318a 18 769 3 -31a2 9 771 3 -31ab 10 772 3 -31bb 2e 773 3 -31e9 9 775 3 -31f2 c 777 3 -31fe 2b 778 3 -3229 e 779 3 -3237 6 780 3 -323d 50 781 3 -328d 49 782 3 -32d6 49 783 3 -331f 2e 784 3 -334d 9 785 3 -3356 29 786 3 -337f 1c5 794 3 -3544 9 795 3 -354d 25 799 3 -3572 9 800 3 -357b 17 777 3 -3592 a 803 3 -359c b 804 3 -35a7 1 804 3 -FUNC 35a8 52a 0 -[DumpSymbols loadModuleInfo] -35a8 14 807 3 -35bc e 808 3 -35ca 41 810 3 -360b 1a 811 3 -3625 6 812 3 -362b 6 814 3 -3631 17 815 3 -3648 c 816 3 -3654 29 820 3 -367d 29 821 3 -36a6 29 822 3 -36cf 35 824 3 -3704 12 826 3 -3716 17 827 3 -372d c 828 3 -3739 3c 832 3 -3775 a 834 3 -377f 9 836 3 -3788 25 837 3 -37ad c 839 3 -37b9 54 840 3 -380d 57 841 3 -3864 57 842 3 -38bb 57 843 3 -3912 57 844 3 -3969 1c 846 3 -3985 4b 847 3 -39d0 49 849 3 -3a19 13 839 3 -3a2c 6 851 3 -3a32 3c 852 3 -3a6e 3a 854 3 -3aa8 17 857 3 -3abf c 858 3 -3acb 7 859 3 -FUNC 3ad2 b6 0 WriteFormat -3ad2 10 862 3 -3ae2 6 867 3 -3ae8 24 868 3 -3b0c 27 869 3 -3b33 40 870 3 -3b73 c 873 3 -3b7f 9 874 3 -FUNC 3b88 35 0 -[DumpSymbols availableArchitectures] -3b88 13 1140 3 -3b9b 1c 1141 3 -3bb7 6 1142 3 -3bbd 1 1142 3 -FUNC 3bbe 1b4 0 -[DumpSymbols setArchitecture:] -3bbe 13 1158 3 -3bd1 1a 1159 3 -3beb 4 1160 3 -3bef 2a 1162 3 -3c19 9 1163 3 -3c22 2a 1165 3 -3c4c 9 1166 3 -3c55 9 1167 3 -3c5e 2a 1169 3 -3c88 6 1170 3 -3c8e 2a 1172 3 -3cb8 6 1173 3 -3cbe 2a 1175 3 -3ce8 4 1176 3 -3cec 6 1179 3 -3cf2 2c 1180 3 -3d1e 9 1181 3 -3d27 1c 1183 3 -3d43 1f 1184 3 -3d62 a 1187 3 -3d6c 6 1188 3 -FUNC 3d72 14 0 -[DumpSymbols architecture] -3d72 c 1191 3 -3d7e 6 1192 3 -3d84 2 1193 3 -FUNC 3d86 e7 0 -[DumpSymbols writeSymbolFile:] -3d86 13 1196 3 -3d99 1a 1197 3 -3db3 48 1200 3 -3dfb 9 1201 3 -3e04 1e 1203 3 -3e22 6 1205 3 -3e28 9 1206 3 -3e31 21 1208 3 -3e52 b 1210 3 -3e5d a 1212 3 -3e67 6 1213 3 -3e6d 1 1213 3 -FUNC 3e6e 65 0 -[MachSection initWithMachSection:andNumber:] -3e6e 13 1219 3 -3e81 37 1220 3 -3eb8 9 1221 3 -3ec1 9 1222 3 -3eca 3 1225 3 -3ecd 6 1226 3 -3ed3 1 1226 3 -FUNC 3ed4 14 0 -[MachSection sectionPointer] -3ed4 c 1228 3 -3ee0 6 1229 3 -3ee6 2 1230 3 -FUNC 3ee8 14 0 -[MachSection sectionNumber] -3ee8 c 1232 3 -3ef4 6 1233 3 -3efa 2 1234 3 -FUNC 3efc 17c 0 -[DumpSymbols processDWARFSourceFileInfo:] -3efc 14 459 3 -3f10 a 460 3 -3f1a 3c 461 3 -3f56 20 463 3 -3f76 5 464 3 -3f7b 3a 465 3 -3fb5 1d 466 3 -3fd2 3a 467 3 -400c 2a 468 3 -4036 3b 464 3 -4071 7 471 3 -FUNC 4078 1d7 0 DumpFunctionMap(std::map, std::allocator > >) -4078 15 82 3 -408d 13 83 3 -40a0 1e 85 3 -40be 42 89 3 -4100 20 90 3 -4120 2b 91 3 -414b 1a 92 3 -4165 23 93 3 -4188 46 96 3 -41ce 46 99 3 -4214 33 83 3 -4247 8 102 3 -424f 1 102 3 -FUNC 4250 3ef 0 -[DumpSymbols processDWARFFunctionInfo:] -4250 15 473 3 -4265 25 474 3 -428a 1e 476 3 -42a8 a 480 3 -42b2 3c 481 3 -42ee 3d 483 3 -432b 23 485 3 -434e 26 487 3 -4374 6 489 3 -437a 37 490 3 -43b1 2a 491 3 -43db 17 492 3 -43f2 30 496 3 -4422 3d 497 3 -445f 2e 498 3 -448d 30 502 3 -44bd 64 504 3 -4521 34 507 3 -4555 9d 509 3 -45f2 45 474 3 -4637 8 513 3 -463f 1 513 3 -FUNC 4640 1f5 0 -[DumpSymbols processDWARFLineNumberInfo:] -4640 15 515 3 -4655 25 516 3 -467a 39 520 3 -46b3 26 521 3 -46d9 6 523 3 -46df 37 524 3 -4716 2a 525 3 -4740 17 526 3 -4757 30 529 3 -4787 61 531 3 -47e8 45 516 3 -482d 8 534 3 -4835 1 534 3 -FUNC 4836 10f 0 -[DumpSymbols dealloc] -4836 13 1145 3 -4849 1c 1146 3 -4865 1c 1147 3 -4881 1c 1148 3 -489d 1c 1149 3 -48b9 1c 1150 3 -48d5 1c 1151 3 -48f1 25 1152 3 -4916 29 1154 3 -493f 6 1155 3 -4945 1 1155 3 -FUNC 4946 512 0 -[DumpSymbols loadDWARFSymbolInfo:offset:] -4946 17 402 3 -495d 9 405 3 -4966 10 406 3 -4976 2b 408 3 -49a1 38 409 3 -49d9 3a 410 3 -4a13 2e 411 3 -4a41 31 416 3 -4a72 e 418 3 -4a80 24 420 3 -4aa4 5 422 3 -4aa9 b 424 3 -4ab4 b 425 3 -4abf e 426 3 -4acd 2b 427 3 -4af8 2b 428 3 -4b23 2c 431 3 -4b4f 52 439 3 -4ba1 34 444 3 -4bd5 1a 446 3 -4bef 21 451 3 -4c10 1e 452 3 -4c2e 21 453 3 -4c4f 40 422 3 -4c8f 6 453 3 -4c95 170 422 3 -4e05 43 456 3 -4e48 10 457 3 -FUNC 4e58 4fd 0 -[DumpSymbols generateSectionDictionary:] -4e58 18 663 3 -4e70 10 665 3 -4e80 2e 666 3 -4eae 9 668 3 -4eb7 2b 669 3 -4ee2 7 670 3 -4ee9 2e 672 3 -4f17 d 676 3 -4f24 32 678 3 -4f56 29 680 3 -4f7f a 684 3 -4f89 3c 685 3 -4fc5 31 688 3 -4ff6 5d 689 3 -5053 26 692 3 -5079 21 694 3 -509a c 698 3 -50a6 e 699 3 -50b4 6 700 3 -50ba 9 701 3 -50c3 2e 702 3 -50f1 c 704 3 -50fd 3c 706 3 -5139 66 709 3 -519f 1c 712 3 -51bb fb 714 3 -52b6 6 717 3 -52bc 5 718 3 -52c1 19 704 3 -52da 25 714 3 -52ff 2e 722 3 -532d 9 723 3 -5336 17 698 3 -534d 8 725 3 -5355 1 725 3 -FUNC 5356 24a 0 -[DumpSymbols getSectionMapForArchitecture:] -5356 14 643 3 -536a 43 645 3 -53ad 1a 648 3 -53c7 1c 645 3 -53e3 18 648 3 -53fb 40 650 3 -543b 20 651 3 -545b 17 652 3 -5472 16 651 3 -5488 cb 652 3 -5553 11 654 3 -5564 32 657 3 -5596 a 658 3 -FUNC 55a0 3fe 0 -[DumpSymbols initWithContentsOfFile:] -55a0 14 1056 3 -55b4 3b 1057 3 -55ef 44 1059 3 -5633 17 1060 3 -564a c 1061 3 -5656 1f 1064 3 -5675 2b 1067 3 -56a0 a 1069 3 -56aa 35 1083 3 -56df 2 1087 3 -56e1 1a 1088 3 -56fb 3d 1087 3 -5738 33 1092 3 -576b 6 1094 3 -5771 e 1095 3 -577f 17 1096 3 -5796 c 1097 3 -57a2 1c 1101 3 -57be 1f 1103 3 -57dd 18 1104 3 -57f5 23 1107 3 -5818 25 1109 3 -583d 1c 1107 3 -5859 17 1110 3 -5870 c 1111 3 -587c 2a 1115 3 -58a6 8 1116 3 -58ae a 1118 3 -58b8 9 1119 3 -58c1 d 1122 3 -58ce 29 1124 3 -58f7 20 1126 3 -5917 20 1128 3 -5937 57 1132 3 -598e 9 1136 3 -5997 7 1137 3 -FUNC 599e d74 0 -[DumpSymbols outputSymbolFile:] -599e 18 877 3 -59b6 2e 879 3 -59e4 30 880 3 -5a14 5d 882 3 -5a71 30 883 3 -5aa1 5d 885 3 -5afe 2e 888 3 -5b2c 38 891 3 -5b64 46 892 3 -5baa 26 893 3 -5bd0 20 895 3 -5bf0 20 904 3 -5c10 30 898 3 -5c40 f 899 3 -5c4f 1e 904 3 -5c6d 17 907 3 -5c84 17 908 3 -5c9b 44 911 3 -5cdf 44 914 3 -5d23 a 917 3 -5d2d 36 921 3 -5d63 30 923 3 -5d93 9 18 4 -5d9c 9 19 4 -5da5 c 20 4 -5db1 56 923 3 -5e07 74 925 3 -5e7b f 927 3 -5e8a 44 932 3 -5ece 20 933 3 -5eee c 934 3 -5efa 4e 935 3 -5f48 41 936 3 -5f89 f 937 3 -5f98 14 934 3 -5fac 7 941 3 -5fb3 14 942 3 -5fc7 14 943 3 -5fdb 1d 946 3 -5ff8 c 948 3 -6004 24 949 3 -6028 29 950 3 -6051 9 953 3 -605a 28 954 3 -6082 2e 955 3 -60b0 1e 957 3 -60ce 7 959 3 -60d5 26 962 3 -60fb 2a 963 3 -6125 2a 964 3 -614f 6 966 3 -6155 2a 967 3 -617f e 971 3 -618d 43 972 3 -61d0 4c 974 3 -621c 8 975 3 -6224 2e 979 3 -6252 2e 982 3 -6280 2e 985 3 -62ae 2e 988 3 -62dc 2e 991 3 -630a 2e 994 3 -6338 2e 997 3 -6366 2e 1000 3 -6394 54 1004 3 -63e8 c 1005 3 -63f4 e 1007 3 -6402 27 1008 3 -6429 8 1009 3 -6431 34 1010 3 -6465 24 1012 3 -6489 2 1013 3 -648b 2a 1017 3 -64b5 a 1019 3 -64bf 14 1020 3 -64d3 1d 1021 3 -64f0 a 1025 3 -64fa 32 1026 3 -652c 33 1028 3 -655f c 1029 3 -656b 55 1034 3 -65c0 f 1036 3 -65cf 16 1040 3 -65e5 61 1041 3 -6646 f 1043 3 -6655 47 1046 3 -669c c 1048 3 -66a8 11 948 3 -66b9 4e 1052 3 -6707 b 1053 3 -FUNC 6712 11 0 operator new(unsigned long, void*) -6712 c 94 5 -671e 5 94 5 -6723 1 94 5 -FUNC 6724 e 0 operator delete(void*, void*) -6724 c 98 5 -6730 2 98 5 -673e 7 76 6 -6745 2 77 6 -6747 1a 78 6 -6761 d 77 6 -676e 3 79 6 -6771 2 80 6 -6773 1 80 6 -6780 d 95 6 -678d 1 95 6 -678e 13 127 74 -67a1 2a 127 74 -67cb 1 127 74 -67cc 13 127 74 -67df 2a 127 74 -6809 1 127 74 -680a 13 127 74 -681d 2a 127 74 -6847 1 127 74 -FUNC 6848 e 0 dwarf2reader::LineInfoHandler::DefineDir(std::string const&, unsigned int) -6848 c 131 7 -6854 2 131 74 -FUNC 6856 26 0 dwarf2reader::LineInfoHandler::DefineFile(std::string const&, int, unsigned int, unsigned long long, unsigned long long) -6856 24 142 7 -687a 2 142 74 -FUNC 687c 1a 0 dwarf2reader::LineInfoHandler::AddLine(unsigned long long, unsigned int, unsigned int, unsigned int) -687c 18 150 7 -6894 2 150 74 -6896 12 299 74 -68a8 12 299 74 -68ba 13 301 74 -68cd 2a 301 74 -68f7 1 301 74 -68f8 13 301 74 -690b 2a 301 74 -6935 1 301 74 -6936 13 301 74 -6949 2a 301 74 -6973 1 301 74 -FUNC 6974 44 0 dwarf2reader::Dwarf2Handler::StartCompilationUnit(unsigned long long, unsigned char, unsigned char, unsigned long long, unsigned char) -6974 39 308 7 -69ad b 308 74 -FUNC 69b8 1f 0 dwarf2reader::Dwarf2Handler::StartDIE(unsigned long long, dwarf2reader::DwarfTag, std::list, std::allocator > > const&) -69b8 18 314 7 -69d0 7 314 74 -69d7 1 314 74 -FUNC 69d8 26 0 dwarf2reader::Dwarf2Handler::ProcessAttributeUnsigned(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, unsigned long long) -69d8 24 323 7 -69fc 2 323 74 -FUNC 69fe 26 0 dwarf2reader::Dwarf2Handler::ProcessAttributeSigned(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, long long) -69fe 24 332 7 -6a22 2 332 74 -FUNC 6a24 26 0 dwarf2reader::Dwarf2Handler::ProcessAttributeBuffer(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, char const*, unsigned long long) -6a24 24 345 7 -6a48 2 345 74 -FUNC 6a4a 1a 0 dwarf2reader::Dwarf2Handler::ProcessAttributeString(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, std::string const&) -6a4a 18 354 7 -6a62 2 354 74 -FUNC 6a64 1a 0 dwarf2reader::Dwarf2Handler::EndDIE(unsigned long long) -6a64 18 360 7 -6a7c 2 360 74 -6a7e c 44 8 -6a8a 2 44 8 -6a8c 13 55 32 -6a9f 35 55 32 -6ad4 13 91 32 -6ae7 73 96 32 -6b5a 13 98 32 -6b6d 35 98 32 -6bae 1a 75 3 -6bc8 2 76 3 -FUNC 6bca 20 0 std::_Rb_tree_const_iterator >::operator!=(std::_Rb_tree_const_iterator > const&) const -6bca c 287 10 -6bd6 14 288 40 -FUNC 6bea 16 0 std::_Rb_tree_const_iterator >::operator->() const -6bea c 249 10 -6bf6 a 250 40 -6c0c 7 614 72 -6c13 1 614 72 -6c14 c 241 40 -6c20 c 242 40 -FUNC 6c2c 16 0 std::_Rb_tree_const_iterator >::operator*() const -6c2c c 245 11 -6c38 a 246 40 -6c42 c 241 40 -6c4e c 242 40 -FUNC 6c5a 20 0 std::_Rb_tree_const_iterator > >::operator!=(std::_Rb_tree_const_iterator > > const&) const -6c5a c 287 11 -6c66 14 288 40 -FUNC 6c7a 16 0 std::_Rb_tree_const_iterator > >::operator->() const -6c7a c 249 11 -6c86 a 250 40 -6c90 c 185 34 -6c9c 18 186 34 -6cc0 14 204 34 -6cd4 c 69 70 -6ce0 d 69 70 -6ced 1 69 70 -6cee c 89 70 -6cfa 20 90 70 -6d1a c 69 70 -6d26 d 69 70 -6d33 1 69 70 -6d34 c 69 70 -6d40 d 69 70 -6d4d 1 69 70 -FUNC 6d4e 25 0 std::_Rb_tree_const_iterator >::operator++() -6d4e c 253 13 -6d5a 14 255 40 -6d6e 5 256 40 -6d73 1 256 40 -FUNC 6d74 25 0 std::_Rb_tree_const_iterator > >::operator++() -6d74 c 253 13 -6d80 14 255 40 -6d94 5 256 40 -6d99 1 256 40 -FUNC 6d9a 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_begin() -6d9a c 461 13 -6da6 8 462 40 -FUNC 6dae 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_begin() -6dae c 461 13 -6dba 8 462 40 -6dc2 c 65 68 -6dce 2 65 68 -6dd0 c 72 68 -6ddc 2 72 68 -6dde c 97 69 -6dea d 97 69 -6df7 1 97 69 -6df8 c 105 69 -6e04 d 105 69 -6e11 1 105 69 -6e12 c 105 69 -6e1e d 105 69 -6e2b 1 105 69 -6e2c c 67 68 -6e38 2 67 68 -6e3a c 99 69 -6e46 14 100 69 -6e5a c 99 69 -6e66 14 100 69 -FUNC 6e7a 2b 0 std::_Vector_base >::get_allocator() const -6e7a 10 93 16 -6e8a 1b 94 71 -6ea5 1 94 71 -6ea6 c 65 68 -6eb2 2 65 68 -6eb4 c 72 68 -6ec0 2 72 68 -6ec2 c 97 69 -6ece d 97 69 -6edb 1 97 69 -6edc c 105 69 -6ee8 d 105 69 -6ef5 1 105 69 -6ef6 c 105 69 -6f02 d 105 69 -6f0f 1 105 69 -6f10 c 67 68 -6f1c 2 67 68 -6f1e c 99 69 -6f2a 14 100 69 -6f3e c 99 69 -6f4a 14 100 69 -FUNC 6f5e 2b 0 std::_Vector_base >::get_allocator() const -6f5e 10 93 16 -6f6e 1b 94 71 -6f89 1 94 71 -6f8a c 603 72 -6f96 c 603 72 -FUNC 6fa2 23 0 std::vector >::begin() -6fa2 c 333 16 -6fae 17 334 71 -6fc5 1 334 71 -FUNC 6fc6 26 0 std::vector >::end() -6fc6 c 351 16 -6fd2 1a 352 71 -6ff8 5 666 72 -6ffd 1 666 72 -6ffe c 608 72 -700a 14 609 72 -702a 5 666 72 -702f 1 666 72 -FUNC 7030 35 0 bool __gnu_cxx::operator!= > >(__gnu_cxx::__normal_iterator > > const&, __gnu_cxx::__normal_iterator > > const&) -7030 d 693 16 -703d 28 694 72 -7065 1 694 72 -7066 c 603 72 -7072 c 603 72 -708a 27 629 72 -70b1 1 629 72 -70b2 c 84 70 -70be 1f 85 70 -70dd 1 85 70 -FUNC 70de 32 0 std::pair, __gnu_cxx::hash, std::equal_to, std::allocator > >*> std::make_pair, __gnu_cxx::hash, std::equal_to, std::allocator > >*>(std::string, __gnu_cxx::hash_map, __gnu_cxx::hash, std::equal_to, std::allocator > >*) -70de 10 144 16 -70ee 22 145 70 -711c a 190 34 -7132 d 194 34 -713f 1 194 34 -7140 c 84 70 -714c 17 85 70 -7163 1 85 70 -FUNC 7164 2d 0 std::pair std::make_pair(char const*, unsigned long) -7164 c 144 16 -7170 21 145 70 -7191 1 145 70 -7192 c 84 70 -719e 1d 85 70 -71bb 1 85 70 -FUNC 71bc 30 0 std::pair > std::make_pair >(char*, std::pair) -71bc 10 144 16 -71cc 20 145 70 -71ec c 89 70 -71f8 20 90 70 -7218 d 89 70 -7225 70 90 70 -7295 1 90 70 -FUNC 7296 12 0 std::iterator_traits::iterator_category std::__iterator_category(unsigned long const* const&) -7296 c 164 17 -72a2 6 165 17 -FUNC 72a8 1d 0 std::iterator_traits::difference_type std::__distance(unsigned long const*, unsigned long const*, std::random_access_iterator_tag) -72a8 c 92 18 -72b4 11 97 18 -72c5 1 97 18 -FUNC 72c6 33 0 std::iterator_traits::difference_type std::distance(unsigned long const*, unsigned long const*) -72c6 c 114 18 -72d2 27 118 18 -72f9 1 118 18 -FUNC 72fa 20 0 void std::__advance(unsigned long const*&, int, std::random_access_iterator_tag) -72fa c 150 18 -7306 14 155 18 -FUNC 731a 33 0 void std::advance(unsigned long const*&, int) -731a c 172 18 -7326 27 175 18 -734d 1 175 18 -FUNC 734e 7a 0 unsigned long const* std::lower_bound(unsigned long const*, unsigned long const*, unsigned long const&) -734e c 2625 19 -735a 15 2642 19 -736f 2 2646 19 -7371 8 2648 19 -7379 6 2649 19 -737f 12 2650 19 -7391 e 2651 19 -739f 6 2653 19 -73a5 4 2654 19 -73a9 e 2655 19 -73b7 6 2658 19 -73bd 6 2646 19 -73c3 5 2660 19 -73db b 227 34 -73e6 e 228 34 -73f4 1c 229 34 -7410 20 230 34 -7430 6 231 34 -7436 c 72 68 -7442 2 72 68 -7444 c 105 69 -7450 d 105 69 -745d 1 105 69 -745e c 105 69 -746a d 105 69 -7477 1 105 69 -7478 c 80 71 -7484 d 80 71 -7491 1 80 71 -7492 c 67 68 -749e 2 67 68 -74a0 c 99 69 -74ac 14 100 69 -FUNC 74c0 2b 0 std::_Vector_base >::get_allocator() const -74c0 10 93 19 -74d0 1b 94 71 -74eb 1 94 71 -74ec c 238 40 -74f8 a 239 40 -FUNC 7502 26 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::begin() const -7502 c 585 19 -750e 1a 588 40 -FUNC 7528 19 0 std::map, std::allocator > >::begin() const -7528 c 243 20 -7534 d 244 45 -7541 1 244 45 -FUNC 7542 26 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::end() const -7542 c 596 20 -754e 1a 597 40 -FUNC 7568 19 0 std::map, std::allocator > >::end() const -7568 c 260 20 -7574 d 261 45 -7581 1 261 45 -7582 c 65 68 -758e 2 65 68 -7590 c 72 68 -759c 2 72 68 -759e c 97 69 -75aa d 97 69 -75b7 1 97 69 -75b8 c 105 69 -75c4 d 105 69 -75d1 1 105 69 -75d2 c 72 68 -75de 2 72 68 -75e0 c 105 69 -75ec d 105 69 -75f9 1 105 69 -75fa c 397 40 -7606 d 397 40 -7613 1 397 40 -7614 c 105 69 -7620 d 105 69 -762d 1 105 69 -FUNC 762e 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_right(std::_Rb_tree_node_base*) -762e c 496 20 -763a 8 497 40 -FUNC 7642 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_left(std::_Rb_tree_node_base*) -7642 c 488 20 -764e 8 489 40 -7656 c 65 68 -7662 2 65 68 -7664 c 72 68 -7670 2 72 68 -7672 c 97 69 -767e d 97 69 -768b 1 97 69 -768c c 105 69 -7698 d 105 69 -76a5 1 105 69 -76a6 c 72 68 -76b2 2 72 68 -76b4 c 105 69 -76c0 d 105 69 -76cd 1 105 69 -76ce c 397 40 -76da d 397 40 -76e7 1 397 40 -76e8 c 105 69 -76f4 d 105 69 -7701 1 105 69 -FUNC 7702 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_right(std::_Rb_tree_node_base*) -7702 c 496 20 -770e 8 497 40 -FUNC 7716 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_left(std::_Rb_tree_node_base*) -7716 c 488 20 -7722 8 489 40 -772a c 84 71 -7736 2f 85 71 -7765 2 86 71 -7767 1 86 71 -7768 c 80 71 -7774 d 80 71 -7781 1 80 71 -7782 c 96 71 -778e 12 97 71 -77a0 2 98 71 -77a2 c 84 71 -77ae 2f 85 71 -77dd 2 86 71 -77df 1 86 71 -77e0 c 80 71 -77ec d 80 71 -77f9 1 80 71 -77fa c 96 71 -7806 12 97 71 -7818 2 98 71 -7826 d 107 68 -7833 1 107 68 -FUNC 7834 2e 0 void std::_Destroy >(std::string*, std::string*, std::allocator) -7834 c 171 21 -7840 2 173 73 -7842 12 174 73 -7854 c 173 73 -7860 2 174 73 -7862 c 167 40 -786e a 168 40 -FUNC 7878 26 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::begin() -7878 c 581 21 -7884 1a 582 40 -FUNC 789e 19 0 std::map, std::allocator > >::begin() -789e c 234 21 -78aa d 235 45 -78b7 1 235 45 -FUNC 78b8 26 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::end() -78b8 c 592 21 -78c4 1a 593 40 -FUNC 78de 19 0 std::map, std::allocator > >::end() -78de c 251 21 -78ea d 252 45 -78f7 1 252 45 -78f8 c 167 40 -7904 a 168 40 -FUNC 790e 26 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::begin() -790e c 581 21 -791a 1a 582 40 -FUNC 7934 19 0 std::map, std::less, std::allocator > > >::begin() -7934 c 234 21 -7940 d 235 45 -794d 1 235 45 -FUNC 794e 26 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::end() -794e c 592 21 -795a 1a 593 40 -FUNC 7974 19 0 std::map, std::less, std::allocator > > >::end() -7974 c 251 21 -7980 d 252 45 -798d 1 252 45 -FUNC 798e 11 0 std::_Select1st, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >::operator()(std::pair, __gnu_cxx::hash, std::equal_to, std::allocator > >*>&) const -798e c 546 22 -799a 5 547 41 -799f 1 547 41 -79a0 c 128 34 -79ac 13 129 34 -79bf 1 129 34 -79cc 22 396 34 -79fa d 199 42 -7a07 1 199 42 -7a08 c 65 68 -7a14 2 65 68 -7a16 c 72 68 -7a22 2 72 68 -7a24 c 97 69 -7a30 d 97 69 -7a3d 1 97 69 -7a3e c 105 69 -7a4a d 105 69 -7a57 1 105 69 -7a58 c 65 68 -7a64 2 65 68 -7a66 c 72 68 -7a72 2 72 68 -7a74 c 105 69 -7a80 d 105 69 -7a8d 1 105 69 -7a8e c 97 69 -7a9a d 97 69 -7aa7 1 97 69 -7aa8 c 72 68 -7ab4 2 72 68 -7ab6 c 105 69 -7ac2 d 105 69 -7acf 1 105 69 -7adc d 94 68 -7ae9 1 94 68 -FUNC 7aea 2f 0 std::_Vector_base >::_M_deallocate(dwarf2reader::CompilationUnit::Abbrev*, unsigned long) -7aea c 120 23 -7af6 6 122 71 -7afc 1d 123 71 -7b19 1 123 71 -7b1a c 108 71 -7b26 43 109 71 -7b69 1 109 71 -7b6a c 65 68 -7b76 2 65 68 -7b78 c 103 69 -7b84 d 103 69 -7b91 1 103 69 -7b92 c 65 68 -7b9e 2 65 68 -7ba0 c 103 69 -7bac d 103 69 -7bb9 1 103 69 -7bc6 d 94 68 -7bd3 1 94 68 -FUNC 7bd4 2f 0 std::_Vector_base >::_M_deallocate(dwarf2reader::SourceFileInfo*, unsigned long) -7bd4 c 120 23 -7be0 6 122 71 -7be6 1d 123 71 -7c03 1 123 71 -7c04 c 108 71 -7c10 43 109 71 -7c53 1 109 71 -7c54 c 188 71 -7c60 12 189 71 -7c72 2 190 71 -7c74 c 35 32 -7c80 d 35 32 -7c8d 1 35 32 -7c9a d 107 68 -7ca7 1 107 68 -FUNC 7ca8 2e 0 void std::_Destroy >(dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo*, std::allocator) -7ca8 c 171 23 -7cb4 2 173 73 -7cb6 12 174 73 -7cc8 c 173 73 -7cd4 2 174 73 -7cd6 d 272 71 -7ce3 8c 273 71 -7d6f 1 273 71 -7d7c d 94 68 -7d89 1 94 68 -FUNC 7d8a 2f 0 std::_Vector_base >::_M_deallocate(std::string*, unsigned long) -7d8a c 120 23 -7d96 6 122 71 -7d9c 1d 123 71 -7db9 1 123 71 -7dba c 108 71 -7dc6 3d 109 71 -7e03 1 109 71 -7e04 c 188 71 -7e10 12 189 71 -7e22 2 190 71 -7e24 d 272 71 -7e31 8c 273 71 -7ebd 1 273 71 -7eca 2b 596 34 -7ef5 1 596 34 -7f02 7 614 72 -7f09 1 614 72 -7f0a c 65 68 -7f16 2 65 68 -7f18 c 72 68 -7f24 2 72 68 -7f26 c 103 69 -7f32 d 103 69 -7f3f 1 103 69 -7f40 c 105 69 -7f4c d 105 69 -7f59 1 105 69 -7f5a c 65 68 -7f66 2 65 68 -7f68 c 72 68 -7f74 2 72 68 -7f76 c 103 69 -7f82 d 103 69 -7f8f 1 103 69 -7f90 c 105 69 -7f9c d 105 69 -7fa9 1 105 69 -7faa c 105 69 -7fb6 d 105 69 -7fc3 1 105 69 -7fd0 d 575 34 -7fdd 1 575 34 -7fea d 575 34 -7ff7 1 575 34 -FUNC 7ff8 11 0 std::_Select1st, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >::operator()(std::pair, __gnu_cxx::hash, std::equal_to, std::allocator > >*> const&) const -7ff8 c 550 23 -8004 5 551 41 -8009 1 551 41 -8016 2f 600 34 -8045 1 600 34 -8046 c 84 70 -8052 1e 85 70 -FUNC 8070 11 0 std::_Select1st > >::operator()(std::pair >&) const -8070 c 546 23 -807c 5 547 41 -8081 1 547 41 -FUNC 8082 11 0 std::_Select1st > >::operator()(std::pair > const&) const -8082 c 550 23 -808e 5 551 41 -8093 1 551 41 -8094 c 128 34 -80a0 13 129 34 -80b3 1 129 34 -80b4 c 84 70 -80c0 1e 85 70 -80de c 65 68 -80ea 2 65 68 -80ec c 103 69 -80f8 d 103 69 -8105 1 103 69 -8106 c 65 68 -8112 2 65 68 -8114 c 72 68 -8120 2 72 68 -8122 c 105 69 -812e d 105 69 -813b 1 105 69 -813c c 103 69 -8148 d 103 69 -8155 1 103 69 -8156 c 105 69 -8162 d 105 69 -816f 1 105 69 -8170 c 80 71 -817c d 80 71 -8189 1 80 71 -818a c 67 68 -8196 2 67 68 -8198 c 99 69 -81a4 14 100 69 -FUNC 81b8 2b 0 std::_Vector_base<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::get_allocator() const -81b8 10 93 23 -81c8 1b 94 71 -81e3 1 94 71 -81e4 c 99 69 -81f0 14 100 69 -8210 2 107 68 -FUNC 8212 2e 0 void std::_Destroy<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>) -8212 c 171 23 -821e 2 173 73 -8220 12 174 73 -8232 c 173 73 -823e 2 174 73 -824c d 107 68 -8259 1 107 68 -825a c 67 68 -8266 2 67 68 -8268 c 99 69 -8274 14 100 69 -8288 c 403 40 -8294 1c 404 40 -82b0 a 406 40 -82ba a 407 40 -82c4 c 408 40 -82d0 e 409 40 -82de c 553 40 -82ea 36 554 40 -8320 2 555 40 -8322 c 103 69 -832e d 103 69 -833b 1 103 69 -FUNC 833c 2b 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::get_allocator() const -833c 10 350 23 -834c 1b 351 40 -8367 1 351 40 -8368 c 69 70 -8374 2 69 70 -8382 d 107 68 -838f 1 107 68 -839c d 94 68 -83a9 1 94 68 -FUNC 83aa 2a 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_put_node(std::_Rb_tree_node >*) -83aa c 359 23 -83b6 1e 360 40 -FUNC 83d4 59 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::destroy_node(std::_Rb_tree_node >*) -83d4 d 387 23 -83e1 35 389 40 -8416 17 390 40 -842d 1 390 40 -FUNC 842e 56 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_erase(std::_Rb_tree_node >*) -842e c 1051 23 -843a 2 1054 40 -843c 1a 1056 40 -8456 e 1057 40 -8464 12 1058 40 -8476 6 1059 40 -847c 6 1054 40 -8482 2 1059 40 -8484 d 569 40 -8491 58 570 40 -84e9 1 570 40 -84ea c 147 45 -84f6 31 148 45 -8527 1 148 45 -8528 c 92 45 -8534 d 92 45 -8541 1 92 45 -8542 c 67 68 -854e 2 67 68 -8550 c 99 69 -855c 14 100 69 -8570 c 403 40 -857c 1c 404 40 -8598 a 406 40 -85a2 a 407 40 -85ac c 408 40 -85b8 e 409 40 -85c6 c 553 40 -85d2 36 554 40 -8608 2 555 40 -860a c 103 69 -8616 d 103 69 -8623 1 103 69 -FUNC 8624 2b 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::get_allocator() const -8624 10 350 23 -8634 1b 351 40 -864f 1 351 40 -8650 c 69 70 -865c d 69 70 -8669 1 69 70 -866a c 69 70 -8676 30 69 70 -86b2 d 107 68 -86bf 1 107 68 -86cc d 94 68 -86d9 1 94 68 -FUNC 86da 2a 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_put_node(std::_Rb_tree_node > >*) -86da c 359 23 -86e6 1e 360 40 -FUNC 8704 59 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::destroy_node(std::_Rb_tree_node > >*) -8704 d 387 23 -8711 35 389 40 -8746 17 390 40 -875d 1 390 40 -FUNC 875e 56 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_erase(std::_Rb_tree_node > >*) -875e c 1051 23 -876a 2 1054 40 -876c 1a 1056 40 -8786 e 1057 40 -8794 12 1058 40 -87a6 6 1059 40 -87ac 6 1054 40 -87b2 2 1059 40 -87b4 d 569 40 -87c1 58 570 40 -8819 1 570 40 -881a c 147 45 -8826 31 148 45 -8857 1 148 45 -8858 c 92 45 -8864 d 92 45 -8871 1 92 45 -8872 c 603 72 -887e c 603 72 -FUNC 888a 23 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::begin() -888a c 333 23 -8896 17 334 71 -88ad 1 334 71 -88ba 2a 654 72 -FUNC 88e4 42 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::operator[](unsigned long) -88e4 c 494 23 -88f0 36 495 71 -FUNC 8926 26 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::end() -8926 c 351 23 -8932 1a 352 71 -FUNC 894c 28 0 bool std::operator==, std::allocator >(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&) -894c c 2115 24 -8958 1c 2116 37 -FUNC 8974 23 0 std::equal_to::operator()(std::string const&, std::string const&) const -8974 c 199 24 -8980 17 200 41 -8997 1 200 41 -8998 c 80 71 -89a4 d 80 71 -89b1 1 80 71 -89b2 c 67 68 -89be 2 67 68 -89c0 c 99 69 -89cc 14 100 69 -FUNC 89e0 2b 0 std::_Vector_base<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::get_allocator() const -89e0 10 93 24 -89f0 1b 94 71 -8a0b 1 94 71 -8a0c c 99 69 -8a18 14 100 69 -8a2c c 84 71 -8a38 2f 85 71 -8a67 2 86 71 -8a69 1 86 71 -8a6a c 96 71 -8a76 12 97 71 -8a88 2 98 71 -8a96 2 107 68 -FUNC 8a98 2e 0 void std::_Destroy<__gnu_cxx::_Hashtable_node > >**, std::allocator<__gnu_cxx::_Hashtable_node > >*> >(__gnu_cxx::_Hashtable_node > >**, __gnu_cxx::_Hashtable_node > >**, std::allocator<__gnu_cxx::_Hashtable_node > >*>) -8a98 c 171 24 -8aa4 2 173 73 -8aa6 12 174 73 -8ab8 c 173 73 -8ac4 2 174 73 -FUNC 8ac6 13 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::max_size() const -8ac6 c 407 24 -8ad2 7 408 71 -8ad9 1 408 71 -8ada c 603 72 -8ae6 c 603 72 -FUNC 8af2 26 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::end() -8af2 c 351 24 -8afe 1a 352 71 -FUNC 8b18 23 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::begin() -8b18 c 333 24 -8b24 17 334 71 -8b3b 1 334 71 -8b48 2a 654 72 -8b7e 7 614 72 -8b85 1 614 72 -FUNC 8b86 42 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::operator[](unsigned long) -8b86 c 494 24 -8b92 36 495 71 -8bd4 d 107 68 -8be1 1 107 68 -FUNC 8be2 28 0 void std::swap<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**>(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**&, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**&) -8be2 c 92 25 -8bee 8 97 61 -8bf6 a 98 61 -8c00 a 99 61 -FUNC 8c0a 50 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::swap(std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >&) -8c0a c 733 25 -8c16 12 735 71 -8c28 18 736 71 -8c40 1a 737 71 -8c66 2b 596 34 -8c91 1 596 34 -8c9e 2f 600 34 -8ccd 1 600 34 -FUNC 8cce 28 0 void std::swap<__gnu_cxx::_Hashtable_node > >**>(__gnu_cxx::_Hashtable_node > >**&, __gnu_cxx::_Hashtable_node > >**&) -8cce c 92 25 -8cda 8 97 61 -8ce2 a 98 61 -8cec a 99 61 -FUNC 8cf6 50 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::swap(std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >&) -8cf6 c 733 25 -8d02 12 735 71 -8d14 18 736 71 -8d2c 1a 737 71 -8d46 c 84 71 -8d52 2f 85 71 -8d81 2 86 71 -8d83 1 86 71 -8d84 c 96 71 -8d90 12 97 71 -8da2 2 98 71 -FUNC 8da4 13 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::max_size() const -8da4 c 407 25 -8db0 7 408 71 -8db7 1 408 71 -8dc4 d 94 68 -8dd1 1 94 68 -FUNC 8dd2 2f 0 std::_Vector_base<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::_M_deallocate(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long) -8dd2 c 120 25 -8dde 6 122 71 -8de4 1d 123 71 -8e01 1 123 71 -8e02 c 108 71 -8e0e 3d 109 71 -8e4b 1 109 71 -8e4c c 272 71 -8e58 4b 273 71 -8ea3 1 273 71 -8ea4 c 188 71 -8eb0 12 189 71 -8ec2 2 190 71 -8ec4 c 603 72 -8ed0 c 603 72 -FUNC 8edc 2b 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::begin() const -8edc c 342 25 -8ee8 1f 343 71 -8f07 1 343 71 -FUNC 8f08 2c 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::end() const -8f08 c 360 25 -8f14 20 361 71 -8f40 5 666 72 -8f45 1 666 72 -8f53 2b 759 72 -FUNC 8f7e 3c 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::size() const -8f7e c 402 25 -8f8a 30 403 71 -8fc6 26 588 34 -8ff8 15 511 34 -900d 79 513 34 -9086 21 517 34 -90a7 1 517 34 -90b4 14 225 42 -90d4 26 592 34 -FUNC 90fa 49 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::capacity() const -90fa c 449 25 -9106 3d 451 71 -9143 1 451 71 -9144 c 103 69 -9150 d 103 69 -915d 1 103 69 -916e 1b 286 34 -9189 1 286 34 -9196 d 94 68 -91a3 1 94 68 -91b0 1e 301 34 -91db 56 622 34 -9231 17 623 34 -9254 9 1080 34 -925d 1a 1082 34 -9277 2 1083 34 -9279 8 1085 34 -9281 12 1086 34 -9293 6 1087 34 -9299 6 1083 34 -929f 1b 1089 34 -92ba 1d 1080 34 -92d7 c 1091 34 -92e3 1 1091 34 -92e4 d 360 34 -92f1 77 361 34 -9368 c 93 42 -9374 d 93 42 -9381 1 93 42 -9382 c 72 68 -938e 2 72 68 -9390 c 105 69 -939c d 105 69 -93a9 1 105 69 -93aa c 301 66 -93b6 d 301 66 -93c3 1 301 66 -93d0 d 94 68 -93dd 1 94 68 -FUNC 93de 2f 0 std::_Vector_base<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::_M_deallocate(__gnu_cxx::_Hashtable_node > >**, unsigned long) -93de c 120 26 -93ea 6 122 71 -93f0 1d 123 71 -940d 1 123 71 -940e c 108 71 -941a 3d 109 71 -9457 1 109 71 -9458 c 188 71 -9464 12 189 71 -9476 2 190 71 -9478 c 272 71 -9484 4b 273 71 -94cf 1 273 71 -94d0 c 603 72 -94dc c 603 72 -FUNC 94e8 2b 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::begin() const -94e8 c 342 26 -94f4 1f 343 71 -9513 1 343 71 -FUNC 9514 2c 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::end() const -9514 c 360 26 -9520 20 361 71 -954c 2d 662 72 -9579 1 662 72 -FUNC 957a 2d 0 unsigned long const& std::max(unsigned long const&, unsigned long const&) -957a c 206 26 -9586 e 211 61 -9594 8 212 61 -959c b 213 61 -95a7 1 213 61 -95b4 19 650 72 -95cd 1 650 72 -95da 5 666 72 -95df 1 666 72 -95ed 2b 759 72 -9624 5 666 72 -9629 1 666 72 -9637 2b 759 72 -FUNC 9662 49 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::capacity() const -9662 c 449 26 -966e 3d 451 71 -96ab 1 451 71 -FUNC 96ac 3c 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::size() const -96ac c 402 26 -96b8 30 403 71 -96f4 26 588 34 -9726 26 592 34 -974c c 103 69 -9758 d 103 69 -9765 1 103 69 -9776 1b 286 34 -9791 1 286 34 -979e d 94 68 -97ab 1 94 68 -97b8 1e 301 34 -97e3 56 622 34 -9839 17 623 34 -985c 9 1080 34 -9865 1a 1082 34 -987f 2 1083 34 -9881 8 1085 34 -9889 12 1086 34 -989b 6 1087 34 -98a1 6 1083 34 -98a7 1b 1089 34 -98c2 1d 1080 34 -98df c 1091 34 -98eb 1 1091 34 -98ec d 360 34 -98f9 77 361 34 -9970 c 69 70 -997c 20 69 70 -99a9 5c 104 68 -9a05 1 104 68 -9a06 c 69 70 -9a12 2c 69 70 -9a4b 5c 104 68 -9aa7 1 104 68 -9ab4 2d 662 72 -9ae1 1 662 72 -9aee 19 650 72 -9b07 1 650 72 -9b14 5 666 72 -9b19 1 666 72 -9b27 2b 759 72 -9b52 c 72 68 -9b5e 2 72 68 -9b60 c 105 69 -9b6c d 105 69 -9b79 1 105 69 -9b7a c 69 70 -9b86 2 69 70 -9b94 d 107 68 -9ba1 1 107 68 -9bae d 94 68 -9bbb 1 94 68 -FUNC 9bbc 2a 0 std::_List_base, std::allocator > >::_M_put_node(std::_List_node >*) -9bbc c 315 26 -9bc8 1e 316 66 -FUNC 9be6 35 0 bool __gnu_cxx::operator!=<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > > const&, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > > const&) -9be6 d 699 26 -9bf3 28 700 72 -9c1b 1 700 72 -9c28 d 623 72 -9c35 5 624 72 -FUNC 9c3a 4b 0 void std::__fill::fill<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::_Hashtable_node > >* const&) -9c3a c 539 61 -9c46 8 541 61 -9c4e 2 542 61 -9c50 12 543 61 -9c62 21 542 61 -9c83 2 543 61 -9c85 1 543 61 -FUNC 9c86 2b 0 void std::fill<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::_Hashtable_node > >* const&) -9c86 c 560 26 -9c92 4 567 61 -9c96 1b 568 61 -9cb1 1 568 61 -FUNC 9cb2 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, std::allocator<__gnu_cxx::_Hashtable_node > >*> >(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, std::allocator<__gnu_cxx::_Hashtable_node > >*>) -9cb2 c 171 26 -9cbe 2 173 73 -9cc0 1a 174 73 -9cda 21 173 73 -9cfb 2 174 73 -9cfd 1 174 73 -9d0a 7 98 68 -9d11 1 98 68 -9d1e 1d 85 68 -9d3b 5 86 68 -9d40 16 88 68 -9d62 1d 297 34 -9d7f 1 297 34 -9d8d e 605 34 -9d9b 9 606 34 -9da4 3c 609 34 -9de0 b 610 34 -9deb 11 609 34 -9dfc b 612 34 -9e07 12 614 34 -9e19 b 615 34 -9e24 13 612 34 -9e37 8 615 34 -9e3f 1 615 34 -9e4d 15 751 34 -9e62 1a 752 34 -9e7c b 754 34 -9e87 49 755 34 -9ed0 3b 756 34 -9f0b 12 754 34 -9f1d 15 758 34 -9f32 8 759 34 -9f3a 1c 760 34 -9f56 f 761 34 -9f65 41 762 34 -9fb2 7 98 68 -9fb9 1 98 68 -9fc6 1d 85 68 -9fe3 5 86 68 -9fe8 17 88 68 -9fff 1 88 68 -a00c 1d 297 34 -a029 1 297 34 -a037 e 605 34 -a045 9 606 34 -a04e 3c 609 34 -a08a b 610 34 -a095 11 609 34 -a0a6 b 612 34 -a0b1 12 614 34 -a0c3 b 615 34 -a0ce 13 612 34 -a0e1 8 615 34 -a0e9 1 615 34 -a0f7 15 751 34 -a10c 1a 752 34 -a126 b 754 34 -a131 49 755 34 -a17a 3b 756 34 -a1b5 12 754 34 -a1c7 15 758 34 -a1dc 8 759 34 -a1e4 1c 760 34 -a200 f 761 34 -a20f 41 762 34 -FUNC a250 35 0 bool __gnu_cxx::operator!=<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > > const&, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > > const&) -a250 d 699 26 -a25d 28 700 72 -a285 1 700 72 -a292 d 623 72 -a29f 5 624 72 -FUNC a2a4 4b 0 void std::__fill::fill<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -a2a4 c 539 61 -a2b0 8 541 61 -a2b8 2 542 61 -a2ba 12 543 61 -a2cc 21 542 61 -a2ed 2 543 61 -a2ef 1 543 61 -FUNC a2f0 2b 0 void std::fill<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -a2f0 c 560 26 -a2fc 4 567 61 -a300 1b 568 61 -a31b 1 568 61 -FUNC a31c 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, __gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>) -a31c c 171 26 -a328 2 173 73 -a32a 1a 174 73 -a344 21 173 73 -a365 2 174 73 -a367 1 174 73 -a368 c 65 68 -a374 2 65 68 -a376 c 103 69 -a382 d 103 69 -a38f 1 103 69 -FUNC a390 2b 0 std::_List_base, std::allocator > >::get_allocator() const -a390 10 322 26 -a3a0 1b 324 66 -a3bb 1 324 66 -FUNC a3bc 7b 0 std::_List_base, std::allocator > >::_M_clear() -a3bc d 69 27 -a3c9 8 72 77 -a3d1 2 73 77 -a3d3 6 75 77 -a3d9 8 76 77 -a3e1 35 77 77 -a416 12 78 77 -a428 a 73 77 -a432 5 78 77 -a437 1 78 77 -a438 c 331 66 -a444 18 332 66 -a45c c 392 66 -a468 d 392 66 -a475 1 392 66 -a476 c 211 74 -a482 10 211 74 -a49e d 107 68 -a4ab 1 107 68 -FUNC a4ac 2e 0 void std::_Destroy >(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, std::allocator) -a4ac c 171 27 -a4b8 2 173 73 -a4ba 12 174 73 -a4cc c 173 73 -a4d8 2 174 73 -a4da c 272 71 -a4e6 4b 273 71 -a531 1 273 71 -a532 13 196 74 -a545 10 196 74 -a555 2f 197 74 -a584 1a 198 74 -a59e 13 196 74 -a5b1 10 196 74 -a5c1 2f 197 74 -a5f0 1a 198 74 -a616 7 98 68 -a61d 1 98 68 -a62a 1d 85 68 -a647 5 86 68 -a64c 10 88 68 -FUNC a65c 2a 0 std::_Vector_base<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::_M_allocate(unsigned long) -a65c c 116 27 -a668 1e 117 71 -a686 d 100 71 -a693 12 101 71 -a6a5 19 103 71 -a6be b 104 71 -a6c9 3a 105 71 -a703 1 105 71 -a710 7 98 68 -a717 1 98 68 -a724 1d 85 68 -a741 5 86 68 -a746 10 88 68 -FUNC a756 2a 0 std::_Vector_base<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::_M_allocate(unsigned long) -a756 c 116 27 -a762 1e 117 71 -a780 d 100 71 -a78d 12 101 71 -a79f 19 103 71 -a7b8 b 104 71 -a7c3 3a 105 71 -a7fd 1 105 71 -a80b 12 424 61 -a81d 2e 425 61 -a84b 13 426 61 -a86a 4 440 61 -a86e 1b 443 61 -a889 1 443 61 -a898 56 482 61 -a8fa 4 514 61 -a8fe 4 515 61 -a902 1b 517 61 -a91d 1 517 61 -a92a 8 616 61 -a932 2 617 61 -a934 8 618 61 -a93c f 617 61 -a94b 5 619 61 -a95c 4 641 61 -a960 1b 642 61 -a97b 1 642 61 -FUNC a97c 27 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&, __true_type) -a97c c 182 28 -a988 1b 183 79 -a9a3 1 183 79 -FUNC a9a4 2f 0 void std::uninitialized_fill_n<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -a9a4 c 214 28 -a9b0 23 218 79 -a9d3 1 218 79 -FUNC a9d4 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>) -a9d4 c 308 28 -a9e0 1b 310 79 -a9fb 1 310 79 -a9fc c 200 71 -aa08 19 201 71 -aa21 42 203 71 -aa63 15 205 71 -aa85 11 992 34 -aa96 c 993 34 -aaa2 15 995 34 -aab7 c 996 34 -aac3 4a 998 34 -ab0d f 1001 34 -ab1c 1c 998 34 -ab38 1a 1003 34 -ab52 5 1004 34 -ab57 1f 1007 34 -ab76 1c 1008 34 -ab92 19 1009 34 -abab 19 1010 34 -abc4 1a 1011 34 -abde a 1004 34 -abe8 11 1001 34 -abf9 15 1014 34 -ac0e 13 1028 34 -ac21 b 1016 34 -ac2c 9 1018 34 -ac35 19 1023 34 -ac4e 23 1024 34 -ac71 19 1025 34 -ac8a 1d 1021 34 -aca7 1a 1018 34 -acc1 b 1028 34 -accc b 1016 34 -acd7 1e 1028 34 -acf5 1 1028 34 -ad06 16 438 34 -ad1c 37 439 34 -ad53 1 439 34 -ad64 37 212 42 -ad9b 1 212 42 -ada8 8 616 61 -adb0 2 617 61 -adb2 8 618 61 -adba f 617 61 -adc9 5 619 61 -adda 4 641 61 -adde 1b 642 61 -adf9 1 642 61 -FUNC adfa 27 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >* const&, __true_type) -adfa c 182 28 -ae06 1b 183 79 -ae21 1 183 79 -FUNC ae22 2f 0 void std::uninitialized_fill_n<__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >* const&) -ae22 c 214 28 -ae2e 23 218 79 -ae51 1 218 79 -FUNC ae52 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >*, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::_Hashtable_node > >**, unsigned long, __gnu_cxx::_Hashtable_node > >* const&, std::allocator<__gnu_cxx::_Hashtable_node > >*>) -ae52 c 308 28 -ae5e 1b 310 79 -ae79 1 310 79 -ae7a c 200 71 -ae86 19 201 71 -ae9f 42 203 71 -aee1 15 205 71 -af03 11 992 34 -af14 c 993 34 -af20 15 995 34 -af35 c 996 34 -af41 4a 998 34 -af8b f 1001 34 -af9a 1c 998 34 -afb6 1a 1003 34 -afd0 5 1004 34 -afd5 1f 1007 34 -aff4 1c 1008 34 -b010 19 1009 34 -b029 19 1010 34 -b042 1a 1011 34 -b05c a 1004 34 -b066 11 1001 34 -b077 15 1014 34 -b08c 13 1028 34 -b09f b 1016 34 -b0aa 9 1018 34 -b0b3 19 1023 34 -b0cc 23 1024 34 -b0ef 19 1025 34 -b108 1d 1021 34 -b125 1a 1018 34 -b13f b 1028 34 -b14a b 1016 34 -b155 1e 1028 34 -b173 1 1028 34 -b184 16 438 34 -b19a 37 439 34 -b1d1 1 439 34 -b1e2 37 212 42 -b219 1 212 42 -b227 12 424 61 -b239 2e 425 61 -b267 13 426 61 -b286 4 440 61 -b28a 1b 443 61 -b2a5 1 443 61 -b2b4 56 482 61 -b316 4 514 61 -b31a 4 515 61 -b31e 1b 517 61 -b339 1 517 61 -b346 8 616 61 -b34e 2 617 61 -b350 12 618 61 -b362 16 617 61 -b378 5 619 61 -b37d 1 619 61 -b38a 4 641 61 -b38e 1b 642 61 -b3a9 1 642 61 -FUNC b3aa 27 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >* const&, __true_type) -b3aa c 182 28 -b3b6 1b 183 79 -b3d1 1 183 79 -FUNC b3d2 2f 0 void std::uninitialized_fill_n<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >* const&) -b3d2 c 214 28 -b3de 23 218 79 -b401 1 218 79 -FUNC b402 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >*, __gnu_cxx::_Hashtable_node > >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >* const&, std::allocator<__gnu_cxx::_Hashtable_node > >*>) -b402 c 308 28 -b40e 1b 310 79 -b429 1 310 79 -b436 8 616 61 -b43e 2 617 61 -b440 12 618 61 -b452 16 617 61 -b468 5 619 61 -b46d 1 619 61 -b47a 4 641 61 -b47e 1b 642 61 -b499 1 642 61 -FUNC b49a 27 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&, __true_type) -b49a c 182 28 -b4a6 1b 183 79 -b4c1 1 183 79 -FUNC b4c2 2f 0 void std::uninitialized_fill_n<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -b4c2 c 214 28 -b4ce 23 218 79 -b4f1 1 218 79 -FUNC b4f2 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*>) -b4f2 c 308 28 -b4fe 1b 310 79 -b519 1 310 79 -b526 22 300 61 -b548 11 301 61 -b559 1 301 61 -b566 4 315 61 -b56a 1b 317 61 -b585 1 317 61 -b592 1b 326 61 -b5ad 1 326 61 -b5ba 4 384 61 -b5be 4 385 61 -b5c2 1b 387 61 -b5dd 1 387 61 -b5ea 1b 74 79 -b605 1 74 79 -b612 23 113 79 -b635 1 113 79 -b642 1b 254 79 -b65d 1 254 79 -b66a 15 763 71 -b67f 40 766 71 -b6bf 3 768 71 -b6c2 2 773 71 -FUNC b6c4 124 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::reserve(unsigned long) -b6c4 13 69 29 -b6d7 15 71 78 -b6ec e 72 78 -b6fa 19 73 78 -b713 e 75 78 -b721 28 78 78 -b749 3e 79 78 -b787 30 81 78 -b7b7 8 84 78 -b7bf 11 85 78 -b7d0 18 86 78 -b7f5 33 335 61 -b834 4 384 61 -b838 4 385 61 -b83c 1b 387 61 -b857 1 387 61 -b864 1b 74 79 -b87f 1 74 79 -b88c 23 113 79 -b8af 1 113 79 -b8bc 1b 254 79 -b8d7 1 254 79 -b8e6 56 354 61 -b948 4 384 61 -b94c 4 385 61 -b950 1b 387 61 -b96b 1 387 61 -b978 1b 74 79 -b993 1 74 79 -b9a0 23 113 79 -b9c3 1 113 79 -b9d0 1b 254 79 -b9eb 1 254 79 -FUNC b9ec 46e 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::_M_fill_insert(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >* const&) -b9ec 14 311 29 -ba00 b 313 78 -ba0b 24 315 78 -ba2f 8 318 78 -ba37 23 319 78 -ba5a 15 320 78 -ba6f c 321 78 -ba7b 51 323 78 -bacc 14 327 78 -bae0 30 328 78 -bb10 35 330 78 -bb45 48 334 78 -bb8d 17 338 78 -bba4 43 339 78 -bbe7 14 342 78 -bbfb 1e 343 78 -bc19 e 348 78 -bc27 1e 349 78 -bc45 e 350 78 -bc53 1d 353 78 -bc70 8 354 78 -bc78 e 355 78 -bc86 27 357 78 -bcad 6 358 78 -bcb3 4d 361 78 -bd00 40 365 78 -bd40 18 367 78 -bd58 4d 368 78 -bda5 3e 379 78 -bde3 30 381 78 -be13 12 384 78 -be25 13 385 78 -be38 22 386 78 -FUNC be5a 2e 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::insert(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node > >**, std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> > >, unsigned long, __gnu_cxx::_Hashtable_node > >* const&) -be5a c 657 29 -be66 22 658 71 -be94 15 580 34 -bea9 15 581 34 -bebe 37 582 34 -bef5 c 583 34 -bf01 1 583 34 -bf02 d 335 34 -bf0f 4e 337 34 -bf5d 4d 338 34 -bfaa d 134 42 -bfb7 65 135 42 -c028 22 300 61 -c04a 11 301 61 -c05b 1 301 61 -c068 4 315 61 -c06c 1b 317 61 -c087 1 317 61 -c094 1b 326 61 -c0af 1 326 61 -c0bc 4 384 61 -c0c0 4 385 61 -c0c4 1b 387 61 -c0df 1 387 61 -c0ec 1b 74 79 -c107 1 74 79 -c114 23 113 79 -c137 1 113 79 -c144 1b 254 79 -c15f 1 254 79 -c16c 15 763 71 -c181 40 766 71 -c1c1 3 768 71 -c1c4 2 773 71 -FUNC c1c6 124 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::reserve(unsigned long) -c1c6 13 69 29 -c1d9 15 71 78 -c1ee e 72 78 -c1fc 19 73 78 -c215 e 75 78 -c223 28 78 78 -c24b 3e 79 78 -c289 30 81 78 -c2b9 8 84 78 -c2c1 11 85 78 -c2d2 18 86 78 -c2f7 33 335 61 -c336 4 384 61 -c33a 4 385 61 -c33e 1b 387 61 -c359 1 387 61 -c366 1b 74 79 -c381 1 74 79 -c38e 23 113 79 -c3b1 1 113 79 -c3be 1b 254 79 -c3d9 1 254 79 -c3e8 56 354 61 -c44a 4 384 61 -c44e 4 385 61 -c452 1b 387 61 -c46d 1 387 61 -c47a 1b 74 79 -c495 1 74 79 -c4a2 23 113 79 -c4c5 1 113 79 -c4d2 1b 254 79 -c4ed 1 254 79 -FUNC c4ee 46e 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::_M_fill_insert(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -c4ee 14 311 29 -c502 b 313 78 -c50d 24 315 78 -c531 8 318 78 -c539 23 319 78 -c55c 15 320 78 -c571 c 321 78 -c57d 51 323 78 -c5ce 14 327 78 -c5e2 30 328 78 -c612 35 330 78 -c647 48 334 78 -c68f 17 338 78 -c6a6 43 339 78 -c6e9 14 342 78 -c6fd 1e 343 78 -c71b e 348 78 -c729 1e 349 78 -c747 e 350 78 -c755 1d 353 78 -c772 8 354 78 -c77a e 355 78 -c788 27 357 78 -c7af 6 358 78 -c7b5 4d 361 78 -c802 40 365 78 -c842 18 367 78 -c85a 4d 368 78 -c8a7 3e 379 78 -c8e5 30 381 78 -c915 12 384 78 -c927 13 385 78 -c93a 22 386 78 -FUNC c95c 2e 0 std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> >::insert(__gnu_cxx::__normal_iterator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >**, std::vector<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*, std::allocator<__gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >*> > >, unsigned long, __gnu_cxx::_Hashtable_node, __gnu_cxx::hash, std::equal_to, std::allocator > >*> >* const&) -c95c c 657 29 -c968 22 658 71 -c996 15 580 34 -c9ab 15 581 34 -c9c0 37 582 34 -c9f7 c 583 34 -ca03 1 583 34 -ca04 d 335 34 -ca11 4e 337 34 -ca5f 4d 338 34 -caac d 134 42 -cab9 65 135 42 -FUNC cb1e 44 0 dwarf2reader::CUFunctionInfoHandler::StartCompilationUnit(unsigned long long, unsigned char, unsigned char, unsigned long long, unsigned char) -cb1e 39 135 42 -cb57 5 102 30 -cb5c 6 103 30 -FUNC cb62 41 0 dwarf2reader::CUFunctionInfoHandler::ProcessAttributeString(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, std::string const&) -cb62 18 136 30 -cb7a 10 137 30 -cb8a 17 138 30 -cba1 2 139 30 -cba3 1 139 30 -FUNC cba4 2a5 0 dwarf2reader::CUFunctionInfoHandler::ProcessAttributeUnsigned(unsigned long long, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm, unsigned long long) -cba4 2d 144 30 -cbd1 a 145 30 -cbdb 58 146 30 -cc33 35 147 30 -cc68 32 146 30 -cc9a 2a 147 30 -ccc4 82 152 30 -cd46 18 153 30 -cd5e 1c 152 30 -cd7a 2f 153 30 -cda9 e 154 30 -cdb7 28 155 30 -cddf 12 157 30 -cdf1 2 158 30 -cdf3 12 160 30 -ce05 2 161 30 -ce07 c 163 30 -ce13 2 164 30 -ce15 2c 166 30 -ce41 8 172 30 -ce49 1 172 30 -FUNC ce4a 19c 0 dwarf2reader::CULineInfoHandler::AddLine(unsigned long long, unsigned int, unsigned int, unsigned int) -ce4a 20 84 30 -ce6a 1c 85 30 -ce86 9c 87 30 -cf22 4f 89 30 -cf71 19 87 30 -cf8a 25 90 30 -cfaf 30 93 30 -cfdf 7 95 30 -FUNC cfe6 9f 0 dwarf2reader::CUFunctionInfoHandler::EndDIE(unsigned long long) -cfe6 19 174 30 -cfff 1c 175 30 -d01b 65 177 30 -d080 5 178 30 -d085 1 178 30 -FUNC d086 164 0 dwarf2reader::CUFunctionInfoHandler::StartDIE(unsigned long long, dwarf2reader::DwarfTag, std::list, std::allocator > > const&) -d086 20 111 30 -d0a6 1c 112 30 -d0c2 c 126 30 -d0ce 23 115 30 -d0f1 26 116 30 -d117 1a 117 30 -d131 d 118 30 -d13e 1b 119 30 -d159 5f 120 30 -d1b8 c 124 30 -d1c4 1c 115 30 -d1e0 3 126 30 -d1e3 7 129 30 -FUNC d1ea 73 0 dwarf2reader::CULineInfoHandler::DefineDir(std::string const&, unsigned int) -d1ea 13 52 30 -d1fd 45 54 30 -d242 15 55 30 -d257 6 56 30 -d25d 1 56 30 -FUNC d25e 23b 0 dwarf2reader::CULineInfoHandler::DefineFile(std::string const&, int, unsigned int, unsigned long long, unsigned long long) -d25e 2c 60 30 -d28a 45 62 30 -d2cf 2f 65 30 -d2fe 24 66 30 -d322 b 68 30 -d32d e 69 30 -d33b 19 71 30 -d354 17 72 30 -d36b 93 74 30 -d3fe 64 77 30 -d462 30 79 30 -d492 7 81 30 -d499 1 81 30 -d49a 14 38 30 -d4ae 36 40 30 -d4e4 41 43 30 -d525 41 44 30 -d566 67 45 30 -d5cd 10 46 30 -d5dd 13 45 30 -d5f0 15 47 30 -d605 e 48 30 -d613 3d 49 30 -d650 20 50 30 -d670 14 38 30 -d684 36 40 30 -d6ba 41 43 30 -d6fb 41 44 30 -d73c 67 45 30 -d7a3 10 46 30 -d7b3 13 45 30 -d7c6 15 47 30 -d7db e 48 30 -d7e9 3d 49 30 -d826 20 50 30 -d846 12 125 74 -d858 12 125 74 -d86a 13 55 32 -d87d 35 55 32 -d8b2 13 98 32 -d8c5 35 98 32 -d8fa c 35 32 -d906 d 35 32 -d913 1 35 32 -d914 d 22 32 -d921 40 22 32 -d961 1 22 32 -d962 c 89 70 -d96e 1e 90 70 -d998 14 208 34 -d9ac c 190 67 -d9b8 a 190 67 -d9c2 c 259 67 -d9ce 21 259 67 -d9ef 1 259 67 -FUNC d9f0 13 0 std::auto_ptr::operator->() const -d9f0 c 283 35 -d9fc 7 286 67 -da03 1 286 67 -da11 5c 104 68 -da6d 1 104 68 -FUNC da6e 28 0 bool std::operator==, std::allocator >(std::basic_string, std::allocator > const&, char const*) -da6e c 2139 37 -da7a 1c 2140 37 -FUNC da96 5d 0 std::basic_string, std::allocator > std::operator+, std::allocator >(std::basic_string, std::allocator > const&, char const*) -da96 d 2081 37 -daa3 12 2083 37 -dab5 1a 2084 37 -dacf 24 2085 37 -daf3 1 2085 37 -FUNC daf4 5d 0 std::basic_string, std::allocator > std::operator+, std::allocator >(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&) -daf4 d 2044 37 -db01 12 2046 37 -db13 1a 2047 37 -db2d 24 2048 37 -db51 1 2048 37 -db52 c 84 70 -db5e 17 85 70 -db75 1 85 70 -FUNC db76 2d 0 std::pair std::make_pair(char const*, unsigned int) -db76 c 144 37 -db82 21 145 70 -dba3 1 145 70 -dba4 c 84 70 -dbb0 23 85 70 -dbd3 1 85 70 -FUNC dbd4 3c 0 std::pair > std::make_pair >(unsigned long long, std::pair) -dbd4 1c 144 37 -dbf0 20 145 70 -dc10 d 89 70 -dc1d 64 90 70 -dc81 1 90 70 -dc82 c 89 70 -dc8e 2a 90 70 -dcb8 c 84 70 -dcc4 1d 85 70 -dce1 1 85 70 -FUNC dce2 3c 0 std::pair std::make_pair(unsigned long long, dwarf2reader::FunctionInfo*) -dce2 1c 144 37 -dcfe 20 145 70 -dd2a a 190 34 -dd40 d 194 34 -dd4d 1 194 34 -dd4e c 603 72 -dd5a c 603 72 -FUNC dd66 2b 0 std::vector >::begin() const -dd66 c 342 39 -dd72 1f 343 71 -dd91 1 343 71 -FUNC dd92 2c 0 std::vector >::end() const -dd92 c 360 39 -dd9e 20 361 71 -ddca 5 666 72 -ddcf 1 666 72 -dddd 2b 759 72 -FUNC de08 3c 0 std::vector >::size() const -de08 c 402 39 -de14 30 403 71 -FUNC de44 2b 0 std::vector >::begin() const -de44 c 342 39 -de50 1f 343 71 -de6f 1 343 71 -FUNC de70 2c 0 std::vector >::end() const -de70 c 360 39 -de7c 20 361 71 -dea9 31 759 72 -FUNC deda 3c 0 std::vector >::size() const -deda c 402 39 -dee6 30 403 71 -df16 c 603 72 -df22 c 603 72 -FUNC df2e 26 0 std::vector >::end() -df2e c 351 39 -df3a 1a 352 71 -df60 7 614 72 -df67 1 614 72 -FUNC df68 13 0 std::vector >::max_size() const -df68 c 407 39 -df74 7 408 71 -df7b 1 408 71 -df88 5 666 72 -df8d 1 666 72 -df9a d 623 72 -dfa7 5 624 72 -FUNC dfac 23 0 std::vector >::begin() -dfac c 333 39 -dfb8 17 334 71 -dfcf 1 334 71 -dfd0 c 35 32 -dfdc 26 35 32 -e00f 5c 104 68 -e06b 1 104 68 -e078 7 614 72 -e07f 1 614 72 -FUNC e080 35 0 dwarf2reader::SourceFileInfo::operator=(dwarf2reader::SourceFileInfo const&) -e080 c 35 39 -e08c 29 35 32 -e0b5 1 35 32 -FUNC e0b6 13 0 std::vector >::max_size() const -e0b6 c 407 39 -e0c2 7 408 71 -e0c9 1 408 71 -e0d6 d 623 72 -e0e3 5 624 72 -FUNC e0e8 3c 0 std::vector >::_M_range_check(unsigned long) const -e0e8 13 515 39 -e0fb 15 517 71 -e110 14 518 71 -FUNC e124 3c 0 std::vector >::_M_range_check(unsigned long) const -e124 13 515 39 -e137 15 517 71 -e14c 14 518 71 -e16c 2a 654 72 -FUNC e196 42 0 std::vector >::operator[](unsigned long) -e196 c 494 39 -e1a2 36 495 71 -FUNC e1d8 32 0 std::vector >::at(unsigned long) -e1d8 c 534 39 -e1e4 12 536 71 -e1f6 14 537 71 -e216 32 654 72 -FUNC e248 42 0 std::vector >::operator[](unsigned long) -e248 c 494 39 -e254 36 495 71 -FUNC e28a 32 0 std::vector >::at(unsigned long) -e28a c 534 39 -e296 12 536 71 -e2a8 14 537 71 -FUNC e2bc 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_end() -e2bc c 472 40 -e2c8 8 473 40 -FUNC e2d0 11 0 std::_Select1st > >::operator()(std::pair > const&) const -e2d0 c 550 41 -e2dc 5 551 41 -e2e1 1 551 41 -FUNC e2e2 53 0 std::less::operator()(unsigned long long const&, unsigned long long const&) const -e2e2 c 226 41 -e2ee 47 227 41 -e335 1 227 41 -FUNC e336 20 0 std::_Rb_tree_iterator > >::operator==(std::_Rb_tree_iterator > > const&) const -e336 c 209 41 -e342 14 210 40 -e356 c 84 70 -e362 18 85 70 -FUNC e37a 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_end() -e37a c 472 41 -e386 8 473 40 -FUNC e38e 11 0 std::_Select1st >::operator()(std::pair const&) const -e38e c 550 41 -e39a 5 551 41 -e39f 1 551 41 -FUNC e3a0 20 0 std::_Rb_tree_iterator >::operator==(std::_Rb_tree_iterator > const&) const -e3a0 c 209 41 -e3ac 14 210 40 -e3c0 c 84 70 -e3cc 18 85 70 -e3e4 c 180 34 -e3f0 13 181 34 -e403 1 181 34 -e410 22 409 34 -e43e d 207 42 -e44b 1 207 42 -FUNC e44c 35 0 bool __gnu_cxx::operator!= > >(__gnu_cxx::__normal_iterator > > const&, __gnu_cxx::__normal_iterator > > const&) -e44c d 699 42 -e459 28 700 72 -e481 1 700 72 -FUNC e482 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator > >, std::allocator >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, std::allocator) -e482 c 171 43 -e48e 2 173 73 -e490 1a 174 73 -e4aa 21 173 73 -e4cb 2 174 73 -e4cd 1 174 73 -FUNC e4ce 35 0 bool __gnu_cxx::operator!= > >(__gnu_cxx::__normal_iterator > > const&, __gnu_cxx::__normal_iterator > > const&) -e4ce d 699 43 -e4db 28 700 72 -e503 1 700 72 -FUNC e504 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator > >, std::allocator >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, std::allocator) -e504 c 171 43 -e510 2 173 73 -e512 1a 174 73 -e52c 21 173 73 -e54d 2 174 73 -e54f 1 174 73 -FUNC e550 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_value(std::_Rb_tree_node > > const*) -e550 c 480 43 -e55c 8 481 40 -FUNC e564 28 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_key(std::_Rb_tree_node > > const*) -e564 c 484 43 -e570 1c 485 40 -FUNC e58c 25 0 std::_Rb_tree_iterator >::operator--() -e58c c 194 43 -e598 14 196 40 -e5ac 5 197 40 -e5b1 1 197 40 -FUNC e5b2 25 0 std::_Rb_tree_iterator > >::operator--() -e5b2 c 194 43 -e5be 14 196 40 -e5d2 5 197 40 -e5d7 1 197 40 -FUNC e5d8 14 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_value(std::_Rb_tree_node_base const*) -e5d8 c 504 43 -e5e4 8 505 40 -FUNC e5ec 28 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_S_key(std::_Rb_tree_node_base const*) -e5ec c 508 43 -e5f8 1c 509 40 -FUNC e614 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_value(std::_Rb_tree_node > const*) -e614 c 480 43 -e620 8 481 40 -FUNC e628 28 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_key(std::_Rb_tree_node > const*) -e628 c 484 43 -e634 1c 485 40 -FUNC e650 14 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_value(std::_Rb_tree_node_base const*) -e650 c 504 43 -e65c 8 505 40 -FUNC e664 28 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_S_key(std::_Rb_tree_node_base const*) -e664 c 508 43 -e670 1c 509 40 -e698 7 614 72 -e69f 1 614 72 -e6ac 7 98 68 -e6b3 1 98 68 -e6c0 1d 85 68 -e6dd 5 86 68 -e6e2 10 88 68 -FUNC e6f2 2a 0 std::_Vector_base >::_M_allocate(unsigned long) -e6f2 c 116 43 -e6fe 1e 117 71 -e728 7 98 68 -e72f 1 98 68 -e73c 1d 85 68 -e759 5 86 68 -e75e 16 88 68 -FUNC e774 2a 0 std::_Vector_base >::_M_allocate(unsigned long) -e774 c 116 43 -e780 1e 117 71 -e7aa 3a 104 68 -e7f0 2a 654 72 -FUNC e81a 42 0 std::vector<__gnu_cxx::_Hashtable_node > >*, std::allocator<__gnu_cxx::_Hashtable_node > >*> >::operator[](unsigned long) const -e81a c 509 43 -e826 36 510 71 -FUNC e85c 4e 0 std::string* std::__copy_backward::copy_b(std::string*, std::string*, std::string*) -e85c c 408 61 -e868 14 411 61 -e87c 1e 412 61 -e89a b 411 61 -e8a5 5 413 61 -FUNC e8aa 2b 0 std::string* std::__copy_backward_aux(std::string*, std::string*, std::string*) -e8aa c 432 44 -e8b6 4 440 61 -e8ba 1b 443 61 -e8d5 1 443 61 -e8e4 56 482 61 -e946 4 514 61 -e94a 4 515 61 -e94e 1b 517 61 -e969 1 517 61 -FUNC e96a 69 0 void std::_Construct(std::string*, std::string const&) -e96a d 77 44 -e977 5c 81 73 -e9d3 1 81 73 -FUNC e9d4 54 0 dwarf2reader::SourceFileInfo* std::__copy_backward::copy_b(dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo*) -e9d4 c 408 61 -e9e0 1a 411 61 -e9fa 1e 412 61 -ea18 b 411 61 -ea23 5 413 61 -FUNC ea28 2b 0 dwarf2reader::SourceFileInfo* std::__copy_backward_aux(dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo*) -ea28 c 432 44 -ea34 4 440 61 -ea38 1b 443 61 -ea53 1 443 61 -ea62 56 482 61 -eac4 4 514 61 -eac8 4 515 61 -eacc 1b 517 61 -eae7 1 517 61 -FUNC eae8 69 0 void std::_Construct(dwarf2reader::SourceFileInfo*, dwarf2reader::SourceFileInfo const&) -eae8 d 77 44 -eaf5 5c 81 73 -eb51 1 81 73 -eb52 c 69 70 -eb5e 20 69 70 -eb7e c 69 70 -eb8a 2a 69 70 -ebc1 5c 104 68 -ec1d 1 104 68 -ec2a 15 523 34 -ec3f 79 525 34 -ecb8 21 529 34 -ecd9 1 529 34 -ece6 14 229 42 -ed06 7 98 68 -ed0d 1 98 68 -ed1a 1d 85 68 -ed37 5 86 68 -ed3c 10 88 68 -FUNC ed4c 29 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_get_node() -ed4c c 355 44 -ed58 1d 356 40 -ed75 1 356 40 -FUNC ed76 b6 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_create_node(std::pair > const&) -ed76 d 363 44 -ed83 e 365 40 -ed91 3c 367 40 -edcd b 373 40 -edd8 11 367 40 -ede9 b 368 40 -edf4 12 370 40 -ee06 b 371 40 -ee11 13 368 40 -ee24 8 373 40 -FUNC ee2c cd 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair > const&) -ee2c d 787 44 -ee39 15 789 40 -ee4e 5d 792 40 -eeab 24 796 40 -eecf f 798 40 -eede 1b 799 40 -eef9 1 799 40 -FUNC eefa 1ef 0 std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::insert_unique(std::pair > const&) -eefa d 869 44 -ef07 e 871 40 -ef15 e 872 40 -ef23 4 873 40 -ef27 2 874 40 -ef29 6 876 40 -ef2f 35 877 40 -ef64 2a 878 40 -ef8e 6 874 40 -ef94 12 880 40 -efa6 a 881 40 -efb0 24 882 40 -efd4 51 883 40 -f025 b 885 40 -f030 36 886 40 -f066 4e 887 40 -f0b4 35 888 40 -f0e9 1 888 40 -FUNC f0ea 20 0 std::map, std::less, std::allocator > > >::insert(std::pair > const&) -f0ea c 359 45 -f0f6 14 360 45 -f116 7 98 68 -f11d 1 98 68 -f12a 1d 85 68 -f147 5 86 68 -f14c 1d 88 68 -f169 1 88 68 -FUNC f16a 29 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_get_node() -f16a c 355 45 -f176 1d 356 40 -f193 1 356 40 -FUNC f194 5f 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_create_node(std::pair const&) -f194 d 363 45 -f1a1 e 365 40 -f1af 3c 367 40 -f1eb 8 373 40 -f1f3 1 373 40 -FUNC f1f4 cd 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair const&) -f1f4 d 787 45 -f201 15 789 40 -f216 5d 792 40 -f273 24 796 40 -f297 f 798 40 -f2a6 1b 799 40 -f2c1 1 799 40 -FUNC f2c2 1ef 0 std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::insert_unique(std::pair const&) -f2c2 d 869 45 -f2cf e 871 40 -f2dd e 872 40 -f2eb 4 873 40 -f2ef 2 874 40 -f2f1 6 876 40 -f2f7 35 877 40 -f32c 2a 878 40 -f356 6 874 40 -f35c 12 880 40 -f36e a 881 40 -f378 24 882 40 -f39c 51 883 40 -f3ed b 885 40 -f3f8 36 886 40 -f42e 4e 887 40 -f47c 35 888 40 -f4b1 1 888 40 -FUNC f4b2 20 0 std::map, std::allocator > >::insert(std::pair const&) -f4b2 c 359 45 -f4be 14 360 45 -FUNC f4d2 19 0 void std::_Destroy(std::string*) -f4d2 c 106 45 -f4de d 107 73 -f4eb 1 107 73 -FUNC f4ec 44 0 void std::__destroy_aux<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, __false_type) -f4ec c 119 45 -f4f8 2 121 73 -f4fa 13 122 73 -f50d 21 121 73 -f52e 2 122 73 -FUNC f530 28 0 void std::_Destroy<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >) -f530 c 148 45 -f53c 1c 155 73 -f565 6 82 79 -f56b 2 85 79 -f56d 24 86 79 -f591 2c 85 79 -f5bd b 87 79 -f5c8 b 89 79 -f5d3 12 91 79 -f5e5 b 92 79 -f5f0 13 89 79 -f603 9 92 79 -f618 23 113 79 -f63b 1 113 79 -f648 1b 254 79 -f663 1 254 79 -FUNC f664 430 0 std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, std::string const&) -f664 14 249 47 -f678 14 251 78 -f68c 22 253 78 -f6ae f 255 78 -f6bd 12 256 78 -f6cf 55 257 78 -f724 4b 260 78 -f76f e 264 78 -f77d 15 265 78 -f792 e 266 78 -f7a0 1d 271 78 -f7bd 8 272 78 -f7c5 e 273 78 -f7d3 27 275 78 -f7fa 6 276 78 -f800 55 279 78 -f855 25 284 78 -f87a b 285 78 -f885 4f 286 78 -f8d4 3 284 78 -f8d7 13 279 78 -f8ea e 286 78 -f8f8 4d 298 78 -f945 30 299 78 -f975 12 302 78 -f987 13 303 78 -f99a 23 304 78 -f9bd 3 298 78 -f9c0 13 286 78 -f9d3 b 292 78 -f9de 39 294 78 -fa17 23 295 78 -fa3a 8 296 78 -fa42 16 294 78 -fa58 3 296 78 -fa5b 19 292 78 -fa74 19 298 78 -fa8d 7 304 78 -FUNC fa94 70 0 std::vector >::push_back(std::string const&) -fa94 c 602 47 -faa0 10 604 71 -fab0 1e 606 71 -face 11 607 71 -fadf 25 610 71 -FUNC fb04 19 0 void std::_Destroy(dwarf2reader::SourceFileInfo*) -fb04 c 106 47 -fb10 d 107 73 -fb1d 1 107 73 -FUNC fb1e 44 0 void std::__destroy_aux<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, __false_type) -fb1e c 119 47 -fb2a 2 121 73 -fb2c 13 122 73 -fb3f 21 121 73 -fb60 2 122 73 -FUNC fb62 28 0 void std::_Destroy<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >) -fb62 c 148 47 -fb6e 1c 155 73 -fb97 6 82 79 -fb9d 2 85 79 -fb9f 24 86 79 -fbc3 2c 85 79 -fbef b 87 79 -fbfa b 89 79 -fc05 12 91 79 -fc17 b 92 79 -fc22 13 89 79 -fc35 9 92 79 -fc4a 23 113 79 -fc6d 1 113 79 -fc7a 1b 254 79 -fc95 1 254 79 -FUNC fc96 43d 0 std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, dwarf2reader::SourceFileInfo const&) -fc96 14 249 47 -fcaa 14 251 78 -fcbe 22 253 78 -fce0 f 255 78 -fcef 12 256 78 -fd01 55 257 78 -fd56 4b 260 78 -fda1 e 264 78 -fdaf 15 265 78 -fdc4 e 266 78 -fdd2 1d 271 78 -fdef 8 272 78 -fdf7 e 273 78 -fe05 27 275 78 -fe2c 6 276 78 -fe32 55 279 78 -fe87 25 284 78 -feac b 285 78 -feb7 4f 286 78 -ff06 3 284 78 -ff09 13 279 78 -ff1c e 286 78 -ff2a 4d 298 78 -ff77 36 299 78 -ffad 12 302 78 -ffbf 13 303 78 -ffd2 2a 304 78 -fffc 3 298 78 -ffff 13 286 78 -10012 b 292 78 -1001d 39 294 78 -10056 23 295 78 -10079 8 296 78 -10081 16 294 78 -10097 3 296 78 -1009a 19 292 78 -100b3 19 298 78 -100cc 7 304 78 -100d3 1 304 78 -FUNC 100d4 70 0 std::vector >::push_back(dwarf2reader::SourceFileInfo const&) -100d4 c 602 47 -100e0 10 604 71 -100f0 1e 606 71 -1010e 11 607 71 -1011f 25 610 71 -FUNC 10144 16c 0 Start -10144 17 610 71 -1015b 40 49 48 -1019b 6 51 48 -101a1 3f 53 48 -101e0 7 54 48 -101e7 5 55 48 -101ec 2a 58 48 -10216 61 61 48 -10277 7 62 48 -1027e 2 63 48 -10280 29 66 48 -102a9 7 67 48 -FUNC 102b0 108 0 Usage -102b0 19 70 48 -102c9 30 71 48 -102f9 29 73 48 -10322 30 74 48 -10352 30 75 48 -10382 30 76 48 -103b2 6 77 48 -FUNC 103b8 3af 0 SetupOptions -103b8 21 80 48 -103d9 8 82 48 -103e1 6 85 48 -103e7 10 86 48 -103f7 2e 88 48 -10425 2f 94 48 -10454 2a 91 48 -1047e 23 95 48 -104a1 3e 97 48 -104df 11 98 48 -104f0 7c 99 48 -1056c c 100 48 -10578 5 99 48 -1057d 3e 101 48 -105bb 11 102 48 -105cc 3e 103 48 -1060a 11 104 48 -1061b 37 106 48 -10652 b 107 48 -1065d c 108 48 -10669 b 113 48 -10674 c 114 48 -10680 14 119 48 -10694 30 120 48 -106c4 b 121 48 -106cf c 122 48 -106db 81 127 48 -1075c b 128 48 -10767 1 128 48 -FUNC 10768 a7 0 main -10768 13 131 48 -1077b 37 132 48 -107b2 1e 135 48 -107d0 e 136 48 -107de 8 137 48 -107e6 17 139 48 -107fd c 141 48 -10809 6 142 48 -1080f 1 142 48 -10810 c 47 49 -1081c 1a 48 49 -10836 2 49 49 -10838 c 47 49 -10844 1a 48 49 -1085e 2 49 49 -FUNC 10860 cb 0 google_breakpad::FileID::FileIdentifier(unsigned char*) -10860 f 51 49 -1086f 16 52 49 -10885 6 53 49 -1088b f 54 49 -1089a b 57 49 -108a5 7 62 49 -108ac 2 63 49 -108ae 1c 64 49 -108ca 32 63 49 -108fc b 67 49 -10907 12 68 49 -10919 10 70 49 -10929 2 71 49 -1092b 1 71 49 -FUNC 1092c f2 0 google_breakpad::FileID::MachoIdentifier(int, unsigned char*) -1092c 10 73 49 -1093c 15 74 49 -10951 20 76 49 -10971 f 77 49 -10980 20 79 49 -109a0 c 80 49 -109ac 69 82 49 -10a15 9 83 49 -FUNC 10a1e fb 0 google_breakpad::FileID::ConvertIdentifierToString(unsigned char const*, char*, int) -10a1e c 87 49 -10a2a 7 88 49 -10a31 c 89 49 -10a3d 15 90 49 -10a52 12 91 49 -10a64 18 93 49 -10a7c e 94 49 -10a8a 2b 96 49 -10ab5 2b 97 49 -10ae0 17 89 49 -10af7 20 101 49 -10b17 2 102 49 -10b19 1 102 49 -FUNC 10b1a 13 0 NXHostByteOrder -10b1a c 144 56 -10b26 5 147 56 -10b2b 2 153 56 -10b2d 1 153 56 -10b2e c 56 51 -10b3a 1a 57 51 -10b54 1e 58 51 -10b72 2 59 51 -10b74 c 56 51 -10b80 1a 57 51 -10b9a 1e 58 51 -10bb8 2 59 51 -10bba c 61 51 -10bc6 e 62 51 -10bd4 11 63 51 -10be5 2 64 51 -10be7 1 64 51 -10be8 c 61 51 -10bf4 e 62 51 -10c02 11 63 51 -10c13 2 64 51 -10c15 1 64 51 -FUNC 10c16 477 0 MacFileUtilities::MachoID::UpdateCRC(unsigned char*, unsigned long) -10c16 c 74 51 -10c22 11 82 51 -10c33 14 83 51 -10c47 5 86 51 -10c4c 9 87 51 -10c55 7 88 51 -10c5c 18b 90 51 -10de7 6 91 51 -10ded 14 89 51 -10e01 23 93 51 -10e24 23 94 51 -10e47 d 86 51 -10e54 f 98 51 -10e63 6 100 51 -10e69 18b 101 51 -10ff4 6 102 51 -10ffa c 99 51 -11006 13 105 51 -11019 8 106 51 -11021 10 104 51 -11031 23 108 51 -11054 23 109 51 -11077 14 110 51 -1108b 2 112 51 -1108d 1 112 51 -FUNC 1108e 2c 0 MacFileUtilities::MachoID::UpdateMD5(unsigned char*, unsigned long) -1108e c 114 51 -1109a 1e 115 51 -110b8 2 116 51 -FUNC 110ba 2c 0 MacFileUtilities::MachoID::UpdateSHA1(unsigned char*, unsigned long) -110ba c 118 51 -110c6 1e 119 51 -110e4 2 120 51 -FUNC 110e6 121 0 MacFileUtilities::MachoID::Update(MacFileUtilities::MachoWalker*, unsigned long, unsigned long) -110e6 f 122 51 -110f5 1b 123 51 -11110 e 129 51 -1111e 5 130 51 -11123 9 131 51 -1112c 7 132 51 -11133 a 133 51 -1113d 6 135 51 -11143 7 136 51 -1114a 35 139 51 -1117f 6c 142 51 -111eb 10 143 51 -111fb a 130 51 -11205 2 145 51 -11207 1 145 51 -FUNC 11208 cf 0 MacFileUtilities::MachoID::UUIDCommand(int, unsigned char*) -11208 14 147 51 -1121c 25 149 51 -11241 7 151 51 -11248 19 152 51 -11261 9 153 51 -1126a 8 157 51 -11272 1f 158 51 -11291 9 159 51 -1129a 36 162 51 -112d0 7 163 51 -112d7 1 163 51 -FUNC 112d8 224 0 MacFileUtilities::MachoID::IDCommand(int, unsigned char*) -112d8 15 165 51 -112ed 25 167 51 -11312 7 169 51 -11319 19 170 51 -11332 c 171 51 -1133e c 175 51 -1134a 6 180 51 -11350 7 181 51 -11357 9 182 51 -11360 9 183 51 -11369 28 185 51 -11391 33 186 51 -113c4 1e 185 51 -113e2 10 189 51 -113f2 10 190 51 -11402 10 191 51 -11412 d 192 51 -1141f 10 193 51 -1142f 10 194 51 -1143f 10 195 51 -1144f d 196 51 -1145c 17 197 51 -11473 17 198 51 -1148a 17 199 51 -114a1 14 200 51 -114b5 9 202 51 -114be 36 205 51 -114f4 8 206 51 -FUNC 114fc d1 0 MacFileUtilities::MachoID::Adler32(int) -114fc 14 208 51 -11510 25 209 51 -11535 27 210 51 -1155c d 211 51 -11569 19 213 51 -11582 9 214 51 -1158b 3b 216 51 -115c6 7 217 51 -115cd 1 217 51 -FUNC 115ce f8 0 MacFileUtilities::MachoID::MD5(int, unsigned char*) -115ce 14 219 51 -115e2 25 220 51 -11607 27 221 51 -1162e 19 223 51 -11647 19 224 51 -11660 9 225 51 -11669 17 227 51 -11680 9 228 51 -11689 36 231 51 -116bf 7 232 51 -FUNC 116c6 f8 0 MacFileUtilities::MachoID::SHA1(int, unsigned char*) -116c6 14 234 51 -116da 25 235 51 -116ff 27 236 51 -11726 19 238 51 -1173f 19 239 51 -11758 9 240 51 -11761 17 242 51 -11778 9 243 51 -11781 36 246 51 -117b7 7 247 51 -FUNC 117be 378 0 MacFileUtilities::MachoID::WalkerCB(MacFileUtilities::MachoWalker*, load_command*, long long, bool, void*) -117be 2b 251 51 -117e9 6 252 51 -117ef e 254 51 -117fd 38 257 51 -11835 f 258 51 -11844 9 260 51 -1184d 17 261 51 -11864 20 266 51 -11884 f 267 51 -11893 d 271 51 -118a0 c 273 51 -118ac 38 274 51 -118e4 f 275 51 -118f3 9 277 51 -118fc 1f 278 51 -1191b 14 282 51 -1192f 2b 283 51 -1195a d 285 51 -11967 19 273 51 -11980 e 287 51 -1198e 38 290 51 -119c6 f 291 51 -119d5 9 293 51 -119de 17 294 51 -119f5 20 299 51 -11a15 f 300 51 -11a24 d 304 51 -11a31 c 306 51 -11a3d 38 307 51 -11a75 f 308 51 -11a84 9 310 51 -11a8d 1f 311 51 -11aac 1a 315 51 -11ac6 39 316 51 -11aff d 318 51 -11b0c 11 306 51 -11b1d 10 323 51 -11b2d 9 324 51 -FUNC 11b36 95 0 MacFileUtilities::MachoID::UUIDWalkerCB(MacFileUtilities::MachoWalker*, load_command*, long long, bool, void*) -11b36 1e 328 51 -11b54 a 329 51 -11b5e 6 331 51 -11b64 2f 333 51 -11b93 9 335 51 -11b9c 6 337 51 -11ba2 14 338 51 -11bb6 9 340 51 -11bbf a 344 51 -11bc9 2 345 51 -11bcb 1 345 51 -FUNC 11bcc 95 0 MacFileUtilities::MachoID::IDWalkerCB(MacFileUtilities::MachoWalker*, load_command*, long long, bool, void*) -11bcc 1e 349 51 -11bea a 350 51 -11bf4 6 351 51 -11bfa 2f 353 51 -11c29 9 354 51 -11c32 6 356 51 -11c38 14 357 51 -11c4c 9 359 51 -11c55 a 363 51 -11c5f 2 364 51 -11c61 1 364 51 -FUNC 11c62 1c 0 _OSSwapInt32 -11c62 f 53 55 -11c71 8 55 55 -11c79 3 56 55 -11c7c 2 57 55 -FUNC 11c7e 19 0 NXSwapInt -11c7e f 52 56 -11c8d 8 54 56 -11c95 2 55 56 -11c97 1 55 56 -FUNC 11c98 13 0 NXHostByteOrder -11c98 c 144 56 -11ca4 5 147 56 -11ca9 2 153 56 -11cab 1 153 56 -11cac c 52 54 -11cb8 12 54 54 -11cca 1a 55 54 -11ce4 2 56 54 -11ce6 c 52 54 -11cf2 12 54 54 -11d04 1a 55 54 -11d1e 2 56 54 -11d20 c 58 54 -11d2c a 59 54 -11d36 d 60 54 -11d43 2 61 54 -11d45 1 61 54 -11d46 c 58 54 -11d52 a 59 54 -11d5c d 60 54 -11d69 2 61 54 -11d6b 1 61 54 -FUNC 11d6c 37 0 MacFileUtilities::MachoWalker::ValidateCPUType(int) -11d6c c 63 54 -11d78 6 66 54 -11d7e 8 67 54 -11d86 6 68 54 -11d8c b 69 54 -11d97 7 74 54 -11d9e 3 80 54 -11da1 2 81 54 -11da3 1 81 54 -FUNC 11da4 50 0 MacFileUtilities::MachoWalker::ReadBytes(void*, unsigned long, long long) -11da4 18 96 54 -11dbc 36 97 54 -11df2 2 98 54 -FUNC 11df4 73 0 MacFileUtilities::MachoWalker::CurrentHeader(mach_header_64*, long long*) -11df4 c 100 54 -11e00 a 101 54 -11e0a 37 102 54 -11e41 11 103 54 -11e52 9 104 54 -11e5b a 107 54 -11e65 2 108 54 -11e67 1 108 54 -FUNC 11e68 2a6 0 MacFileUtilities::MachoWalker::FindHeader(int, long long&) -11e68 c 110 54 -11e74 15 111 54 -11e89 31 114 54 -11eba c 115 54 -11ec6 10 117 54 -11ed6 4 120 54 -11eda 14 121 54 -11eee 4 122 54 -11ef2 11 129 54 -11f03 28 124 54 -11f2b c 126 54 -11f37 31 133 54 -11f68 c 134 54 -11f74 14 136 54 -11f88 b 137 54 -11f93 8 139 54 -11f9b c 140 54 -11fa7 10 142 54 -11fb7 c 143 54 -11fc3 10 146 54 -11fd3 31 148 54 -12004 c 149 54 -12010 f 151 54 -1201f 14 152 54 -12033 16 154 54 -12049 c 158 54 -12055 31 159 54 -12086 9 160 54 -1208f f 162 54 -1209e 1c 163 54 -120ba 8 165 54 -120c2 10 166 54 -120d2 9 167 54 -120db 16 170 54 -120f1 11 158 54 -12102 a 174 54 -1210c 2 175 54 -FUNC 1210e 109 0 MacFileUtilities::MachoWalker::WalkHeaderCore(long long, unsigned int, bool) -1210e 1e 224 54 -1212c c 225 54 -12138 2f 227 54 -12167 c 228 54 -12173 6 230 54 -12179 14 231 54 -1218d 5b 234 54 -121e8 12 237 54 -121fa 11 225 54 -1220b a 240 54 -12215 2 241 54 -12217 1 241 54 -FUNC 12218 10e 0 MacFileUtilities::MachoWalker::WalkHeader64AtOffset(long long) -12218 18 203 54 -12230 2f 205 54 -1225f c 206 54 -1226b e 208 54 -12279 6 209 54 -1227f 14 210 54 -12293 9 212 54 -1229c a 213 54 -122a6 f 214 54 -122b5 15 215 54 -122ca 2b 216 54 -122f5 a 217 54 -122ff a 218 54 -12309 11 219 54 -1231a a 220 54 -12324 2 221 54 -FUNC 12326 143 0 MacFileUtilities::MachoWalker::WalkHeaderAtOffset(long long) -12326 18 177 54 -1233e 2f 179 54 -1236d c 180 54 -12379 e 182 54 -12387 6 183 54 -1238d 14 184 54 -123a1 2e 189 54 -123cf 7 190 54 -123d6 9 192 54 -123df a 193 54 -123e9 f 194 54 -123f8 15 195 54 -1240d 2b 196 54 -12438 a 197 54 -12442 a 198 54 -1244c 11 199 54 -1245d a 200 54 -12467 2 201 54 -12469 1 201 54 -FUNC 1246a 99 0 MacFileUtilities::MachoWalker::WalkHeader(int) -1246a c 83 54 -12476 15 84 54 -1248b 1d 86 54 -124a8 d 87 54 -124b5 21 88 54 -124d6 21 90 54 -124f7 a 93 54 -12501 2 94 54 -12503 1 94 54 -FUNC 12504 1c 0 _OSSwapInt32 -12504 f 53 55 -12513 8 55 55 -1251b 3 56 55 -1251e 2 57 55 -FUNC 12520 2b 0 _OSSwapInt64 -12520 12 64 55 -12532 11 69 55 -12543 6 70 55 -12549 2 71 55 -1254b 1 71 55 -FUNC 1254c 19 0 NXSwapLong -1254c f 61 56 -1255b 8 63 56 -12563 2 64 56 -12565 1 64 56 -FUNC 12566 1f 0 NXSwapLongLong -12566 12 70 56 -12578 b 72 56 -12583 2 73 56 -12585 1 73 56 -FUNC 12586 32 0 breakpad_swap_uuid_command(breakpad_uuid_command*, NXByteOrder) -12586 c 37 57 -12592 11 39 57 -125a3 13 40 57 -125b6 2 41 57 -FUNC 125b8 da 0 breakpad_swap_segment_command_64(segment_command_64*, NXByteOrder) -125b8 c 44 57 -125c4 11 46 57 -125d5 13 47 57 -125e8 17 49 57 -125ff 17 50 57 -12616 17 51 57 -1262d 17 52 57 -12644 13 54 57 -12657 13 55 57 -1266a 13 56 57 -1267d 13 57 57 -12690 2 58 57 -FUNC 12692 a4 0 breakpad_swap_mach_header_64(mach_header_64*, NXByteOrder) -12692 c 61 57 -1269e 11 63 57 -126af 13 64 57 -126c2 13 65 57 -126d5 13 66 57 -126e8 13 67 57 -126fb 13 68 57 -1270e 13 69 57 -12721 13 70 57 -12734 2 71 57 -FUNC 12736 1d1 0 breakpad_swap_section_64(section_64*, unsigned int, NXByteOrder) -12736 d 75 57 -12743 c 77 57 -1274f 33 78 57 -12782 33 79 57 -127b5 2d 81 57 -127e2 2d 82 57 -1280f 2d 83 57 -1283c 2d 84 57 -12869 2d 85 57 -12896 2d 86 57 -128c3 2d 87 57 -128f0 11 77 57 -12901 6 89 57 -12907 1 89 57 -12908 12 9 58 -1291a 4f 11 58 -12969 2 12 58 -1296b 1 12 58 -1296c 12 9 58 -1297e 4f 11 58 -129cd 2 12 58 -129cf 1 12 58 -129d0 13 14 58 -129e3 2a 14 58 -12a0d 1 14 58 -12a0e 13 14 58 -12a21 2a 14 58 -12a4b 1 14 58 -12a4c 13 14 58 -12a5f 2a 14 58 -12a89 1 14 58 -FUNC 12a8a bb 0 dwarf2reader::ByteReader::SetOffsetSize(unsigned char) -12a8a 19 16 58 -12aa3 a 17 58 -12aad 48 18 58 -12af5 6 19 58 -12afb 23 20 58 -12b1e 21 22 58 -12b3f 6 24 58 -12b45 1 24 58 -FUNC 12b46 bb 0 dwarf2reader::ByteReader::SetAddressSize(unsigned char) -12b46 19 26 58 -12b5f a 27 58 -12b69 48 28 58 -12bb1 6 29 58 -12bb7 23 30 58 -12bda 21 32 58 -12bfb 6 34 58 -12c01 1 34 58 -FUNC 12c02 a2 0 dwarf2reader::ByteReader::ReadFourBytes(char const*) const -12c02 c 24 59 -12c0e c 25 64 -12c1a d 26 64 -12c27 f 27 64 -12c36 f 28 64 -12c45 b 29 64 -12c50 27 30 64 -12c77 2b 32 64 -12ca2 2 34 64 -FUNC 12ca4 40e 0 dwarf2reader::ByteReader::ReadEightBytes(char const*) const -12ca4 11 36 59 -12cb5 1a 37 64 -12ccf 1b 38 64 -12cea 1d 39 64 -12d07 1d 40 64 -12d24 1d 41 64 -12d41 1d 42 64 -12d5e 1d 43 64 -12d7b 1d 44 64 -12d98 f 45 64 -12da7 18f 47 64 -12f36 172 50 64 -130a8 a 52 64 -130b2 2 52 64 -FUNC 130b4 a6 0 ReadInitialLength -130b4 15 29 60 -130c9 18 30 60 -130e1 6 31 60 -130e7 d 35 60 -130f4 13 36 60 -13107 9 37 60 -13110 1a 38 60 -1312a 13 40 60 -1313d 9 41 60 -13146 12 43 60 -13158 2 44 60 -1315a 1f 47 60 -13179 65 50 60 -131de 1f 47 60 -131fd 65 50 60 -FUNC 13262 393 0 dwarf2reader::CompilationUnit::SkipAttribute(char const*, dwarf2reader::DwarfForm) -13262 14 133 60 -13276 82 136 60 -132f8 1f 139 60 -13317 a 140 60 -13321 21 141 60 -13342 c 147 60 -1334e e 151 60 -1335c e 155 60 -1336a e 159 60 -13378 27 162 60 -1339f 1c 166 60 -133bb 10 167 60 -133cb 1c 171 60 -133e7 10 172 60 -133f7 1e 175 60 -13415 56 180 60 -1346b d 181 60 -13478 1e 182 60 -13496 11 183 60 -134a7 1e 184 60 -134c5 24 189 60 -134e9 26 192 60 -1350f 23 195 60 -13532 22 198 60 -13554 15 199 60 -13569 1b 203 60 -13584 30 206 60 -135b4 30 208 60 -135e4 a 209 60 -135ee 7 210 60 -135f5 1 210 60 -FUNC 135f6 29b 0 dwarf2reader::CompilationUnit::ReadHeader() -135f6 14 217 60 -1360a 9 218 60 -13613 4e 221 60 -13661 17 223 60 -13678 a 224 60 -13682 f 225 60 -13691 4e 227 60 -136df 1e 228 60 -136fd 6 229 60 -13703 5e 231 60 -13761 1e 232 60 -1377f 18 233 60 -13797 4c 235 60 -137e3 1d 236 60 -13800 1c 237 60 -1381c 5 238 60 -13821 9 240 60 -1382a 60 245 60 -1388a 7 247 60 -13891 1 247 60 -FUNC 13892 a57 0 dwarf2reader::CompilationUnit::ProcessAttribute(unsigned long long, char const*, dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm) -13892 24 299 60 -138b6 8a 302 60 -13940 1f 307 60 -1395f a 308 60 -13969 36 309 60 -1399f 5b 316 60 -139fa c 317 60 -13a06 5b 322 60 -13a61 e 323 60 -13a6f 55 328 60 -13ac4 e 329 60 -13ad2 55 334 60 -13b27 e 335 60 -13b35 6 338 60 -13b3b 9a 340 60 -13bd5 33 341 60 -13c08 25 340 60 -13c2d 5c 348 60 -13c89 10 349 60 -13c99 5c 354 60 -13cf5 10 355 60 -13d05 55 359 60 -13d5a 1e 360 60 -13d78 56 365 60 -13dce d 366 60 -13ddb 55 368 60 -13e30 1e 369 60 -13e4e 11 370 60 -13e5f 55 372 60 -13eb4 1e 373 60 -13ed2 29 378 60 -13efb 4a 380 60 -13f45 f 381 60 -13f54 29 385 60 -13f7d 4c 387 60 -13fc9 11 388 60 -13fda 1b 392 60 -13ff5 4c 394 60 -14041 11 395 60 -14052 22 399 60 -14074 4e 401 60 -140c2 15 402 60 -140d7 3c 406 60 -14113 1b 408 60 -1412e 54 409 60 -14182 f 411 60 -14191 9a 413 60 -1422b 24 414 60 -1424f 25 413 60 -14274 30 418 60 -142a4 30 420 60 -142d4 a 421 60 -142de b 422 60 -142e9 1 422 60 -142ea 1f 489 60 -14309 3a 491 60 -14343 a 492 60 -1434d 6 493 60 -14353 1 493 60 -14354 1f 489 60 -14373 3a 491 60 -143ad a 492 60 -143b7 6 493 60 -143bd 1 493 60 -FUNC 143be b5 0 dwarf2reader::CompilationUnit::ProcessDIE(unsigned long long, char const*, dwarf2reader::CompilationUnit::Abbrev const&) -143be 19 426 60 -143d7 13 427 60 -143ea 46 430 60 -14430 3a 427 60 -1446a 3 432 60 -1446d 6 433 60 -14473 1 433 60 -FUNC 14474 85 0 dwarf2reader::CompilationUnit::SkipDIE(char const*, dwarf2reader::CompilationUnit::Abbrev const&) -14474 c 122 60 -14480 13 123 60 -14493 27 126 60 -144ba 3a 123 60 -144f4 3 128 60 -144f7 2 129 60 -144f9 1 129 60 -FUNC 144fa be4 0 dwarf2reader::LineInfo::ProcessOneOpcode(dwarf2reader::ByteReader*, dwarf2reader::LineInfoHandler*, dwarf2reader::LineInfoHeader const&, char const*, dwarf2reader::LineStateMachine*, unsigned long*, unsigned long, bool*) -144fa 18 593 60 -14512 a 594 60 -1451c 18 596 60 -14534 8 597 60 -1453c 5 598 60 -14541 19 602 60 -1455a f 603 60 -14569 50 605 60 -145b9 46 607 60 -145ff e0 610 60 -146df 6 612 60 -146e5 22 615 60 -14707 22 616 60 -14729 7 617 60 -14730 b 618 60 -1473b f 619 60 -1474a 5a 623 60 -147a4 7 625 60 -147ab b 626 60 -147b6 f 627 60 -147c5 28 631 60 -147ed e 632 60 -147fb 144 635 60 -1493f 6 637 60 -14945 9e 640 60 -149e3 5 642 60 -149e8 22 644 60 -14a0a e 645 60 -14a18 1c 646 60 -14a34 2b 652 60 -14a5f b 653 60 -14a6a 22 658 60 -14a8c e 659 60 -14a9a 8 660 60 -14aa2 5 662 60 -14aa7 22 664 60 -14ac9 e 665 60 -14ad7 9 666 60 -14ae0 5 668 60 -14ae5 12 670 60 -14af7 5 672 60 -14afc 7 674 60 -14b03 5 676 60 -14b08 16 678 60 -14b1e 9 679 60 -14b27 d9 682 60 -14c00 6 684 60 -14c06 1f 687 60 -14c25 5 689 60 -14c2a 40 693 60 -14c6a d6 696 60 -14d40 6 698 60 -14d46 1c 701 60 -14d62 5 703 60 -14d67 1f 706 60 -14d86 d 707 60 -14d93 13 708 60 -14da6 26 710 60 -14dcc 5 711 60 -14dd1 50 713 60 -14e21 7 715 60 -14e28 b 716 60 -14e33 f 717 60 -14e42 18 725 60 -14e5a f 726 60 -14e69 5 728 60 -14e6e 6 730 60 -14e74 28 732 60 -14e9c d 733 60 -14ea9 22 735 60 -14ecb e 736 60 -14ed9 22 739 60 -14efb e 740 60 -14f09 22 743 60 -14f2b e 744 60 -14f39 a 746 60 -14f43 fd 748 60 -15040 a 758 60 -1504a 9 759 60 -15053 1c 761 60 -1506f d 762 60 -1507c e 763 60 -1508a 2e 759 60 -150b8 b 769 60 -150c3 10 770 60 -150d3 b 771 60 -FUNC 150de 14b 0 dwarf2reader::LineInfo::ReadLines() -150de e 773 60 -150ec 9 778 60 -150f5 17 782 60 -1510c 8 783 60 -15114 6 785 60 -1511a 9 787 60 -15123 5 788 60 -15128 19 789 60 -15141 5 790 60 -15146 4a 793 60 -15190 6 794 60 -15196 4a 796 60 -151e0 a 797 60 -151ea f 790 60 -151f9 15 788 60 -1520e 14 801 60 -15222 7 802 60 -15229 1 802 60 -FUNC 1522a 4fd 0 dwarf2reader::CompilationUnit::ReadAbbrevs() -1522a 18 60 60 -15242 e 61 60 -15250 58 65 60 -152a8 38 66 60 -152e0 44 65 60 -15324 2a 66 60 -1534e 45 68 60 -15393 16 69 60 -153a9 1d 75 60 -153c6 6 76 60 -153cc 40 77 60 -1540c b 80 60 -15417 1f 82 60 -15436 e 84 60 -15444 6 77 60 -1544a 1f 68 60 -15469 a 84 60 -15473 1d 79 60 -15490 6 86 60 -15496 a 87 60 -154a0 3d 89 60 -154dd 1f 90 60 -154fc a 91 60 -15506 6 92 60 -1550c 3d 94 60 -15549 1d 95 60 -15566 5 96 60 -1556b 3d 98 60 -155a8 1f 101 60 -155c7 a 102 60 -155d1 3d 104 60 -1560e 1f 105 60 -1562d a 106 60 -15637 c 107 60 -15643 6 111 60 -15649 6 112 60 -1564f 32 113 60 -15681 47 115 60 -156c8 30 116 60 -156f8 24 79 60 -1571c b 118 60 -15727 1 118 60 -FUNC 15728 5dc 0 dwarf2reader::LineInfo::ReadHeader() -15728 18 503 60 -15740 9 504 60 -15749 17 508 60 -15760 a 510 60 -1576a f 511 60 -15779 60 512 60 -157d9 44 516 60 -1581d 1e 518 60 -1583b 6 519 60 -15841 1e 521 60 -1585f 18 522 60 -15877 1d 524 60 -15894 5 525 60 -15899 20 527 60 -158b9 5 528 60 -158be c 530 60 -158ca 5 531 60 -158cf 1d 533 60 -158ec 5 534 60 -158f1 1d 536 60 -1590e 5 537 60 -15913 45 539 60 -15958 1f 540 60 -15977 19 541 60 -15990 15 542 60 -159a5 1f 539 60 -159c4 30 543 60 -159f4 5 544 60 -159f9 14 542 60 -15a0d e 548 60 -15a1b 7 549 60 -15a22 5 550 60 -15a27 6 551 60 -15a2d 8b 552 60 -15ab8 28 553 60 -15ae0 5 554 60 -15ae5 16 550 60 -15afb 25 552 60 -15b20 5 557 60 -15b25 e 560 60 -15b33 7 561 60 -15b3a 5 563 60 -15b3f 6 564 60 -15b45 28 565 60 -15b6d 22 567 60 -15b8f a 568 60 -15b99 22 570 60 -15bbb a 571 60 -15bc5 22 573 60 -15be7 a 574 60 -15bf1 ba 576 60 -15cab 5 577 60 -15cb0 16 563 60 -15cc6 25 576 60 -15ceb 5 580 60 -15cf0 9 582 60 -15cf9 b 583 60 -FUNC 15d04 3d 0 dwarf2reader::LineInfo::Start() -15d04 c 495 60 -15d10 b 496 60 -15d1b b 497 60 -15d26 19 498 60 -15d3f 2 499 60 -15d41 1 499 60 -FUNC 15d42 304 0 dwarf2reader::CompilationUnit::ProcessDIEs() -15d42 11 435 60 -15d53 9 436 60 -15d5c 9 441 60 -15d65 17 445 60 -15d7c 8 446 60 -15d84 6 448 60 -15d8a 6c 453 60 -15df6 8 455 60 -15dfe 16 453 60 -15e14 3 455 60 -15e17 2f 453 60 -15e46 29 458 60 -15e6f 22 460 60 -15e91 a 462 60 -15e9b a 465 60 -15ea5 1e 466 60 -15ec3 13 467 60 -15ed6 2b 468 60 -15f01 18 472 60 -15f19 9 473 60 -15f22 42 474 60 -15f64 1e 475 60 -15f82 2a 477 60 -15fac b 480 60 -15fb7 1e 481 60 -15fd5 26 483 60 -15ffb 1d 455 60 -16018 24 485 60 -1603c a 486 60 -FUNC 16046 35f 0 dwarf2reader::CompilationUnit::Start() -16046 18 249 60 -1605e 58 251 60 -160b6 35 252 60 -160eb 32 251 60 -1611d 2a 252 60 -16147 20 255 60 -16167 37 256 60 -1619e b 259 60 -161a9 f 264 60 -161b8 17 265 60 -161cf c 266 60 -161db a 268 60 -161e5 95 271 60 -1627a 11 276 60 -1628b b 279 60 -16296 58 282 60 -162ee 2f 283 60 -1631d 32 282 60 -1634f 14 284 60 -16363 1a 285 60 -1637d b 289 60 -16388 12 291 60 -1639a b 292 60 -163a5 1 292 60 -FUNC 163a6 3a 0 std::fill(unsigned char*, unsigned char*, unsigned char const&) -163a6 c 573 61 -163b2 9 576 61 -163bb 23 577 61 -163de 2 578 61 -FUNC 163e0 33 0 std::__deque_buf_size(unsigned long) -163e0 c 83 62 -163ec 27 84 62 -16413 1 84 62 -FUNC 16414 18 0 dwarf2reader::ByteReader::OffsetSize() const -16414 c 38 63 -16420 c 38 63 -FUNC 1642c 18 0 dwarf2reader::ByteReader::AddressSize() const -1642c c 41 63 -16438 c 41 63 -FUNC 16444 17 0 dwarf2reader::ByteReader::ReadOneByte(char const*) const -16444 c 10 64 -16450 9 11 64 -16459 2 12 64 -1645b 1 12 64 -FUNC 1645c 63 0 dwarf2reader::ByteReader::ReadTwoBytes(char const*) const -1645c c 14 64 -16468 d 15 64 -16475 e 16 64 -16483 b 17 64 -1648e 17 18 64 -164a5 18 20 64 -164bd 2 22 64 -164bf 1 22 64 -FUNC 164c0 98 0 dwarf2reader::ByteReader::ReadUnsignedLEB128(char const*, unsigned long*) const -164c0 e 59 64 -164ce e 60 64 -164dc 7 61 64 -164e3 7 62 64 -164ea e 66 64 -164f8 5 67 64 -164fd 38 69 64 -16535 6 71 64 -1653b 8 65 64 -16543 8 75 64 -1654b 6 77 64 -16551 7 78 64 -FUNC 16558 ee 0 dwarf2reader::ByteReader::ReadSignedLEB128(char const*, unsigned long*) const -16558 e 84 64 -16566 e 85 64 -16574 7 86 64 -1657b 7 87 64 -16582 e 91 64 -16590 5 92 64 -16595 44 93 64 -165d9 6 94 64 -165df 8 90 64 -165e7 14 97 64 -165fb 36 98 64 -16631 8 99 64 -16639 6 100 64 -1663f 7 101 64 -FUNC 16646 a2 0 dwarf2reader::ByteReader::ReadOffset(char const*) const -16646 13 103 64 -16659 3f 104 64 -16698 4a 105 64 -166e2 6 106 64 -FUNC 166e8 a2 0 dwarf2reader::ByteReader::ReadAddress(char const*) const -166e8 13 108 64 -166fb 3f 109 64 -1673a 4a 110 64 -16784 6 111 64 -FUNC 1678a 61 0 dwarf2reader::LineStateMachine::Reset(bool) -1678a 12 12 65 -1679c 9 13 65 -167a5 11 14 65 -167b6 11 15 65 -167c7 a 16 65 -167d1 a 17 65 -167db 7 18 65 -167e2 7 19 65 -167e9 2 20 65 -167eb 1 20 65 -FUNC 167ec 20 0 std::_List_const_iterator >::operator!=(std::_List_const_iterator > const&) const -167ec c 253 66 -167f8 14 254 66 -FUNC 1680c 25 0 std::_List_const_iterator >::operator++(int) -1680c c 226 66 -16818 8 228 66 -16820 c 229 66 -1682c 5 230 66 -16831 1 230 66 -FUNC 16832 16 0 std::_List_const_iterator >::operator->() const -16832 c 215 66 -1683e a 216 66 -16848 c 190 67 -16854 a 190 67 -FUNC 1685e 13 0 std::auto_ptr > > >::operator->() const -1685e c 283 67 -1686a 7 286 67 -16871 1 286 67 -16872 c 65 68 -1687e 2 65 68 -16880 c 97 69 -1688c d 97 69 -16899 1 97 69 -1689a c 99 69 -168a6 14 100 69 -168ba c 97 69 -168c6 d 97 69 -168d3 1 97 69 -168d4 c 84 70 -168e0 17 85 70 -168f7 1 85 70 -FUNC 168f8 2d 0 std::pair std::make_pair(dwarf2reader::DwarfAttribute, dwarf2reader::DwarfForm) -168f8 c 144 70 -16904 21 145 70 -16925 1 145 70 -16926 c 202 66 -16932 a 203 66 -FUNC 1693c 25 0 std::list, std::allocator > >::begin() const -1693c c 588 70 -16948 19 589 66 -16961 1 589 66 -FUNC 16962 23 0 std::list, std::allocator > >::end() const -16962 c 605 70 -1696e 17 606 66 -16985 1 606 66 -16986 c 65 68 -16992 2 65 68 -16994 c 72 68 -169a0 2 72 68 -169a2 c 97 69 -169ae d 97 69 -169bb 1 97 69 -169bc c 105 69 -169c8 d 105 69 -169d5 1 105 69 -169d6 c 105 69 -169e2 d 105 69 -169ef 1 105 69 -169f0 c 67 68 -169fc 2 67 68 -169fe c 99 69 -16a0a 14 100 69 -16a1e c 99 69 -16a2a 14 100 69 -16a3e c 129 62 -16a4a 30 131 62 -16a7a c 65 68 -16a86 2 65 68 -16a88 c 72 68 -16a94 2 72 68 -16a96 c 97 69 -16aa2 d 97 69 -16aaf 1 97 69 -16ab0 c 105 69 -16abc d 105 69 -16ac9 1 105 69 -16aca c 105 69 -16ad6 d 105 69 -16ae3 1 105 69 -16ae4 c 67 68 -16af0 2 67 68 -16af2 c 99 69 -16afe 14 100 69 -16b12 c 99 69 -16b1e 14 100 69 -FUNC 16b32 2b 0 std::_Vector_base >::get_allocator() const -16b32 10 93 71 -16b42 1b 94 71 -16b5d 1 94 71 -16b6a 7 614 72 -16b71 1 614 72 -16b72 c 80 71 -16b7e d 80 71 -16b8b 1 80 71 -16b98 2 107 68 -FUNC 16b9a 2d 0 void std::_Destroy >(unsigned char*, unsigned char*, std::allocator) -16b9a c 171 73 -16ba6 2 173 73 -16ba8 12 174 73 -16bba b 173 73 -16bc5 2 174 73 -16bc7 1 174 73 -16bc8 c 84 71 -16bd4 2f 85 71 -16c03 2 86 71 -16c05 1 86 71 -16c06 c 96 71 -16c12 12 97 71 -16c24 2 98 71 -FUNC 16c26 1f 0 std::_List_base, std::allocator > >::_M_init() -16c26 c 338 73 -16c32 8 340 66 -16c3a b 341 66 -16c45 1 341 66 -16c46 c 105 69 -16c52 d 105 69 -16c5f 1 105 69 -16c60 c 125 66 -16c6c a 126 66 -FUNC 16c76 25 0 std::list, std::allocator > >::begin() -16c76 c 579 73 -16c82 19 580 66 -16c9b 1 580 66 -FUNC 16c9c 23 0 std::list, std::allocator > >::end() -16c9c c 597 73 -16ca8 17 597 66 -16cbf 1 597 66 -16cc0 c 603 72 -16ccc c 603 72 -FUNC 16cd8 2b 0 std::vector >::begin() const -16cd8 c 342 73 -16ce4 1f 343 71 -16d03 1 343 71 -FUNC 16d04 2c 0 std::vector >::end() const -16d04 c 360 73 -16d10 20 361 71 -16d3c 5 666 72 -16d41 1 666 72 -16d4f 31 759 72 -FUNC 16d80 3c 0 std::vector >::size() const -16d80 c 402 73 -16d8c 30 403 71 -16dbc c 603 72 -16dc8 c 603 72 -FUNC 16dd4 23 0 std::vector >::begin() -16dd4 c 333 73 -16de0 17 334 71 -16df7 1 334 71 -16e04 33 654 72 -16e37 1 654 72 -FUNC 16e38 26 0 std::vector >::end() -16e38 c 351 73 -16e44 1a 352 71 -16e6a 7 614 72 -16e71 1 614 72 -FUNC 16e72 42 0 std::vector >::operator[](unsigned long) -16e72 c 494 73 -16e7e 36 495 71 -FUNC 16eb4 13 0 std::vector >::max_size() const -16eb4 c 407 73 -16ec0 7 408 71 -16ec7 1 408 71 -16ed4 5 666 72 -16ed9 1 666 72 -16ee6 d 623 72 -16ef3 5 624 72 -16ef8 c 382 62 -16f04 d 382 62 -16f11 1 382 62 -FUNC 16f12 2b 0 std::_Deque_base >::get_allocator() const -16f12 10 360 73 -16f22 1b 361 62 -16f3d 1 361 62 -FUNC 16f3e 2d 0 std::deque >::get_allocator() const -16f3e 10 764 73 -16f4e 1d 765 62 -16f6b 1 765 62 -FUNC 16f6c 13 0 std::_Deque_iterator::operator*() const -16f6c c 134 73 -16f78 7 135 62 -16f7f 1 135 62 -16f8c 2 107 68 -16f8e c 129 62 -16f9a 30 131 62 -FUNC 16fca 2c 0 std::deque >::end() const -16fca 10 799 73 -16fda 1c 800 62 -FUNC 16ff6 2c 0 std::deque >::begin() const -16ff6 10 781 73 -17006 1c 782 62 -FUNC 17022 2e 0 std::deque >::end() -17022 10 790 73 -17032 1e 791 62 -FUNC 17050 3c 0 std::vector >::_M_range_check(unsigned long) const -17050 13 515 73 -17063 15 517 71 -17078 14 518 71 -FUNC 1708c 32 0 std::vector >::at(unsigned long) -1708c c 534 73 -17098 12 536 71 -170aa 14 537 71 -170ca 2e 104 68 -170f8 c 84 71 -17104 2f 85 71 -17133 2 86 71 -17135 1 86 71 -17136 c 96 71 -17142 12 97 71 -17154 2 98 71 -17156 c 603 72 -17162 c 603 72 -FUNC 1716e 23 0 std::vector >::begin() -1716e c 333 73 -1717a 17 334 71 -17191 1 334 71 -1719e 27 654 72 -171c5 1 654 72 -FUNC 171c6 42 0 std::vector >::operator[](unsigned long) -171c6 c 494 73 -171d2 36 495 71 -FUNC 17208 26 0 std::vector >::end() -17208 c 351 73 -17214 1a 352 71 -1723a d 94 68 -17247 1 94 68 -FUNC 17248 2f 0 std::_Vector_base >::_M_deallocate(unsigned char*, unsigned long) -17248 c 120 73 -17254 6 122 71 -1725a 1d 123 71 -17277 1 123 71 -17278 c 108 71 -17284 3a 109 71 -172be c 188 71 -172ca 12 189 71 -172dc 2 190 71 -172de c 272 71 -172ea 4b 273 71 -17335 1 273 71 -17336 13 62 74 -17349 10 62 74 -17359 a 63 74 -17363 25 64 74 -17388 1a 66 74 -173a2 13 62 74 -173b5 10 62 74 -173c5 a 63 74 -173cf 25 64 74 -173f4 1a 66 74 -1740e c 188 71 -1741a 12 189 71 -1742c 2 190 71 -1743b 31 759 72 -1746c c 65 68 -17478 2 65 68 -1747a c 103 69 -17486 d 103 69 -17493 1 103 69 -FUNC 17494 2d 0 std::list, std::allocator > >::get_allocator() const -17494 10 570 74 -174a4 1d 571 66 -174c1 1 571 66 -174ce 2e 104 68 -FUNC 174fc 20 0 std::_List_iterator >::operator!=(std::_List_iterator > const&) const -174fc c 172 74 -17508 14 173 66 -FUNC 1751c 1d 0 std::_List_const_iterator >::operator++() -1751c c 219 74 -17528 c 221 66 -17534 5 222 66 -17539 1 222 66 -FUNC 1753a 1d 0 std::_List_iterator >::operator++() -1753a c 138 74 -17546 c 140 66 -17552 5 141 66 -17557 1 141 66 -FUNC 17558 16 0 std::_List_const_iterator >::operator*() const -17558 c 211 74 -17564 a 212 66 -FUNC 1756e 16 0 std::_List_iterator >::operator*() const -1756e c 130 74 -1757a a 131 66 -FUNC 17584 20 0 std::_List_const_iterator >::operator==(std::_List_const_iterator > const&) const -17584 c 249 74 -17590 14 250 66 -FUNC 175a4 35 0 bool __gnu_cxx::operator!= > >(__gnu_cxx::__normal_iterator > > const&, __gnu_cxx::__normal_iterator > > const&) -175a4 d 699 74 -175b1 28 700 72 -175d9 1 700 72 -FUNC 175da 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator > >, std::allocator >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, std::allocator) -175da c 171 74 -175e6 2 173 73 -175e8 1a 174 73 -17602 21 173 73 -17623 2 174 73 -17625 1 174 73 -17626 c 127 62 -17632 29 127 62 -1765b 1 127 62 -1765c c 388 62 -17668 41 389 62 -176a9 2 390 62 -176ab 1 390 62 -176b8 d 94 68 -176c5 1 94 68 -FUNC 176c6 20 0 bool std::operator==(std::_Deque_iterator const&, std::_Deque_iterator const&) -176c6 c 243 74 -176d2 14 244 62 -FUNC 176e6 26 0 bool std::operator!=(std::_Deque_iterator const&, std::_Deque_iterator const&) -176e6 c 256 74 -176f2 1a 257 62 -FUNC 1770c 1a 0 std::_Deque_iterator::_S_buffer_size() -1770c c 106 74 -17718 e 107 62 -FUNC 17726 3e 0 std::_Deque_iterator::_M_set_node(unsigned long long**) -17726 d 229 74 -17733 9 231 62 -1773c b 232 62 -17747 1d 233 62 -FUNC 17764 50 0 std::_Deque_iterator::operator++() -17764 c 142 74 -17770 d 144 62 -1777d f 145 62 -1778c 18 147 62 -177a4 b 148 62 -177af 5 150 62 -FUNC 177b4 4b 0 void std::_Destroy, std::allocator >(std::_Deque_iterator, std::_Deque_iterator, std::allocator) -177b4 c 171 74 -177c0 2 173 73 -177c2 1a 174 73 -177dc 21 173 73 -177fd 2 174 73 -177ff 1 174 73 -FUNC 17800 50 0 std::_Deque_iterator::operator--() -17800 c 162 74 -1780c f 164 62 -1781b 18 166 62 -17833 b 167 62 -1783e d 169 62 -1784b 5 170 62 -FUNC 17850 39 0 std::deque >::back() -17850 c 988 74 -1785c 15 990 62 -17871 b 991 62 -1787c d 992 62 -17889 1 992 62 -FUNC 1788a 19 0 std::stack > >::top() -1788a c 163 75 -17896 d 166 75 -178a3 1 166 75 -FUNC 178a4 66 0 std::_Deque_iterator::difference_type std::operator-(std::_Deque_iterator const&, std::_Deque_iterator const&) -178a4 d 328 75 -178b1 59 333 62 -FUNC 1790a 26 0 std::deque >::size() const -1790a c 840 75 -17916 1a 841 62 -1793c 36 662 72 -1797e 23 650 72 -179a1 1 650 72 -179a2 c 67 68 -179ae 2 67 68 -179b0 c 99 69 -179bc 14 100 69 -179d0 c 303 66 -179dc 12 304 66 -179ee 2 305 66 -179f0 c 326 66 -179fc 2f 327 66 -17a2b d 328 66 -17a38 c 457 66 -17a44 14 458 66 -17a58 c 211 74 -17a64 2d 211 74 -17a91 1 211 74 -17a9e 7 98 68 -17aa5 1 98 68 -17ab2 1d 85 68 -17acf 5 86 68 -17ad4 17 88 68 -17aeb 1 88 68 -FUNC 17aec 2a 0 std::_Vector_base >::_M_allocate(unsigned long) -17aec c 116 75 -17af8 1e 117 71 -17b22 d 94 68 -17b2f 1 94 68 -FUNC 17b30 34 0 std::_Deque_base >::_M_deallocate_node(unsigned long long*) -17b30 c 402 75 -17b3c 28 403 62 -FUNC 17b64 38 0 std::_Deque_base >::_M_destroy_nodes(unsigned long long**, unsigned long long**) -17b64 c 504 75 -17b70 8 506 62 -17b78 14 507 62 -17b8c e 506 62 -17b9a 2 507 62 -FUNC 17b9c 62 0 std::deque >::_M_pop_back_aux() -17b9c c 391 76 -17ba8 15 393 76 -17bbd 1b 394 76 -17bd8 f 395 76 -17be7 17 396 76 -FUNC 17bfe 4f 0 std::deque >::pop_back() -17bfe c 1081 76 -17c0a 10 1083 62 -17c1a f 1086 62 -17c29 17 1087 62 -17c40 d 1090 62 -17c4d 1 1090 62 -FUNC 17c4e 19 0 std::stack > >::pop() -17c4e c 205 76 -17c5a d 208 75 -17c67 1 208 75 -17c68 c 72 68 -17c74 2 72 68 -17c76 c 105 69 -17c82 d 105 69 -17c8f 1 105 69 -17c90 c 603 72 -17c9c c 603 72 -FUNC 17ca8 2b 0 std::vector >::begin() const -17ca8 c 342 76 -17cb4 1f 343 71 -17cd3 1 343 71 -FUNC 17cd4 2c 0 std::vector >::end() const -17cd4 c 360 76 -17ce0 20 361 71 -17d0c 5 666 72 -17d11 1 666 72 -17d1f 28 759 72 -17d47 1 759 72 -FUNC 17d48 3c 0 std::vector >::size() const -17d48 c 402 76 -17d54 30 403 71 -17d90 d 623 72 -17d9d 5 624 72 -17dae 5 666 72 -17db3 1 666 72 -FUNC 17db4 35 0 bool __gnu_cxx::operator!= > >(__gnu_cxx::__normal_iterator > > const&, __gnu_cxx::__normal_iterator > > const&) -17db4 d 699 76 -17dc1 28 700 72 -17de9 1 700 72 -FUNC 17dea 4b 0 void std::_Destroy<__gnu_cxx::__normal_iterator > >, std::allocator >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, std::allocator) -17dea c 171 76 -17df6 2 173 73 -17df8 1a 174 73 -17e12 21 173 73 -17e33 2 174 73 -17e35 1 174 73 -17e43 28 759 72 -17e6b 1 759 72 -17e78 2a 662 72 -FUNC 17ea2 13 0 std::vector >::max_size() const -17ea2 c 407 76 -17eae 7 408 71 -17eb5 1 408 71 -17ec2 16 650 72 -17ee4 7 98 68 -17eeb 1 98 68 -17ef8 1d 85 68 -17f15 5 86 68 -17f1a 10 88 68 -FUNC 17f2a 29 0 std::_List_base, std::allocator > >::_M_get_node() -17f2a c 311 76 -17f36 1d 312 66 -17f53 1 312 66 -FUNC 17f54 5f 0 std::list, std::allocator > >::_M_create_node(std::pair const&) -17f54 d 435 76 -17f61 e 437 66 -17f6f 3c 440 66 -17fab 8 447 66 -17fb3 1 447 66 -FUNC 17fb4 35 0 std::list, std::allocator > >::_M_insert(std::_List_iterator >, std::pair const&) -17fb4 c 1149 76 -17fc0 15 1151 66 -17fd5 14 1152 66 -17fe9 1 1152 66 -FUNC 17fea 52 0 void std::list, std::allocator > >::_M_insert_dispatch > >(std::_List_iterator >, std::_List_const_iterator >, std::_List_const_iterator >, __false_type) -17fea c 1126 66 -17ff6 2 1128 66 -17ff8 21 1129 66 -18019 21 1128 66 -1803a 2 1129 66 -FUNC 1803c 36 0 void std::list, std::allocator > >::insert > >(std::_List_iterator >, std::_List_const_iterator >, std::_List_const_iterator >) -1803c c 838 66 -18048 2a 842 66 -18072 e 491 66 -18080 32 492 66 -180b2 64 493 66 -18116 c 211 74 -18122 3d 211 74 -1815f 1 211 74 -1816d 5c 104 68 -181c9 1 104 68 -FUNC 181ca 31 0 std::list, std::allocator > >::push_back(std::pair const&) -181ca c 772 76 -181d6 25 773 66 -181fb 1 773 66 -FUNC 181fc 69 0 void std::_Construct(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev const&) -181fc d 77 76 -18209 5c 81 73 -18265 1 81 73 -18272 7 98 68 -18279 1 98 68 -18286 1d 85 68 -182a3 5 86 68 -182a8 10 88 68 -182b8 c 65 68 -182c4 2 65 68 -182c6 c 103 69 -182d2 d 103 69 -182df 1 103 69 -FUNC 182e0 4d 0 std::_Deque_base >::_M_get_map_allocator() const -182e0 11 394 76 -182f1 3c 395 62 -1832d 1 395 62 -FUNC 1832e 75 0 std::_Deque_base >::_M_allocate_map(unsigned long) -1832e d 406 76 -1833b 68 407 62 -183a3 1 407 62 -FUNC 183a4 47 0 std::_Deque_base >::_M_deallocate_map(unsigned long long**, unsigned long) -183a4 c 410 76 -183b0 3b 411 62 -183eb 1 411 62 -183ec c 424 62 -183f8 9 426 62 -18401 22 428 62 -18423 2b 430 62 -1844e c 714 62 -1845a 70 715 62 -184ca c 111 75 -184d6 d 111 75 -184e3 1 111 75 -184e4 c 259 67 -184f0 26 259 67 -18522 7 98 68 -18529 1 98 68 -18536 1d 85 68 -18553 5 86 68 -18558 10 88 68 -FUNC 18568 33 0 std::_Deque_base >::_M_allocate_node() -18568 c 398 76 -18574 27 399 62 -1859b 1 399 62 -FUNC 1859c 82 0 std::_Deque_base >::_M_create_nodes(unsigned long long**, unsigned long long**) -1859c d 486 76 -185a9 8 491 62 -185b1 12 492 62 -185c3 13 491 62 -185d6 b 494 62 -185e1 19 496 62 -185fa b 497 62 -18605 13 494 62 -18618 6 497 62 -FUNC 1861e 17b 0 std::_Deque_base >::_M_initialize_map(unsigned long) -1861e d 447 76 -1862b 1e 450 62 -18649 2a 452 62 -18673 1c 454 62 -1868f 19 462 62 -186a8 c 463 62 -186b4 1e 466 62 -186d2 b 467 62 -186dd 1e 469 62 -186fb 9 470 62 -18704 a 471 62 -1870e b 472 62 -18719 13 467 62 -1872c 15 475 62 -18741 18 476 62 -18759 c 477 62 -18765 34 478 62 -18799 1 478 62 -1879a d 366 62 -187a7 12 367 62 -187b9 39 368 62 -187f2 c 645 62 -187fe 1c 646 62 -FUNC 1881a 4d 0 void std::__fill::fill<__gnu_cxx::__normal_iterator > >, unsigned char>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char const&) -1881a c 539 61 -18826 9 541 61 -1882f 2 542 61 -18831 13 543 61 -18844 21 542 61 -18865 2 543 61 -18867 1 543 61 -FUNC 18868 2b 0 void std::fill<__gnu_cxx::__normal_iterator > >, unsigned char>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char const&) -18868 c 560 76 -18874 4 567 61 -18878 1b 568 61 -18893 1 568 61 -FUNC 18894 6a 0 std::list, std::allocator > >::_M_erase(std::_List_iterator >) -18894 d 1157 76 -188a1 b 1159 66 -188ac 6 1160 66 -188b2 35 1161 66 -188e7 17 1162 66 -FUNC 188fe 37 0 std::list, std::allocator > >::erase(std::_List_iterator >) -188fe c 95 77 -1890a 14 97 77 -1891e 12 98 77 -18930 5 99 77 -18935 1 99 77 -FUNC 18936 3e 0 std::list, std::allocator > >::erase(std::_List_iterator >, std::_List_iterator >) -18936 c 883 77 -18942 2 885 66 -18944 15 886 66 -18959 16 885 66 -1896f 5 887 66 -FUNC 18974 129 0 std::list, std::allocator > >::operator=(std::list, std::allocator > > const&) -18974 e 120 77 -18982 c 122 77 -1898e e 124 77 -1899c e 125 77 -189aa e 126 77 -189b8 e 127 77 -189c6 2 128 77 -189c8 20 130 77 -189e8 5a 128 77 -18a42 16 131 77 -18a58 1b 132 77 -18a73 20 134 77 -18a93 a 136 77 -18a9d 1 136 77 -FUNC 18a9e 4c 0 dwarf2reader::CompilationUnit::Abbrev::operator=(dwarf2reader::CompilationUnit::Abbrev const&) -18a9e c 211 77 -18aaa 40 211 74 -FUNC 18aea 52 0 dwarf2reader::CompilationUnit::Abbrev* std::__copy::copy(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -18aea c 280 61 -18af6 1a 283 61 -18b10 12 285 61 -18b22 4 286 61 -18b26 6 287 61 -18b2c b 283 61 -18b37 5 289 61 -FUNC 18b3c 2b 0 dwarf2reader::CompilationUnit::Abbrev* std::__copy_aux(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -18b3c c 307 77 -18b48 4 315 61 -18b4c 1b 317 61 -18b67 1 317 61 -18b76 56 354 61 -18bd8 4 384 61 -18bdc 4 385 61 -18be0 1b 387 61 -18bfb 1 387 61 -FUNC 18bfc ac 0 std::vector >::erase(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >) -18bfc d 122 78 -18c09 26 124 78 -18c2f 43 125 78 -18c72 2e 126 78 -18ca0 8 127 78 -FUNC 18ca8 54 0 dwarf2reader::CompilationUnit::Abbrev* std::__copy_backward::copy_b(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -18ca8 c 408 61 -18cb4 1a 411 61 -18cce 1e 412 61 -18cec b 411 61 -18cf7 5 413 61 -FUNC 18cfc 2b 0 dwarf2reader::CompilationUnit::Abbrev* std::__copy_backward_aux(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -18cfc c 432 78 -18d08 4 440 61 -18d0c 1b 443 61 -18d27 1 443 61 -18d36 56 482 61 -18d98 4 514 61 -18d9c 4 515 61 -18da0 1b 517 61 -18dbb 1 517 61 -FUNC 18dbc 4d 0 void std::__fill::fill<__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev const&) -18dbc c 526 61 -18dc8 2 528 61 -18dca 1c 529 61 -18de6 21 528 61 -18e07 2 529 61 -18e09 1 529 61 -FUNC 18e0a 2b 0 void std::fill<__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev const&) -18e0a c 560 78 -18e16 4 567 61 -18e1a 1b 568 61 -18e35 1 568 61 -FUNC 18e36 3f 0 unsigned char* std::__copy::copy(unsigned char const*, unsigned char const*, unsigned char*) -18e36 c 298 61 -18e42 22 300 61 -18e64 11 301 61 -18e75 1 301 61 -FUNC 18e76 2b 0 unsigned char* std::__copy_aux(unsigned char*, unsigned char*, unsigned char*) -18e76 c 307 78 -18e82 4 315 61 -18e86 1b 317 61 -18ea1 1 317 61 -18eb0 56 354 61 -18f12 4 384 61 -18f16 4 385 61 -18f1a 1b 387 61 -18f35 1 387 61 -FUNC 18f36 a0 0 std::vector >::erase(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >) -18f36 d 122 78 -18f43 26 124 78 -18f69 43 125 78 -18fac 22 126 78 -18fce 8 127 78 -18fe2 7 98 68 -18fe9 1 98 68 -18ff6 1d 85 68 -19013 5 86 68 -19018 d 88 68 -19025 1 88 68 -FUNC 19026 2a 0 std::_Vector_base >::_M_allocate(unsigned long) -19026 c 116 78 -19032 1e 117 71 -1905c 1b 74 79 -19077 1 74 79 -19084 23 113 79 -190a7 1 113 79 -190b4 1b 254 79 -190cf 1 254 79 -FUNC 190d0 19 0 void std::_Destroy(dwarf2reader::CompilationUnit::Abbrev*) -190d0 c 106 79 -190dc d 107 73 -190e9 1 107 73 -FUNC 190ea 44 0 void std::__destroy_aux<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, __false_type) -190ea c 119 79 -190f6 2 121 73 -190f8 13 122 73 -1910b 21 121 73 -1912c 2 122 73 -FUNC 1912e 28 0 void std::_Destroy<__gnu_cxx::__normal_iterator > > >(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >) -1912e c 148 79 -1913a 1c 155 73 -FUNC 19156 8d 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&, __false_type) -19156 d 188 79 -19163 6 190 79 -19169 2 193 79 -1916b 1c 194 79 -19187 1b 193 79 -191a2 b 196 79 -191ad 12 198 79 -191bf b 199 79 -191ca 13 196 79 -191dd 6 199 79 -191e3 1 199 79 -FUNC 191e4 2f 0 void std::uninitialized_fill_n<__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&) -191e4 c 214 79 -191f0 23 218 79 -19213 1 218 79 -FUNC 19214 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&, std::allocator) -19214 c 308 79 -19220 1b 310 79 -1923b 1 310 79 -19249 6 82 79 -1924f 2 85 79 -19251 24 86 79 -19275 2c 85 79 -192a1 b 87 79 -192ac b 89 79 -192b7 12 91 79 -192c9 b 92 79 -192d4 13 89 79 -192e7 9 92 79 -192fc 23 113 79 -1931f 1 113 79 -1932c 1b 254 79 -19347 1 254 79 -FUNC 19348 409 0 std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev const&) -19348 14 249 79 -1935c 14 251 78 -19370 22 253 78 -19392 f 255 78 -193a1 12 256 78 -193b3 55 257 78 -19408 4b 260 78 -19453 e 264 78 -19461 15 265 78 -19476 e 266 78 -19484 1d 271 78 -194a1 8 272 78 -194a9 e 273 78 -194b7 27 275 78 -194de 6 276 78 -194e4 55 279 78 -19539 25 284 78 -1955e b 285 78 -19569 4f 286 78 -195b8 3 284 78 -195bb 13 279 78 -195ce e 286 78 -195dc 4d 298 78 -19629 36 299 78 -1965f 12 302 78 -19671 13 303 78 -19684 2e 304 78 -196b2 13 286 78 -196c5 b 292 78 -196d0 39 294 78 -19709 23 295 78 -1972c b 296 78 -19737 13 292 78 -1974a 7 304 78 -19751 1 304 78 -FUNC 19752 70 0 std::vector >::push_back(dwarf2reader::CompilationUnit::Abbrev const&) -19752 c 602 79 -1975e 10 604 71 -1976e 1e 606 71 -1978c 11 607 71 -1979d 25 610 71 -FUNC 197c2 50 0 unsigned char* std::__copy_backward::copy_b(unsigned char const*, unsigned char const*, unsigned char*) -197c2 d 422 61 -197cf f 424 61 -197de 24 425 61 -19802 10 426 61 -FUNC 19812 2b 0 unsigned char* std::__copy_backward_aux(unsigned char*, unsigned char*, unsigned char*) -19812 c 432 79 -1981e 4 440 61 -19822 1b 443 61 -1983d 1 443 61 -1984c 56 482 61 -198ae 4 514 61 -198b2 4 515 61 -198b6 1b 517 61 -198d1 1 517 61 -FUNC 198d2 32 0 unsigned char* std::fill_n(unsigned char*, unsigned long, unsigned char const&) -198d2 c 647 79 -198de 1e 649 61 -198fc 8 650 61 -FUNC 19904 27 0 void std::__uninitialized_fill_n_aux(unsigned char*, unsigned long, unsigned char const&, __true_type) -19904 c 182 79 -19910 1b 183 79 -1992b 1 183 79 -FUNC 1992c 2f 0 void std::uninitialized_fill_n(unsigned char*, unsigned long, unsigned char const&) -1992c c 214 79 -19938 23 218 79 -1995b 1 218 79 -FUNC 1995c 27 0 void std::__uninitialized_fill_n_a(unsigned char*, unsigned long, unsigned char const&, std::allocator) -1995c c 308 79 -19968 1b 310 79 -19983 1 310 79 -FUNC 19984 27 0 void std::__destroy_aux(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, __false_type) -19984 c 119 79 -19990 2 121 73 -19992 b 122 73 -1999d c 121 73 -199a9 2 122 73 -199ab 1 122 73 -FUNC 199ac 28 0 void std::_Destroy(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -199ac c 148 79 -199b8 1c 155 73 -FUNC 199d4 88 0 dwarf2reader::CompilationUnit::Abbrev* std::__uninitialized_copy_aux(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, __false_type) -199d4 d 80 79 -199e1 6 82 79 -199e7 2 85 79 -199e9 12 86 79 -199fb 12 85 79 -19a0d b 87 79 -19a18 b 89 79 -19a23 12 91 79 -19a35 b 92 79 -19a40 13 89 79 -19a53 9 92 79 -FUNC 19a5c 2f 0 dwarf2reader::CompilationUnit::Abbrev* std::uninitialized_copy(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*) -19a5c c 108 79 -19a68 23 113 79 -19a8b 1 113 79 -FUNC 19a8c 27 0 dwarf2reader::CompilationUnit::Abbrev* std::__uninitialized_copy_a(dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev*, std::allocator) -19a8c c 252 79 -19a98 1b 254 79 -19ab3 1 254 79 -FUNC 19ab4 7e 0 void std::__uninitialized_fill_n_aux(dwarf2reader::CompilationUnit::Abbrev*, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&, __false_type) -19ab4 d 188 79 -19ac1 6 190 79 -19ac7 2 193 79 -19ac9 12 194 79 -19adb 16 193 79 -19af1 b 196 79 -19afc 12 198 79 -19b0e b 199 79 -19b19 13 196 79 -19b2c 6 199 79 -FUNC 19b32 2f 0 void std::uninitialized_fill_n(dwarf2reader::CompilationUnit::Abbrev*, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&) -19b32 c 214 79 -19b3e 23 218 79 -19b61 1 218 79 -FUNC 19b62 27 0 void std::__uninitialized_fill_n_a(dwarf2reader::CompilationUnit::Abbrev*, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&, std::allocator) -19b62 c 308 79 -19b6e 1b 310 79 -19b89 1 310 79 -FUNC 19b8a a5 0 dwarf2reader::CompilationUnit::Abbrev* std::__uninitialized_copy_aux<__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*, __false_type) -19b8a d 80 79 -19b97 6 82 79 -19b9d 2 85 79 -19b9f 1a 86 79 -19bb9 27 85 79 -19be0 b 87 79 -19beb b 89 79 -19bf6 12 91 79 -19c08 b 92 79 -19c13 13 89 79 -19c26 9 92 79 -19c2f 1 92 79 -FUNC 19c30 2f 0 dwarf2reader::CompilationUnit::Abbrev* std::uninitialized_copy<__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*) -19c30 c 108 79 -19c3c 23 113 79 -19c5f 1 113 79 -FUNC 19c60 27 0 dwarf2reader::CompilationUnit::Abbrev* std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*, dwarf2reader::CompilationUnit::Abbrev>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, dwarf2reader::CompilationUnit::Abbrev*, std::allocator) -19c60 c 252 79 -19c6c 1b 254 79 -19c87 1 254 79 -FUNC 19c88 5f8 0 std::vector >::_M_fill_insert(__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&) -19c88 15 311 79 -19c9d b 313 78 -19ca8 2a 315 78 -19cd2 12 318 78 -19ce4 23 319 78 -19d07 15 320 78 -19d1c c 321 78 -19d28 5a 323 78 -19d82 1c 327 78 -19d9e 35 328 78 -19dd3 16 323 78 -19de9 30 330 78 -19e19 10 343 78 -19e29 48 334 78 -19e71 21 338 78 -19e92 3d 339 78 -19ecf 13 334 78 -19ee2 b 339 78 -19eed 1c 342 78 -19f09 1e 343 78 -19f27 13 339 78 -19f3a 24 343 78 -19f5e e 348 78 -19f6c 1e 349 78 -19f8a e 350 78 -19f98 1d 353 78 -19fb5 8 354 78 -19fbd e 355 78 -19fcb 27 357 78 -19ff2 6 358 78 -19ff8 4d 361 78 -1a045 40 365 78 -1a085 18 367 78 -1a09d 44 368 78 -1a0e1 3 365 78 -1a0e4 19 361 78 -1a0fd 13 365 78 -1a110 e 368 78 -1a11e 3e 379 78 -1a15c 36 381 78 -1a192 12 384 78 -1a1a4 13 385 78 -1a1b7 2e 386 78 -1a1e5 e 368 78 -1a1f3 b 372 78 -1a1fe 39 374 78 -1a237 23 376 78 -1a25a b 377 78 -1a265 13 372 78 -1a278 8 386 78 -FUNC 1a280 2e 0 std::vector >::insert(__gnu_cxx::__normal_iterator > >, unsigned long, dwarf2reader::CompilationUnit::Abbrev const&) -1a280 c 657 79 -1a28c 22 658 71 -FUNC 1a2ae ab 0 std::vector >::resize(unsigned long, dwarf2reader::CompilationUnit::Abbrev const&) -1a2ae d 422 79 -1a2bb 15 424 71 -1a2d0 48 425 71 -1a318 41 427 71 -1a359 1 427 71 -FUNC 1a35a 63 0 std::vector >::resize(unsigned long) -1a35a d 441 79 -1a367 56 442 71 -1a3bd 1 442 71 -FUNC 1a3be 13 0 std::_Deque_iterator::operator*() const -1a3be c 134 79 -1a3ca 7 135 62 -1a3d1 1 135 62 -FUNC 1a3d2 3f 0 unsigned long long** std::__copy::copy(unsigned long long* const*, unsigned long long* const*, unsigned long long**) -1a3d2 c 298 61 -1a3de 22 300 61 -1a400 11 301 61 -1a411 1 301 61 -FUNC 1a412 2b 0 unsigned long long** std::__copy_aux(unsigned long long**, unsigned long long**, unsigned long long**) -1a412 c 307 79 -1a41e 4 315 61 -1a422 1b 317 61 -1a43d 1 317 61 -FUNC 1a43e 27 0 unsigned long long** std::__copy_normal::copy_n(unsigned long long**, unsigned long long**, unsigned long long**) -1a43e c 325 61 -1a44a 1b 326 61 -1a465 1 326 61 -FUNC 1a466 2f 0 unsigned long long** std::copy(unsigned long long**, unsigned long long**, unsigned long long**) -1a466 c 376 79 -1a472 4 384 61 -1a476 4 385 61 -1a47a 1b 387 61 -1a495 1 387 61 -FUNC 1a496 60 0 unsigned long long** std::__copy_backward::copy_b(unsigned long long* const*, unsigned long long* const*, unsigned long long**) -1a496 d 422 61 -1a4a3 12 424 61 -1a4b5 2e 425 61 -1a4e3 13 426 61 -FUNC 1a4f6 2b 0 unsigned long long** std::__copy_backward_aux(unsigned long long**, unsigned long long**, unsigned long long**) -1a4f6 c 432 79 -1a502 4 440 61 -1a506 1b 443 61 -1a521 1 443 61 -FUNC 1a522 27 0 unsigned long long** std::__copy_backward_normal::copy_b_n(unsigned long long**, unsigned long long**, unsigned long long**) -1a522 c 451 61 -1a52e 1b 452 61 -1a549 1 452 61 -FUNC 1a54a 2f 0 unsigned long long** std::copy_backward(unsigned long long**, unsigned long long**, unsigned long long**) -1a54a c 504 79 -1a556 4 514 61 -1a55a 4 515 61 -1a55e 1b 517 61 -1a579 1 517 61 -FUNC 1a57a 1df 0 std::deque >::_M_reallocate_map(unsigned long, bool) -1a57a 13 723 79 -1a58d 1b 726 76 -1a5a8 9 727 76 -1a5b1 13 730 76 -1a5c4 39 732 76 -1a5fd b 735 76 -1a608 27 736 76 -1a62f 2f 740 76 -1a65e 26 748 76 -1a684 15 750 76 -1a699 36 751 76 -1a6cf 22 753 76 -1a6f1 1e 756 76 -1a70f 8 758 76 -1a717 9 759 76 -1a720 15 762 76 -1a735 24 763 76 -1a759 1 763 76 -FUNC 1a75a 59 0 std::deque >::_M_reserve_map_at_back(unsigned long) -1a75a e 1443 79 -1a768 2a 1445 62 -1a792 21 1447 62 -1a7b3 1 1447 62 -FUNC 1a7b4 8c 0 std::deque >::_M_push_back_aux(unsigned long long const&) -1a7b4 c 345 79 -1a7c0 e 347 76 -1a7ce 13 348 76 -1a7e1 18 349 76 -1a7f9 1e 352 76 -1a817 1b 353 76 -1a832 c 355 76 -1a83e 2 360 76 -FUNC 1a840 62 0 std::deque >::push_back(unsigned long long const&) -1a840 c 1039 79 -1a84c 13 1041 62 -1a85f 1e 1044 62 -1a87d 11 1045 62 -1a88e 14 1048 62 -FUNC 1a8a2 20 0 std::stack > >::push(unsigned long long const&) -1a8a2 c 190 79 -1a8ae 14 191 75 -FUNC 1a8c2 27 0 unsigned char* std::__copy_normal::copy_n(unsigned char*, unsigned char*, unsigned char*) -1a8c2 c 325 61 -1a8ce 1b 326 61 -1a8e9 1 326 61 -FUNC 1a8ea 2f 0 unsigned char* std::copy(unsigned char*, unsigned char*, unsigned char*) -1a8ea c 376 79 -1a8f6 4 384 61 -1a8fa 4 385 61 -1a8fe 1b 387 61 -1a919 1 387 61 -FUNC 1a91a 27 0 unsigned char* std::__uninitialized_copy_aux(unsigned char*, unsigned char*, unsigned char*, __true_type) -1a91a c 73 79 -1a926 1b 74 79 -1a941 1 74 79 -FUNC 1a942 2f 0 unsigned char* std::uninitialized_copy(unsigned char*, unsigned char*, unsigned char*) -1a942 c 108 79 -1a94e 23 113 79 -1a971 1 113 79 -FUNC 1a972 27 0 unsigned char* std::__uninitialized_copy_a(unsigned char*, unsigned char*, unsigned char*, std::allocator) -1a972 c 252 79 -1a97e 1b 254 79 -1a999 1 254 79 -FUNC 1a99a 40 0 unsigned char* std::__copy_normal::copy_n<__gnu_cxx::__normal_iterator > >, unsigned char*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char*) -1a99a d 334 61 -1a9a7 33 335 61 -FUNC 1a9da 2f 0 unsigned char* std::copy<__gnu_cxx::__normal_iterator > >, unsigned char*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char*) -1a9da c 376 79 -1a9e6 4 384 61 -1a9ea 4 385 61 -1a9ee 1b 387 61 -1aa09 1 387 61 -FUNC 1aa0a 27 0 unsigned char* std::__uninitialized_copy_aux<__gnu_cxx::__normal_iterator > >, unsigned char*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char*, __true_type) -1aa0a c 73 79 -1aa16 1b 74 79 -1aa31 1 74 79 -FUNC 1aa32 2f 0 unsigned char* std::uninitialized_copy<__gnu_cxx::__normal_iterator > >, unsigned char*>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char*) -1aa32 c 108 79 -1aa3e 23 113 79 -1aa61 1 113 79 -FUNC 1aa62 27 0 unsigned char* std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator > >, unsigned char*, unsigned char>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, unsigned char*, std::allocator) -1aa62 c 252 79 -1aa6e 1b 254 79 -1aa89 1 254 79 -1aa96 9 616 61 -1aa9f 2 617 61 -1aaa1 13 618 61 -1aab4 16 617 61 -1aaca 5 619 61 -1aacf 1 619 61 -1aadc 4 641 61 -1aae0 1b 642 61 -1aafb 1 642 61 -FUNC 1aafc 27 0 void std::__uninitialized_fill_n_aux<__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char>(__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char const&, __true_type) -1aafc c 182 79 -1ab08 1b 183 79 -1ab23 1 183 79 -FUNC 1ab24 2f 0 void std::uninitialized_fill_n<__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char>(__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char const&) -1ab24 c 214 79 -1ab30 23 218 79 -1ab53 1 218 79 -FUNC 1ab54 27 0 void std::__uninitialized_fill_n_a<__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char, unsigned char>(__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char const&, std::allocator) -1ab54 c 308 79 -1ab60 1b 310 79 -1ab7b 1 310 79 -FUNC 1ab7c 45a 0 std::vector >::_M_fill_insert(__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char const&) -1ab7c 14 311 79 -1ab90 b 313 78 -1ab9b 21 315 78 -1abbc 9 318 78 -1abc5 23 319 78 -1abe8 15 320 78 -1abfd c 321 78 -1ac09 4e 323 78 -1ac57 11 327 78 -1ac68 30 328 78 -1ac98 35 330 78 -1accd 48 334 78 -1ad15 14 338 78 -1ad29 43 339 78 -1ad6c 11 342 78 -1ad7d 1e 343 78 -1ad9b e 348 78 -1ada9 1e 349 78 -1adc7 e 350 78 -1add5 1d 353 78 -1adf2 8 354 78 -1adfa e 355 78 -1ae08 27 357 78 -1ae2f 6 358 78 -1ae35 4d 361 78 -1ae82 40 365 78 -1aec2 18 367 78 -1aeda 4d 368 78 -1af27 3e 379 78 -1af65 2d 381 78 -1af92 12 384 78 -1afa4 13 385 78 -1afb7 1f 386 78 -FUNC 1afd6 2e 0 std::vector >::insert(__gnu_cxx::__normal_iterator > >, unsigned long, unsigned char const&) -1afd6 c 657 79 -1afe2 22 658 71 -FUNC 1b004 ab 0 std::vector >::resize(unsigned long, unsigned char const&) -1b004 d 422 79 -1b011 15 424 71 -1b026 48 425 71 -1b06e 41 427 71 -1b0af 1 427 71 -FUNC 1b0b0 2b 0 std::vector >::resize(unsigned long) -1b0b0 c 441 79 -1b0bc 1f 442 71 -1b0db 1 442 71 -FUNC 1b0dc 1a 0 std::_Deque_iterator::_S_buffer_size() -1b0dc c 106 79 -1b0e8 e 107 62 -FUNC 1b0f6 66 0 std::_Deque_iterator::difference_type std::operator-(std::_Deque_iterator const&, std::_Deque_iterator const&) -1b0f6 d 328 79 -1b103 59 333 62 -FUNC 1b15c 3e 0 std::_Deque_iterator::_M_set_node(unsigned long long**) -1b15c d 229 79 -1b169 9 231 62 -1b172 b 232 62 -1b17d 1d 233 62 -FUNC 1b19a 50 0 std::_Deque_iterator::operator++() -1b19a c 142 79 -1b1a6 d 144 62 -1b1b3 f 145 62 -1b1c2 18 147 62 -1b1da b 148 62 -1b1e5 5 150 62 -FUNC 1b1ea 84 0 std::_Deque_iterator std::__copy::copy, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator) -1b1ea e 280 61 -1b1f8 17 283 61 -1b20f 20 285 61 -1b22f b 286 61 -1b23a b 287 61 -1b245 b 283 61 -1b250 1e 289 61 -FUNC 1b26e 7e 0 std::_Deque_iterator std::__copy_aux, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator) -1b26e 11 307 79 -1b27f 4 315 61 -1b283 69 317 61 -FUNC 1b2ec 7a 0 std::_Deque_iterator std::__copy_normal::copy_n, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator) -1b2ec 11 325 61 -1b2fd 69 326 61 -FUNC 1b366 82 0 std::_Deque_iterator std::copy, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator) -1b366 11 376 79 -1b377 4 384 61 -1b37b 4 385 61 -1b37f 69 387 61 -FUNC 1b3e8 7a 0 std::_Deque_iterator std::__uninitialized_copy_aux, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator, __true_type) -1b3e8 11 73 79 -1b3f9 69 74 79 -FUNC 1b462 82 0 std::_Deque_iterator std::uninitialized_copy, std::_Deque_iterator >(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator) -1b462 11 108 79 -1b473 71 113 79 -FUNC 1b4e4 7a 0 std::_Deque_iterator std::__uninitialized_copy_a, std::_Deque_iterator, unsigned long long>(std::_Deque_iterator, std::_Deque_iterator, std::_Deque_iterator, std::allocator) -1b4e4 11 252 79 -1b4f5 69 254 79 -1b55e 10 679 62 -1b56e 64 680 62 -1b5d2 e8 681 62 -1b6ba c 143 75 -1b6c6 14 144 75 -1b6da 6 144 75 -FUNC 1b6e0 4d 0 __eprintf -1b6e0 6 1826 80 -1b6e6 3 1832 80 -1b6e9 c 1826 80 -1b6f5 29 1832 80 -1b71e a 1837 80 -1b728 5 1838 80 -1b72d e8d3 1838 80 diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/ucontext_compat.h b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/ucontext_compat.h deleted file mode 100644 index 1e4b752e5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/ucontext_compat.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_ -#define CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_ - -#include - -// The purpose of this file is to work around the fact that ucontext_t's -// uc_mcontext member is an mcontext_t rather than an mcontext64_t on ARM64. -#if defined(__aarch64__) -// doesn't include the below file. -#include -typedef ucontext64_t breakpad_ucontext_t; -#define breakpad_uc_mcontext uc_mcontext64 -#else -typedef ucontext_t breakpad_ucontext_t; -#define breakpad_uc_mcontext uc_mcontext -#endif // defined(__aarch64__) - -#endif // CLIENT_MAC_HANDLER_UCONTEXT_COMPAT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/Breakpad.xib b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/Breakpad.xib deleted file mode 100644 index 7966f895c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/Breakpad.xib +++ /dev/null @@ -1,1140 +0,0 @@ - - - - 1050 - 10F569 - 762 - 1038.29 - 461.00 - - YES - - YES - - - YES - - - - YES - - - - YES - - - YES - - - - YES - - Reporter - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{72, 251}, {490, 489}} - 536871936 - - NSWindow - - {1.79769e+308, 1.79769e+308} - {72, 5} - - - 264 - - YES - - - 272 - - YES - - - 256 - - YES - - - 290 - {{17, 36}, {456, 70}} - - YES - - 67239424 - 272760832 - Providing your email address is optional and will allow us contact you in case we need more details. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed arcu urna, pulvinar sit amet, tincidunt ac, fermentum ut, ligula. Quisque mi. Duis lectus. Vestibulum velit. Morbi turpis. Nunc at diam consectetur turpis volutpat tristique. Donec quis diam. Suspendisse scelerisque. - - LucidaGrande - 11 - 3100 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 290 - {{87, 9}, {195, 19}} - - YES - - -1804468671 - 272761856 - - - optional - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 292 - {{17, 11}, {65, 14}} - - YES - - 68288064 - 71435264 - EmailLabel: - - - - - - - - - 289 - {{456, 10}, {16, 17}} - - YES - - -2080244224 - 0 - Privacy Policy - - LucidaGrande - 13 - 1044 - - - -2040250113 - 36 - - NSImage - goArrow - - - - 400 - 75 - - - - - 289 - {{355, 11}, {100, 14}} - - YES - - 68288064 - 4326400 - PrivacyPolicyLabel - - - - - - - - {490, 114} - - - - {{0, 51}, {490, 114}} - - {0, 0} - - 67239424 - 0 - Title - - LucidaGrande - 11 - 16 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 3 - 0 - NO - - - - 289 - {{330, 12}, {146, 32}} - - YES - - 67239424 - 134217728 - SendReportLabel - - - -2038284033 - 129 - - - DQ - 200 - 25 - - - - - 289 - {{214, 12}, {116, 32}} - - YES - - 67239424 - 134217728 - CancelLabel - - - -2038284033 - 129 - - - Gw - 200 - 25 - - - - - 256 - - YES - - - 256 - - YES - - - 266 - {{17, 83}, {456, 154}} - - YES - - 67239424 - 272760832 - VGhlIHN5c3RlbSBhbmQgb3RoZXIgYXBwbGljYXRpb25zIGhhdmUgbm90IGJlZW4gYWZmZWN0ZWQuIEEg -cmVwb3J0IGhhcyBiZWVuIGNyZWF0ZWQgdGhhdCB5b3UgY2FuIHNlbmQgdG8gPFJlYWxseSBMb25nIENv -bXBhbnkgTmFtZT4gdG8gaGVscCBpZGVudGlmeSB0aGUgcHJvYmxlbS4gTG9yZW0gaXBzdW0gZG9sb3Ig -c2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gU2VkIGFyY3UgdXJuYSwgcHVsdmlu -YXIgc2l0IGFtZXQsIHRpbmNpZHVudCBhYywgZmVybWVudHVtIHV0LCBsaWd1bGEuIFF1aXNxdWUgbWku -IER1aXMgbGVjdHVzLiBWZXN0aWJ1bHVtIHZlbGl0LiBNb3JiaSB0dXJwaXMuIE51bmMgYXQgZGlhbSBj -b25zZWN0ZXR1ciB0dXJwaXMgdm9sdXRwYXQgdHJpc3RpcXVlLiBEb25lYyBxdWlzIGRpYW0uIFN1c3Bl -bmRpc3NlIHNjZWxlcmlzcXVlLiBRdWlzcXVlIHB1bHZpbmFyIG1pIGlkIHB1cnVzLiBFdGlhbSB2aXRh -ZSB0dXJwaXMgdml0YWUgbmVxdWUgcG9ydGEgY29uZ3VlLgoKUGxlYXNlIGhlbHAgdXMgZml4IHRoZSBw -cm9ibGVtIGJ5IGRlc2NyaWJpbmcgd2hhdCBoYXBwZW5lZCBiZWZvcmUgdGhlIGNyYXNoLiBMb3JlbSBp -cHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBTZWQgYXJjdSB1 -cm5hLCBwdWx2aW5hciBzaXQgYW1ldCwgdGluY2lkdW50IGFjLCBmZXJtZW50dW0gdXQsIGxpZ3VsYS4g -UXVpc3F1ZSBtaS4gRHVpcyBsZWN0dXMuA - - - - - - - - - 274 - {{20, 14}, {450, 61}} - - YES - - 341966337 - 272760832 - Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 - - - YES - - - - - - - 256 - - YES - - - 256 - - YES - - - 266 - {{85, 10}, {381, 54}} - - YES - - 67239424 - 272629760 - The application <Really Long App Name Here> has quit unexpectedly. - - LucidaGrande-Bold - 14 - 16 - - - - - - - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{16, 0}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 0 - 0 - NO - - YES - - - {482, 70} - - - - {{4, 245}, {482, 70}} - - {0, 0} - - 67239424 - 0 - Title - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 3 - 0 - NO - - - {490, 325} - - - - {{0, 160}, {490, 325}} - - {0, 0} - - 67239424 - 0 - Title - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 3 - 0 - NO - - - - 268 - {{17, 20}, {163, 14}} - - YES - - 68288064 - 272630784 - xx seconds. - - - - - - - - {490, 489} - - {{0, 0}, {2560, 1578}} - {72, 27} - {1.79769e+308, 1.79769e+308} - - - YES - - - - - YES - - - sendReport: - - - - 45 - - - - cancel: - - - - 46 - - - - showPrivacyPolicy: - - - - 53 - - - - value: emailValue - - - - - - value: emailValue - value - emailValue - - NSNullPlaceholder - optional - - 2 - - - 90 - - - - initialFirstResponder - - - - 91 - - - - value: commentsValue - - - - - - value: commentsValue - value - commentsValue - - NSNullPlaceholder - optional comments - - 2 - - - 124 - - - - nextKeyView - - - - 125 - - - - nextKeyView - - - - 126 - - - - nextKeyView - - - - 127 - - - - delegate - - - - 128 - - - - alertWindow_ - - - - 142 - - - - preEmailBox_ - - - - 150 - - - - headerBox_ - - - - 151 - - - - emailSectionBox_ - - - - 152 - - - - privacyLinkLabel_ - - - - 153 - - - - commentMessage_ - - - - 154 - - - - dialogTitle_ - - - - 155 - - - - emailLabel_ - - - - 156 - - - - cancelButton_ - - - - 158 - - - - sendButton_ - - - - 159 - - - - emailEntryField_ - - - - 161 - - - - privacyLinkArrow_ - - - - 162 - - - - emailMessage_ - - - - 163 - - - - commentsEntryField_ - - - - 176 - - - - value: countdownMessage - - - - - - value: countdownMessage - value - countdownMessage - 2 - - - 194 - - - - countdownLabel_ - - - - 208 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - Window - - - 2 - - - YES - - - - - - - - - - 12 - - - YES - - - - - - 14 - - - YES - - - - - - 132 - - - YES - - - - - - - - - - 145 - - - YES - - - - - - - - 189 - - - YES - - - - - - 191 - - - Shared User Defaults Controller - - - 210 - - - - - 211 - - - - - 221 - - - - - 58 - - - YES - - - - - - 215 - - - - - 18 - - - YES - - - - - - 212 - - - - - 20 - - - YES - - - - - - 213 - - - - - 48 - - - YES - - - - - - 214 - - - - - 66 - - - YES - - - - - - 216 - - - - - 8 - - - YES - - - - - - 217 - - - - - 116 - - - YES - - - - - - 218 - - - - - 147 - - - YES - - - - - - - 3 - - - YES - - - - - - 219 - - - - - 6 - - - YES - - - - - - 220 - - - - - - - YES - - YES - -3.ImportedFromIB2 - 1.IBEditorWindowLastContentRect - 1.IBWindowTemplateEditedContentRect - 1.ImportedFromIB2 - 1.windowTemplate.hasMinSize - 1.windowTemplate.minSize - 116.CustomClassName - 116.ImportedFromIB2 - 12.ImportedFromIB2 - 132.ImportedFromIB2 - 14.ImportedFromIB2 - 145.ImportedFromIB2 - 147.ImportedFromIB2 - 18.CustomClassName - 18.ImportedFromIB2 - 189.ImportedFromIB2 - 191.ImportedFromIB2 - 2.ImportedFromIB2 - 20.ImportedFromIB2 - 3.ImportedFromIB2 - 48.ImportedFromIB2 - 58.ImportedFromIB2 - 6.ImportedFromIB2 - 66.ImportedFromIB2 - 8.ImportedFromIB2 - - - YES - - {{0, 656}, {490, 489}} - {{0, 656}, {490, 489}} - - - {72, 5} - LengthLimitingTextField - - - - - - - LengthLimitingTextField - - - - - - - - - - - - - - - YES - - - YES - - - - - YES - - - YES - - - - 221 - - - - YES - - LengthLimitingTextField - NSTextField - - IBUserSource - - - - - Reporter - NSObject - - YES - - YES - cancel: - sendReport: - showPrivacyPolicy: - - - YES - id - id - id - - - - YES - - YES - alertWindow_ - cancelButton_ - commentMessage_ - commentsEntryField_ - countdownLabel_ - dialogTitle_ - emailEntryField_ - emailLabel_ - emailMessage_ - emailSectionBox_ - headerBox_ - preEmailBox_ - privacyLinkArrow_ - privacyLinkLabel_ - sendButton_ - - - YES - NSWindow - NSButton - NSTextField - LengthLimitingTextField - NSTextField - NSTextField - LengthLimitingTextField - NSTextField - NSTextField - NSBox - NSBox - NSBox - NSView - NSTextField - NSButton - - - - IBUserSource - - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../Breakpad.xcodeproj - 3 - - YES - - YES - NSApplicationIcon - goArrow - - - YES - {128, 128} - {128, 128} - - - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/InfoPlist.strings deleted file mode 100644 index 65d161818..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/Localizable.strings deleted file mode 100644 index 5f1cc8269..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/English.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ReporterIcon.graffle b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ReporterIcon.graffle deleted file mode 100644 index 14a0e7c4c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ReporterIcon.graffle +++ /dev/null @@ -1,2489 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro - 137.6.0.106738 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {512, 512}} - Class - SolidGraphic - FontInfo - - Font - CalisMTBol - Size - 112 - - ID - 2 - Style - - fill - - Color - - a - 0 - b - 0 - g - 0.852018 - r - 0.998962 - - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - CanvasOrigin - {0, 0} - CanvasSize - {512, 512} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2008-11-14 16:58:15 -0700 - Creator - John P. Developer - DisplayScale - 1 pt = 1 px - FileType - flat - GraphDocumentVersion - 6 - GraphicsList - - - Bounds - {{33.9443, 35.3885}, {444.111, 437.112}} - Class - ShapedGraphic - FontInfo - - Font - CalisMTBol - Size - 112 - - ID - 31 - Rotation - 270 - Shape - Bezier - ShapeData - - UnitPoints - - {-0.5, -0.439247} - {-0.5, -0.485429} - {-0.446294, -0.512626} - {-0.409932, -0.494153} - {-0.373569, -0.47568} - {0.436363, -0.0733799} - {0.472729, -0.0549059} - {0.50909, -0.0364333} - {0.509091, 0.0364345} - {0.472729, 0.0549059} - {0.436368, 0.0733802} - {-0.373569, 0.475681} - {-0.409932, 0.494153} - {-0.446294, 0.512626} - {-0.500001, 0.485429} - {-0.5, 0.439247} - {-0.49998, 0.393072} - {-0.500002, -0.393066} - - - Style - - fill - - Color - - b - 0 - g - 0.770962 - r - 0.997971 - - Draws - NO - FillType - 3 - GradientCenter - {-0.609524, 0} - GradientColor - - b - 0 - g - 0.911574 - r - 0.998779 - - MiddleFraction - 0.6111111044883728 - - shadow - - Color - - a - 0.43 - b - 0 - g - 0 - r - 0 - - Draws - NO - Fuzziness - 7.2213706970214844 - ShadowVector - {0, 6} - - stroke - - Color - - b - 0 - g - 0.766903 - r - 0.997925 - - Width - 7 - - - Text - - Pad - 0 - VerticalPad - 0 - - TextPlacement - 0 - TextRelativeArea - {{0.06, 0.17}, {0.88, 0.5}} - TextRotation - 90 - Wrap - NO - - - Bounds - {{3.89085, 67.8908}, {404.218, 332}} - Class - ShapedGraphic - FontInfo - - Font - CalisMTBol - Size - 112 - - ID - 30 - Rotation - 270 - Shape - Bezier - ShapeData - - UnitPoints - - {-0.5, -0.5} - {-0.459695, -0.475464} - {0.429465, 0.0537758} - {0.469773, 0.0783133} - {0.510074, 0.102849} - {0.510077, 0.198357} - {0.469773, 0.222892} - {0.429473, 0.247428} - {-0.00521517, 0.499998} - {-0.00521785, 0.5} - {-0.00521713, -0.113381} - {-0.44962, -0.458615} - - - Style - - fill - - Color - - a - 0 - b - 1 - g - 1 - r - 1 - - FillType - 2 - GradientAngle - 180 - GradientCenter - {-0.609524, 0} - GradientColor - - a - 0.5 - w - 1 - - MiddleFraction - 0.6111111044883728 - - shadow - - Color - - a - 0.51 - b - 0 - g - 0 - r - 0 - - Draws - NO - Fuzziness - 3.3371961116790771 - ShadowVector - {0, 2} - - stroke - - Color - - b - 0 - g - 0.766903 - r - 0.997925 - - Draws - NO - Width - 2 - - - Text - - Pad - 0 - VerticalPad - 0 - - TextPlacement - 0 - TextRelativeArea - {{0.06, 0.17}, {0.88, 0.5}} - TextRotation - 90 - Wrap - NO - - - Bounds - {{33.9443, 35.3886}, {444.112, 437.111}} - Class - ShapedGraphic - FontInfo - - Font - CalisMTBol - Size - 112 - - ID - 29 - Rotation - 270 - Shape - Bezier - ShapeData - - UnitPoints - - {-0.5, -0.439247} - {-0.500001, -0.485429} - {-0.446295, -0.512626} - {-0.409932, -0.494153} - {-0.373568, -0.475681} - {0.436363, -0.0733802} - {0.472729, -0.0549062} - {0.509089, -0.0364334} - {0.509092, 0.0364341} - {0.472729, 0.0549056} - {0.436369, 0.0733803} - {-0.373568, 0.475681} - {-0.409932, 0.494153} - {-0.446294, 0.512626} - {-0.500001, 0.485428} - {-0.5, 0.439248} - {-0.499978, 0.39307} - {-0.500003, -0.393066} - - - Style - - fill - - Color - - a - 0.2 - b - 1 - g - 1 - r - 1 - - FillType - 2 - GradientAngle - 90 - GradientCenter - {-0.609524, 0} - GradientColor - - a - 0 - w - 1 - - MiddleFraction - 0.6111111044883728 - - shadow - - Color - - a - 0.51 - b - 0 - g - 0 - r - 0 - - Draws - NO - Fuzziness - 3.3371961116790771 - ShadowVector - {0, 2} - - stroke - - Color - - b - 0 - g - 0.766903 - r - 0.997925 - - Draws - NO - Width - 2 - - - Text - - Pad - 0 - VerticalPad - 0 - - TextPlacement - 0 - TextRelativeArea - {{0.06, 0.17}, {0.88, 0.5}} - TextRotation - 90 - Wrap - NO - - - Bounds - {{176, 102.384}, {158.841, 537.616}} - Class - ShapedGraphic - FontInfo - - Font - CalisMTBol - Size - 425 - - ID - 26 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf350 -{\fonttbl\f0\fnil\fcharset0 CalistoMT;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\b\fs850 \cf1 !} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{176, 104}, {158.841, 537.616}} - Class - ShapedGraphic - FontInfo - - Color - - b - 0 - g - 0.749523 - r - 0.997726 - - Font - CalisMTBol - Size - 425 - - ID - 27 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - RTFD - - BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0 - ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp - bmcBlIQBKwEhhoQCaUkBAZKEhIQMTlNEaWN0aW9uYXJ5 - AJSEAWkEkoSWlhBOU1BhcmFncmFwaFN0eWxlhpKEhIQQ - TlNQYXJhZ3JhcGhTdHlsZQCUhARDQ0BTAgCEhIQHTlNB - cnJheQCUmQyShISECU5TVGV4dFRhYgCUhAJDZgAchpKE - n54AOIaShJ+eAFSGkoSfngBwhpKEn54AgYwAhpKEn54A - gagAhpKEn54AgcQAhpKEn54AgeAAhpKEn54AgfwAhpKE - n54AgRgBhpKEn54AgTQBhpKEn54AgVABhoYAhpKElpYG - TlNGb250hpKEhIQGTlNGb250HpSZIIQFWzMyY10GAAAA - FgAAAP/+QwBhAGwAaQBzAE0AVABCAG8AbAAAAIQBZoGp - AYQBYwCiAaIAogCGkoSWlg1OU1N0cm9rZVdpZHRohpKE - hIQITlNOdW1iZXIAhIQHTlNWYWx1ZQCUhAEqhIQBZKYD - hpKElpYHTlNDb2xvcoaShISEB05TQ29sb3IAlKIChARm - ZmZmAYN4dz8/AAGGhoY= - - Text - {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf350 -{\fonttbl\f0\fnil\fcharset0 CalistoMT;} -{\colortbl;\red255\green255\blue255;\red254\green191\blue0;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\b\fs850 \cf2 \outl\strokewidth60 \strokec2 !} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{33.9441, 35.3884}, {444.112, 437.111}} - Class - ShapedGraphic - FontInfo - - Font - CalisMTBol - Size - 112 - - ID - 16 - Rotation - 270 - Shape - Bezier - ShapeData - - UnitPoints - - {-0.5, -0.439247} - {-0.5, -0.485429} - {-0.446295, -0.512626} - {-0.409933, -0.494153} - {-0.373569, -0.47568} - {0.436363, -0.073379} - {0.472729, -0.0549049} - {0.50909, -0.0364324} - {0.509091, 0.0364344} - {0.472729, 0.0549058} - {0.436368, 0.0733801} - {-0.373569, 0.47568} - {-0.409933, 0.494153} - {-0.446295, 0.512626} - {-0.500001, 0.485429} - {-0.5, 0.439247} - {-0.49998, 0.393072} - {-0.500002, -0.393066} - - - Style - - fill - - Color - - b - 0 - g - 0.770962 - r - 0.997971 - - FillType - 3 - GradientCenter - {-0.609524, 0} - GradientColor - - b - 0 - g - 0.911574 - r - 0.998779 - - MiddleFraction - 0.6111111044883728 - - shadow - - Color - - a - 0.9 - b - 0 - g - 0 - r - 0 - - Fuzziness - 8.0632610321044922 - ShadowVector - {0, 9} - - stroke - - Color - - b - 0 - g - 0.766903 - r - 0.997925 - - Draws - NO - Width - 2 - - - Text - - Pad - 0 - VerticalPad - 0 - - TextPlacement - 0 - TextRelativeArea - {{0.06, 0.17}, {0.88, 0.5}} - TextRotation - 90 - Wrap - NO - - - GridInfo - - GridSpacing - 4 - ShowsGrid - YES - SnapsToGrid - YES - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 2 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2008-11-17 11:41:28 -0700 - Modifier - Preston Jackson - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612, 792} - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - QuickLookPreview - - JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls - dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlktvJEUQhO/9K5IbHFyuR9brioEV - nFh5JM5o5MWsPIA9IP4+X2b12gPrBbHWSt3lzkdFREb6Ud7Ko0R+asr+/+lOfpBfJIYW - /Z/8LNc35yTHsyROh/ZYxyTgfJTrN/zip7NcxVD3r1+e9oQbCd/J9fd3T8e7337/48cH - eSLjm3O2wEfR2ry8tiJ5hDJSVEk9pF7jkONJrr89JfnqV/p8uz1KK1YpJynNHlKVk2gJ - JZWqdqZz9iklBc21ZmkxlJoin0/vsEonTo6b9lC79iQzh6azSc7FYjINZWIkk4MCKtrG - ejhyRpZeRYcSNIbk7oXmtk5m4mRaD/NvYcOK1bKnpnkuu4qt6jqEVujLmtuOvFgdrXv7 - mcjWQxut71ds5LcbAIADIcTkDgpt4TKmyigWoXNzVAYtfYzdUe5fOT25ACxMtZAQiPeX - xEVTSCkNeaBLDbXWDhwfnxH1QHJX0sfiulDDhhpMgMnUJZAGDLkCea3T6b+9T3K+N/pf - F6qL8+ZW0hYDjM4ESlFubyTlAFd/kvfwRKilj3IFRdTQHJsk6EwzW5UvDwBY1xf2cNVL - SDWiyTa2AyL8JgXr8fBOPv/sCzm8l68PNERtwm0wGIb4yTrK2LiYt3+rI5+uY1df7JW8 - CD9tS/XNGUdxFSUs1e+yiQPuXPUMyVI9lL2qeh2bq16Rjet+qRdVLcWrceySz8+S30+A - zyTPTNiYWMQSe10Z64vY+/OoudZNus9dudwRqE+rVVty97v63bZd7iZHL7PkjnfYe5xw - vvTOAJtW5+gMv3vFB8RetF6yzYQ5x3/L08wKeQZ3t1pin5Fp1GpD0ORKy7AnlLN/kbPS - 2ofZwIlqwA1G35aT5d3JyGncLARwMKZb0Tt2gIAHLOBGpTJExgtaxZ/MjxbK+B8mYdQ0 - 5QuYoSumBgvBBXEsP0n9khlidnI8xrK6LZqBzVm2bFzEhIjMiIwcPyGGeQqjdjrwT7h+ - LYHiADxbwGHg6+Uux+3+4u1/I6yj5DSiaKw0CBBXpRSDluldCFM4zgHvPa9zujJygMR3 - RXlB+JWt1t0PvmNg35PwHxsOE4mw1Weu0cykNci2JJjJhX+sVUm1pt4BgIOOr6HBGsLd - eYUt0uRFYFIEgAl4n6yrBqw6QuzKxtA0wdf4g/OZ2QWMAd4DfUgXOqHaYjtc4/Gjshmh - y/PP/YQ62VDzj4dlZttYGh2ZHAwCzaCeVcoaJty3VGm2b4bnZwuhC2LommlOA9lxF2ub - WDS6QrjdWjcjNZJ3Uzh/OyA6IjK7cIVwj0t8fPwuD05ya6b+F7C1v1cKZW5kc3RyZWFt - CmVuZG9iago1IDAgb2JqCjk4MwplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAv - UGFyZW50IDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRp - YUJveCBbMCAwIDUxMiA1MTJdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsg - L1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8 - IC9DczIgMTIgMCBSCi9DczEgNyAwIFIgPj4gL0V4dEdTdGF0ZSA8PCAvR3MxIDE3IDAg - UiAvR3MyIDE4IDAgUiA+PiAvRm9udCA8PCAvRjEuMCAxMSAwIFIKPj4gL1hPYmplY3Qg - PDwgL0ltMiAxMyAwIFIgL0ltMSA4IDAgUiAvSW0zIDE1IDAgUiA+PiAvU2hhZGluZyA8 - PCAvU2gxIDEwIDAgUgo+PiA+PgplbmRvYmoKMTAgMCBvYmoKPDwgL0NvbG9yU3BhY2Ug - NyAwIFIgL1NoYWRpbmdUeXBlIDMgL0Nvb3JkcyBbIC0yNzEuMzA2MyAwIDAgLTI3MS4z - MDYzIDAgNTQwLjI2NApdIC9Eb21haW4gWyAwIDEgXSAvRXh0ZW5kIFsgZmFsc2UgZmFs - c2UgXSAvRnVuY3Rpb24gMTkgMCBSID4+CmVuZG9iagoxMyAwIG9iago8PCAvTGVuZ3Ro - IDE0IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDI1NiAv - SGVpZ2h0IDI1NiAvQ29sb3JTcGFjZQo3IDAgUiAvU01hc2sgMjAgMCBSIC9CaXRzUGVy - Q29tcG9uZW50IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dABAQAA - CAKg/p+2Bx4QJpBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDDQBg4DBgwYMGDA - wNjAA65NNU0KZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iago4ODMKZW5kb2JqCjggMCBv - YmoKPDwgL0xlbmd0aCA5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2Ug - L1dpZHRoIDkxMiAvSGVpZ2h0IDkyNiAvQ29sb3JTcGFjZQoyMiAwIFIgL1NNYXNrIDIz - IDAgUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0 - cmVhbQp4Ae3QgQAAAADDoPlTH+SFUGHAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - wMvAAKraAAEKZW5kc3RyZWFtCmVuZG9iago5IDAgb2JqCjExMDcwCmVuZG9iagoxNSAw - IG9iago8PCAvTGVuZ3RoIDE2IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1h - Z2UgL1dpZHRoIDI1NiAvSGVpZ2h0IDI1NiAvQ29sb3JTcGFjZQo3IDAgUiAvU01hc2sg - MjUgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4K - c3RyZWFtCngB7dKBDQAgDMMw/n+6SHBGvA+aeXMKFAucd8XlNiuw8U9BuQD/5e/bzj8D - 5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+ - vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2889A - uQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/ - bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t/DNQ - LsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv - 284/A+UC/Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyU - C/Bf/r7t/DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7 - tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPl - AvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+ - 7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5 - AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79v - O/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+vu38M1Au - wH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2889AuQD/5e/b - zj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL - 8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2 - 889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC - /Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287/wyUC/Bf/r7t - /DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7Af/n7tvPPQLkA - /+Xv284/A+UC/Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vOPwPlAvyXv287 - /wyUC/Bf/r7t/DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvwX/6+7fwzUC7A - f/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+vu38M1AuwH/5+7bzz0C5AP/l79vO - PwPlAvyXv287/wyUC/Bf/r7t/DNQLsB/+fu2889AuQD/5e/bzj8D5QL8l79vO/8MlAvw - X/6+7fwzUC7Af/n7tvPPQLkA/+Xv284/A+UC/Je/bzv/DJQL8F/+vu3f/wUgwjJ6CmVu - ZHN0cmVhbQplbmRvYmoKMTYgMCBvYmoKMTIxNAplbmRvYmoKMjMgMCBvYmoKPDwgL0xl - bmd0aCAyNCAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA5 - MTIgL0hlaWdodCA5MjYgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21w - b25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHsnYlfTV37/288 - j4xJUVJRGtCEoggliZCxyFQUlUiGNCgJIXOFyFTKlCljmUMlUaZK4XY/N31fv//jd621 - 9z57n6nxDPvU1ev1PHfts89a61zn+njvz7XW3uuvv/AHI4ARwAhgBDACGAGMQOeIQDfy - 0132hx7tHB8QPwVGQCciwOiwR48e//nPf/4r9QMH/gPHQaRwjk58FhwkRkCHI0ClSIT4 - 3//27Kmn10vuR0+vZ8///peoEjWpw98zDl0HIkAuT0GLIEWqxN59+vTt269ff8lPv379 - +vbt07s3iJSoEkSJmtSBrxWHqIsRoGKkWuzVqzcRYn/9AQMMDAwGDhxoyPwMHAh/GgzQ - 1+/fD1QJmtQDTTKc1MUPjGPGCIg1AqwYe8IFKmiRSNFgoKHRoEGDjY1NTIbAjyn5PxMT - Y+PBg4wMQZcD9PszmmQkiWZSrN8sjkv3IgBqJI6xJxEjaNHAAKRobDLE1HSombmFxbBh - w+nPsGHDLMzNzYaampqAKkGUA/SBk+TSFShJLlx174PjiDECoosAMY0gRj0qRuCi0WDj - IaZDzS2GWVpZjbC2sbG1tWN+bG1trEdYWVkOH2ZuBqIETRoYEEyCJOl1KypSdN8tDkjX - IsCqsVevPn37DwAwDjYBLYIUR9jYjRxlb+/g6OjkDD9j4H9OTo4O9vajR9nZgiyHW5iZ - DjEmmNTvB2aSgSQqUte+fhyvqCLAqJGiUZ+QcYipmYWllbXtyNH2js5jxrm4uI6f4Obu - 7j5xIvyfm9uE8a4u48Y6OznYj7KzGWE1zHyoKUjSYED/vqhIUX2vOBhdjAD1jWAbwTXq - GxgOMiFiHGEzcrSD0xgX1wnuEz0mT5nq6TVtmrf39One3t7TvLw8p0yePMndbbzLWGdH - +1G21lbDzU2HDDYayCmS+EhdjASOGSOg9QiQKg4p4vTpBxeqgEbz4VY2I+0dQYtuEydP - 8Zw23cd3pt/sOXPn+jM/c+fM9pvlO8PH22vqZA/3CS5jnQCT1pbDzACSAw0oI0llBy9a - tf7N4gB0LwIUjlDFoWwcPGSohaW13WgQ44SJk6dOmz5j1uy5/vMXLgoIDFyydGkQ+Vm6 - ZElgwOJFC+b5z/Hz9fH2nDzJzXUcSNKGQBIUSRlJa62ISN1LBxyxdiNA4QjGsS9cqYIa - hxE0Oo8bP3Gyp/eMWXP8FywOXLpsxargkNWhYWFr165bt27t2rDQNauDg1cuDwoMWDjf - f7avz7QpHm4uYxxH244gijQyGNCvDxR2EJHa/Waxdx2MAJEjgWP/AQMHmQy1sLIZ5TDG - xc3Dc7qvH2hxybKVwWvCwiPWb4jeFBOzecuWrVu3btmyOSYmemNUZPja0JBVy5cGLpo3 - Z6aP1+SJ4wGSdiOGw1WroYE+FHYAkegidTAlcMhaiwC5ViV1HICjkbGpuaU1qNF14uRp - Pn7+CwODVoaEhkdu2LR5a2x8QmJS8s6UXbt2pe7alZKyM2lHQnzcti0xG9eHr10dvHzJ - YpDk9KkeE1yc7G2thg0dAhetBJHURWrtw2HHGAHdigDI8T//Jc4R4DjEbPiIkfagxine - vnPmBwStXL02YkPM1u3xO3bu2r133/709IOHDh0mP4cOpqcf2Je2JzUlKSFu2+bo9eGh - wcsDF/r7+Xh6TBjnNNrGyoJctFJEkmtW3YoJjhYjoKUIsNaxT38DQ2NTCytbe2cXUOPM - uQsDV4SsjdgYExuflLI77UD64aPHMzNPnDyVnX0afrKzT508kZWZcezIwfR9e1KTE+O2 - booKX7MqaPG82T5eHhPGOoy0Hm4GiNTvR65ZUZBa+naxWx2LACtHcq1qYjbcepTjOLfJ - RI1LVq4J3wBiTE7de+DQ0Yysk9k5OecuXMzNu3QpH34uXcrLvXjh/NmcM6dOZB47nL5v - d8qOuC3RkWHBywLmASMnuY6Bi1Zz08GG5JoVBaljWYHD1VIEmEoOWEe4VjUHOI4Z7+E1 - g6gxNCJ6S3xSalr64eNZp86cvZB7Kf/y1WvXC2/cuHETfuA/NwqvX71SkJ938VzO6ROZ - Rw/u370zITZm/TqiyFnTp7i5OI4cMYyUdfqjILX07WK3OhaBbt2gsNqrN1jHwXCtOtJh - nNsUH7/5gSvXRERvjd+5+wCIMTvnQl7+lWuFN27dKbp3/wH8PCQ/8N/79+4W3b554/rV - gksXz505mXk0PS11x/aYqLXBQYvm+np5uDqPthk+1MSICFIPL1l1LDVwuFqIAJRyeuox - chw2YpSTyyQvX//Fy0LCN25NSNmbfjQTxHjp8jWQ4r0HDx6VPH7y9NmzZ8+ZH/jt6ZOS - 4ocP7hfdvnH9Sn7uuTMnjh/al5q0PWZ92KrA+X7TJ7uNtbe1NBtCBYmXrFr4erFL3YoA - raz27jtgoLHpMOvRY8ZP9vabv2TV2qjN8Tv3ph87ceZ8XsG1G7fvghSfPHv+ovTV6zdl - ZeXsT1nZm9evSl++ePb0cTFo8lbhlfyLOacyD+9P3RG7KXz1ssVzZ3i6uzjYWZmzgsQq - q24lB45W0xEg8456vcA7GpsOt7EfA9eqcxYtWx2xaXvSblBjzoX8qzdu33tQ/OTZi9LX - b8rL31a+q6p6//4D8/P+fdW7yrcV5WVvXr18/rTk4f2im9cLcs9mZx7atythS9TaVYHz - ZnpNcnEUChJnPTT9FWN/uhMBiRwHEzmOdZs6wz9gRVjUloTU/UeyzlzIv3ajiIjx5euy - 8rfvqj5UV9d8/Pjp8+fPX+AH/vPp08ea6uoP799VVpS/KX3+rOThvduFl/POnjp+cE/y - 9k3hwUsX+Hl7uDqOpISEaQ9YqYOC1J30wJFqOAK0ltNH32AwXKzaj3X39PUPDF4XHZu8 - 52BG9vn8azfvPighYqyoBC2CEL98ra2rl/qpq6v9+uUzqPL9u7dEkk8e3QdF5uacOLp/ - V/zmyDXLFs6ePpkI0swEpj16Y01Hw18wdqdLESDmEZasGgzi5DhvSXB4THzK/iMncvKu - 3Lj74PGz0jflle+raz59+QpK/NbQ0Pj9+w/Jz/fvjY0N3+rrQZSfP1Z/qHpb/vrF0+L7 - t6/nXzidkb57x9ao0OWL5hBB2lkONTYc0LeX3n96ICB1KUVwrBqMADGPvfsZGA2xGDF6 - jJun77ylIRExCanpx7MvFBTeATW+KntbRcRYW18PSvzx8+fff/+S/vn7758/vhNR1hFJ - vq8kinx07+bVvJysw2nJsRvDViyeM93DxcF2+NDBA/VhGhKvWDX4BWNXuhQBMtXRq+8A - QxMzq5HOE6b6zlsSErk5cffBzJzcqzfvFT8rLXv7vvojiPFbA2iRKPGf//3vf/8KfuDP - f/6B43//BE0SSdZ8eAeKfPLgTmH+uZNH9+3cvnHtikWzvSe52NsMMx1k0B+vWHUpQXCs - mowAKebA1erAwUMt7RzHT57hD3LckrjnUFbOpet3Hjx58QbY+AkuU0GMoMV//gEl/v79 - h/w00R/66+/fv//993+gSSLJb/W1oMjK8lfPiu/duHwh+9j+lO0bw5Yv8ps2cezoERZD - jAb0Q0Bq8ivGvnQoAlDMIVerYB5tHFwm+0ApJ2Jz4p7DJ87l37j76Nmr8ndEjd8af/wk - XAQtskL8P+EPEeafP6BJKskf3xuIIt+/ffPi8YNbV3NPHz9ABLlswSxPN+dRVmbG9IoV - V5brUJLgUDUVAcnVqvmI0eMmes8JWBUeQ+VYcONeyfM3bz/UfCFq/JsTIyhPqET+d4Ek - AZIN9V8/Vb8rL3368Pa13DPH9++M3bAmaN6MKeMdbYebDmauWLGko6kvGfvRmQh0I8Wc - /gaDh4J5dPOctXDFuk3xuw+dOFdw4/7jl2UAx9r6BkaNQEalYmRlSSlJIAmK/Fb3peZ9 - xetnj+5cA0LuT962PiTQ38fDxd6aXLH2xStWnUkRHKjmIsDg0cCIXK26Tp4xLyh0Y1zq - wayzIMcnpeVVBI7ffxI2UjXyNCS//T/mR+ogoSS9bP37RyMg8sNbRpDZR9N2bA5fFTB7 - mvsYesXavw9MQiIgNfdFY086EQHAY68++gNNyNXqpOlzA0PWx6akZ+bks3L8SuGoSI2s - GOUlKVEkILL2c3XlGyDk1YunjuxJiFm3fIEvc8U6yABLOjqRHzhIjUaA4pEUcyztnCZ4 - zlq0KnxL0r7jZy4V3nv8svz9x6/1jSwcpV2jlBjpH0JIMletcNH6vaGOCvLh7SvnTxxM - jdu4ZilcsY6zH2FuYgiTkAhIjX7X2Jn4I8Dg0XCIhbU91FbnBYVtit9zJDv3+t2SF+VV - rBzlLlXl1SgrSeai9dffP4gg4ZL1wc2Cs5kHdm6NDF4828vNeaQllHQQkOJPDxyhZiPA - 4pEUc8a4T5sTGBIVu+vgifNX7jx6XlZV87WeWEeQoxQclaiRHOYhSRBJ6jpEkB8qXj25 - f+PSmWNpiTFrl8+fMZmWdBCQmv2qsTcdiACHR1LMmeK7cEX45qT9GTn5Nx88e1NZ/YVc - rBLrKJRjM2qUU+RvIshvdZ/el78sKbp28eSh1LgNqwPnek+Eks5QBKQO5AcOUaMR4PE4 - auzE6f5L1myM330kO6/w3pNXb6s/K5BjC2qURSQI8m8o6nysKnv+8Ba5Yk3eEr5y4cwp - rg42w4YgIDX6XWNn4o+ABI+2juOnQjEnYuvO9Cy4Wi1+Uf7+U13DD9mL1ZblKFQkMZH/ - g6JO/ZfqytdP4Yr19NE98dGhS/2nTxqLgBR/duAINRwBDo9mVjDX4eO/NGxTwt5jZ/Jv - wNXqu5qv32Tl2Co1ygvyZ2P95w/kivXqhRPpKdsiVi2aNXW8IwJSw182dif6CFA8DjAa - MszWEeY6FgdHQjHn5MVrdx+XVhDz+Pev/wm9Y2vlKCjrACH/JRaSXLFCjTU/53hawqaw - IH+fSeNGo4MUfX7gADUaASEePXz8g8JiEvdl5BTcevgcpjrqGkgtR1DKab0cBYgka3XA - QsIV69tXj+9ev3jy4K5YmPPw85zgaIsOUqPfNnYm9ggw7pHgEZYC+C0OXh+beuhU7nUo - 5lRWw1TH3zDTIamstkmN0oL836+fDaTGSko6ORn7EmMIID0AkGZYYhV7iuD4NBcBaTzO - C1obs2NfxtnLtx/RYg6Z6oCrVXZGsa1ylFyzMles3799ra589eReYe6pQ6mx6xGQmvuW - sSddiYA0HgOC128HPOYV3n/6upIt5kiuVtsuR16QpMb6s5EA8sWj25fPZuzbEbM2aB4C - UlfSBMepmQjI4HEZwWMmg8cPMPX49y+yEKDdeOQvWdmSztcaMuehAJB4m4dmvm/sRdwR - EMw9gnukeDwsxGOHrlYpUBkxk5LOr79hzgMBKe6EwNFpMwLK8AhLATg8csWc9lytkvew - cKWrAn58EwByu5SDREBqMw+wb3FEAPCo10ffkJl7ZPAo5R55PLZXjpwgm5rInEdj/acP - 5S+KJQ4S5yDFkQc4ClFEQBEeSXGVw6NgrqP9emQJKQ9IpsQKj9Khc5AISFGkBA5CixGQ - xiPMPcoUV1WBRyEgqYMEQHIlVlyko8UvH7sWWwQ4PA6lK1f5uUd5PHaAjhILqRiQszy5 - VawISLHlB45HsxEQ4HE8vzSHn3tUDR45QRIHSQBJHCQAUrJIZ9I4vM1Ds9879ibKCEjj - kaxcZZbmcHiEuUe2uNoxPEquWMmiAGGJla5i5W/zQECKMk1wUBqKgASPNuS+R27lqhrw - yAqSAhLuu2IAya9ixfsgNfSFYzdijgCPx1Fj4b5H9sYOunL1wydmaY6K8MgD8l8OkE/u - Xc89eYgHpAV5UAACUsz5gmNTbwRk8Qj3PcKNHWrBIwdIskiHAJIs0oHbPI6nJW4Kg2c/ - 8oDs0V29nxlbxwiINQJkf7l+ZIcAIR4LmBs7yENzVOYeifvkVs3RG5PhNo/XFJDkPkj6 - oAAHGwSkWPMEx6WRCHB4tGDdI8HjSXLfI3tjB7kNmVFRR6s59P20KTrlIQ9IwZN0EJAa - +fKxE9FFoHsPHo/TyVNzEtOOw2MB6H2PDB5ZPapEjgoBSR4UsE0CSPKwcr3/dsfdPESX - Kjgg9UegW3dm5aqFjQN9qFzkNnhqDoPHauYhVirFI+8gufsgnzMOMmGT5FFzdDcPBKT6 - v3vsQXwRYPA4iLpHwGOoEI91wscCqAaP8g4SHhRAn6RDHjU3cyo8i9UCANlb7z8ISPEl - C45I3RGAyQ5yY4eJFB4vsk/Noc94VDEeFQCSPEmHPGqOAHIieRbrIAPYDxIBqe7vHtsX - XwTk8JjAuMfn5BHI6sCjUkDSZ7GSh5VbIyDFlyc4Io1EgOCxN4NH16kz4ZHkxD2qF48K - AQnPYt2bQB9WDrt5WJoiIDXy7WMnYosAwWNfA+oeYccOcI8MHuGZq2rDoxQguUfNXb/I - PqycBeTA/uggxZYrOB61R0CCR2vY0IriMUX9eFQCyGMEkEv8Ybsr2A8SAan27x47EF8E - WDyaWo4cQ/EYnbD3eE4+eSS5GvEoB8i3r57Aw8oBkFsjmO2uwEEiIMWXLTgiNUeA4rH/ - QBMLHo/pJy5ev0v2l/v67TvsZ6Xy4iozayJcpMM+rDw/59je+Og1S8h+kBJA4poANWcA - Ni+mCAjx6O2/JBTweEwDeJQGZP1XupvHNbLdFQtIewSkmNIEx6KZCEjjceHKiK0pgEfY - 0IrgsV6NeJRykLCbB9mgFba7kgPkf3sgIDWTCtiLCCLQjSmuUvfoPXfJmuh4gseb6naP - 5JJVcJsHt90VAeTOrbBhsu8UV3trc3SQIsgQHIIGI8Dj0R6KqwtXhhM8XmDw+EW9eJTo - kezm0VBH9oMUAtKdc5AISA3mA3al3QjAjVZk7lEej2VVsDu5cEMrVS1dFbQjC8jSx3d5 - QE52QUBqNzewd41HgMOjuTXg0ZfgcafG8MhfsEoB8szRPfEbSYmVAeSAvr0QkBrPC+xQ - OxGgeBxA8ehO3ONGcI9nwD0+K2O3Q5ZsaCXAmup+VQjIrPSdW8JXLPRFQGonJ7BXrUVA - gEeXySwes4h7LH1brW73SFTN6ZEH5IOb+RSQqwPneLs7kzlIBKTW0gM71nAE5PG45yjg - 8YGG8MgLEnbXoSXW0sdFVy8wgFxAADkCS6waTgnsTnsRkMbjghXhW3amaxKPvB4FgLwh - AeQ0d2c7S1MjBKT2MgR71mQEeDw6u0+bE7h6Y7yG8cgLUgjI81npyeAgWUAawyrWnvig - AE3mBfallQgAHnv27j/Q2HyEPbhHDo9Xi1j3+LfaVq4KCkJSDrKWzEE+kAbkcASkVpID - O9V4BBg8Gpla2gnxeENz7lFY0mEBWVFaUnSVA+QM6iCNDRCQGs8N7FDjEZDHY3J61nmC - xwpSXNUIHvkLVuogOUCePro7fgOUWKe5OdshIDWeGdihNiLA4XG4nbMbcY8bqHtk8Fir - 7qU5/CUrd8UqBcjMA8mbwUEiILWRGNinNiLA4NGAcY8ziHtk8FiiUTwqBuSl00ekAdkH - F+loI0ewT81FQB6Pu4+eztc4HnlBygNy+XwKSDN0kJpLC+xJOxGQxuP8FeGbkw9kgnvU - NB55PXIO8g2UWAkg4zaEBM72cnOiDhIBqZ00wV41FAGCxz4DjEwl7jFu95HTlwCPb6o+ - atA9SkqsTU1/KCA/V1e8LCm6cp44yHU8IPv1wjlIDWUGdqOFCFA89jMwNiNzjzPmL5fg - 8WVF9We2uMrsaMVXXtT1G1fRAUD+aKj9+A4BqYWEwC61GgEej05uXrMDQzZI8PhO03hk - r1ilAHnnyrnMA0kcIK3AQSIgtZov2LlaI0DwCPuvSvC4bnPSgcxzV+6UaAGPUg6SB2T2 - kdS4KMZB2pI5SHSQas0IbFybEZDFY5QUHn/8+p9673uUvfKlV6wSQH6oeFnMADIGHKQP - LNJBQGozWbBvdUdAgkcrcI8+85drF4+ygKyhDjIv+zABZMBsrwlOtsMQkOrOCWxfexGQ - 4NGWcY9RcalHsmlx9V1NbYPG8ShxkL+ZEisHyP1JMeuWzfPxGDfaymwwOkjt5Qv2rNYI - yOExJmk/cY/FLys+aLq4yly6Ckus32p5QG6PCmYBOcRIHx2kWrMCG9dWBDg8DrN1muA1 - OyAkanvq4ew8MveoJTxKAbKx/vOHcsZBAiDXIiC1lSbYr2YiwOJxsJnV6HEePvOWrZPg - sRzw2Ag3dvxu0tTcI1fZkQfk/RvEQRJA+nkSBznEEAGpmfzAXjQbAYpHfaMhBI+efgHB - UniE7ck1XFwVXLE2NREHyQHy8rnM/TsQkJpNDuxN0xGQxePamB2se9QeHqVLrMRBvn7K - AnI9BaQjA0g9fBarptMF+1NzBBg8GgIeHSke1zPu8f7T1+AetYVHeQf5ovj25bMISDUn - Azav7QgoxOPZy1Bc1SYeZQD5lQKyMO8UOMj1wYvBQSIgtZ042L9aIgB41OujL43HU3k3 - tI1HJYDM2AcOMoiZgxyKc5BqyQhsVIsRkMFjELjHfZlnL98ufqFdPMoBshIcZGHuqUOp - sRSQ4x1taIkVHaQWkwe7VnkEpPG4OBjc46FTeYWAx8qar9pzj6TIyq5ilZRYqYMkgAwL - 8veZBIt0EJAqTwdsULsR4PA4FOYeJ/n4UzxmiAKPzQNy1lQEpHYzB3tXRwQkeLRxHO85 - C/AYC3jMFQUeBYD8xcxBvngEJdaMfYkMIMeOQkCqIyWwTe1FQBaPYeAeCR4fse7xlxaW - 5nBLdJQCcldsZPBiBKT2sgZ7VlcEhHicCniMFBMehYD82Vj/6X05ALIgJyNNFpA9uqsr - PtguRkCDEeDxOGoscY9hMYn7MnIKKB4/wcpV7eJRASCf3CvMPXmQB6QFWcWKJVYNpgx2 - pcYIcHi0APfI4HGXeNwjX2L98/vfXxwgbxXkHE9L3BS21H/6JImDRECqMUmwaY1FoHsP - 8tScwUOtWDxuSkxj8fge8PhT23jkAfnvP79+fPtaXfn6yb3rBJDbIlctAgfpYMMCsns3 - jcUMO8IIqCkCMnhcFRm76+DJ3Ov3nrBzj5rYYI6v3ij8jZmDZABZRx0kC8hQDpCDyIMC - EJBqShFsVoMREOJxuv/SMMDj8ZyCW1Bc5fD4R9P3PcqKkrsPkgPkKwDkRSlAmhjq99bD - /Vk1mDbYlXoi0K07s3LVwsYB3OOiVZHbAI8XKR6rydIcEeCRK7H+IZsHNBJAPn9EAZmw - iQByInGQgwz6IiDVkyHYqiYjwOBxEHWPgMfQTQkMHp8DHuvAPUruQ5aFlib/VgLIlG0R - qxbNnOoKDhIBqcmkwb7UFQGY7NDrrW9oAnh0JXiM4PD4qlI8eFQAyIe38qHEygJyzCgr - UwSkulIE29VgBAge+xpQPE4ULR7lSqxvWQfJAHKKq4O1hcnA/uggNZg42JU6IkDx2J/B - 45SZBI8pjHsUFx6VAPLY3oTo0CX+3hPHjLREQKojP7BNzUaAxaOp5agxFI/RCXuP5+Tf - eigq90icqsBBfoc5SADk3esXT6SnbI1YuXAmAlKzWYO9qSkCDB4HmlhYO7iyeEw/QYqr - r96KyT1KBNkkKLESB0kAuWbJXCEgcU2AmnIFm1V/BCR4HDlmorf/klDA4zFR4lEakPVf - AJCP7167wAPSHh2k+tMFe1BvBKTxuHBlxNYUwOO1uxSP9d/FMffIzatwi3SYOciqsucP - bxJAxksDEh/9qN6UwdbVGIFuTHHV1JLgce6SNdHxBI83xeceJRes/0c2MP/1XQDInVvD - Vy70neJqb22OJVY15go2rfYIcHg0t7YH97hwZTjB44Vrdx+De/wiNjxKKjpkkU5D3ceq - smcsIDcSB+nOlVgRkGrPG+xAPRGAleRk7pHg0V0Kj2VVn+oaRLI0h7tclXeQpYyDZAAJ - +7MiINWTJtiqZiIgxONkX4LHnSLGI69HHpAPbuafObonXgDIAX17ISA1kz7Yi4ojQPE4 - gMfjRtY9Piur+iiFx//jGaXV34RzkMRBUkBmpe/cEr5igS8CUsXpgc1pNgICPLpweMwi - 7rFUjO5RWNGRB+TqwDnT3J3JIh0EpGazCHtTVQR4PDqDewxcszF+z9Ez+TcfiBaP/BUr - 3cCcArLo6gUBIEeYG8Mq1p54H6SqcgTb0VgEJHgcYQ94XLAifMvOdMBjEYtH2H+VvQ1Z - LFerQEjuglUAyBuMg2QAaWdpaoSA1FgKYUcqjIAEj3bO7tPmBK7WATzygmQBWVH6uOjq - +az0ZM5BIiBVmCHYlAYjAHjs2bv/QGNzKTxeFTUeeT1SQNaSOcgHDCA3EEC6OdsNR0Bq - MImwK5VFgMGjkelwKTzeoO6xVjj3KKLLVcEVqwSQJTwgZ0CJFQBpgA5SZVmCDWkoAgwe - DRg8ziDuMTk96zzBYwVZmiNK9yhXYuUAefro7ngEpIYyB7tRRwQEeHQj7nFD/G4orooe - j/wVqxQgMw8kbw5fPh8BqY5UwTbVHwE5PG5OPpAJeCwROR55PXIO8g04yEunj+yO2xDC - O8g+uEhH/TmEPaguAgrweOT0JR3AIyvIJnKbx9/kNo+KlyVFV84LAWlmbNAP5yBVlyvY - ktojwOHRjBRXZ8xfHq4zeJQD5DshIGd7uTnREisCUu05hB2oLgIEj30G0OKqm9fswJAN - cbsZPL6p+iji4iop6MgA8jMB5J0r5zIPJG1exzpIAsheuEhHdemCLak3AgSPsIOOsTQe - rxSVvKyo/swWV7W9RQCjPUX/L1ik86Oh9iMPyKiQQAJIWzIHiYBUbwph6yqMAI9HJxk8 - vgM8/uAfSS6uuUdOnMyDO1gHKQNIH5iDtEJAqjBZsCl1R0CCRyvGPa7bnHQg89yVO7qB - RykHCYCsYQCZfSQ1jgJyAgJS3QmE7as0AhI82jJ4jIpLPZJNiqtvdAKPsg7yQ8XLYuIg - 9yfFgIP08SCAHIwOUqUpg42pLwJSePSZv3xdDIPHYp1wj+SiVdpBMoDMyz6cuj0qJGC2 - FwBymKmRPjpI9aUQtqzCCAjwOMFrdkAI4PFwdh7FY40OuEeJIJuafsMcZGP95w/lPCCX - zfPxGDcaAanCfMGm1BoBFo+DzaxGj/PwmbcM8LifuEfA4wemuPq7SbzFVaamIwTkN9ZB - MoAMDvDzJIAcYoiAVGsaYeMqigDFo77RkGG2TgSPwVHbBXiE/Vcl+z2Ks7gqEKQ8IHfE - rEVAqihPsBmNREAWj2sleCwHPDbCjR3ix6O0gySAfP30/g0KyPUUkI4MIPXwUXMaySns - pP0RYPBoSPHo6RcQvJ7B4/1nr9/V1OoKHiUlVqGDvHw2cz8Csv2Zge/UQgTk8bgD3ONl - cI+6hEcZQH6lgCzMOwUlVgSkFrIKu2xvBACPen30CR4dJwjx+FS38CgPyBfFty+fzdgH - gAxiSqxDcQ6yvUmC79NUBBTgcV/m2cu3i1/oFh7lAFkJDrIw99Sh1Nj1wYv9PMc72tAS - KzpITWUW9tOeCEjjcTFxj4dO5RXeJ3j8qjvuUdEcpASQYUH+PpNgDhIB2Z4MwfdoMAIc - Hocyc49Ba2N27MvQSTw2D8hZUxGQGkwr7KqdEZDg0cZxvKcf4DEW8JhL8Fipa3gUOMhf - zCKdF4+og0yMoYAcOwoB2c4swbdpKAJCPE7y8Q8K02E8KgXkrtjI4MUISA2lFHbTgQgI - 8Th11uLgSF3GowwgP70vB0AW5GSkyQKyR/cOhAzfihFQVwR4PI4ay+AxcV9GzuXbj6C4 - +gmW5vzSiaU5zII5SUUHNjCHR839+Pa1pvL1k3uFuScP8oC0IKtYscSqrnzCdjsWAQ6P - FuAeGTzu0l33KBEk6PHfXz8b6zlAHk9L3BS21H/6JImDREB2LG/w3eqJQPce5Kk5g4da - SfCYlpFTQPD4HvD4U9fwyDvIf/8hgKwmgLxOALktctUicJAONiwgu3dTT0CxVYxA+yOg - AI8HT+Zev/dEF4urzFUr8yQdBpB1AMjnj24V5BBAhnKAHEQeFICAbH/W4DvVFQEhHqf7 - Lw3blJh2PKfglgCP7IaPvEMT+2/cfZAcIF8BIC9KAdLEUL+3Hu7Pqq6cwnbbHYFu3enK - VRMLGwdwj4tWRW7bdfDkRYrHarI0R4z7r7b47wEHyP+BgxQAMoECciJxkIMM+iIg2500 - +Ea1RYDB4yDqHgGPoZsSGDw+B/dYB+5Rch9yiyIQ0QlKAJmyLWLVoplTXcFBmhj2R0Cq - Lamw4fZGACY79HrrGxI8uhI8RnB4fFWpu3jk5iDJlAcLyIe38sFBsoAcM8rKFAHZ3pTB - 96kxAgSPfQ0oHid2GjzKlVjfsg6SAeQUVwdrC5OBCEg15hU23a4IUDz2H2hiYe3gOmUm - wWMK4x51G49KAHlsb0J06BJ/74ljRloiINuVMPgmtUaAxaOp5cgxFI/RCXuP5+TfeqjT - 7pEYWYGD/A5zkADIu9cvnkhP2RqxcuFMBKRakwobb28EFOAx/QQprr56q8vuUSJIumhO - 4CCP7Y2PXrNkrhCQuCagvcmD71N5BIR49PZfEgp4PNYp8CgNSNif9e2rx3evXeABaW9t - jg5S5fmEDXYoAjwe7cE9LlwZsTUF8HjtLsVj/XfdnHvkpl0Ec5ANdZ+qyp4/vJmfIwdI - fPRjhzII36zKCMBSOVJcpe7Re+6SNdHxBI83dd89Si5Y4TYPWKRDNjDnALlza/jKhb5T - XBGQqswkbEsFEeDwaG4NePRduDKc4PHCtbuPwT1+0XU8Sio6ZA6yoe5jVdkzFpAbiYN0 - pyXWAX17ISBVkEnYhCoiIMCjuxQey6o+1TXo6NIc7nJV3kGWEgeZlc4AEvZnRQepiiTC - NlQVASEeJ1M87uxEeOT1yAPywc38M0f3xDOAdCZzkAhIVWUTttPRCFA8DqDukeJxY/ye - Y2fAPT4rq/oohUcx76DD41D+N+EcJHGQHCC3hK9Y4IuA7Gj+4PtVGgEBHl0AjyvCt+xM - zyLusbQzuEdhRUcekKsD50xzR0CqNJ+wsY5FgMejs7v3nMA1gMejgMcHnQaP/BUr7M9K - S6ylj4uuEgfJAXKEuTGsYu2J90F2LJPw3SqIAOCxZ+/+A43NR9gDHhdweCxi8QgbzLG3 - Ievq1SoQkrtgpYCsJSXWBzcYB8kA0m64qRE6SBUkEzbR4QgweDQytbRzdp82J3B1J8Qj - L0gWkBUEkOez0pMJIGeAg0RAdjiPsAGVREAxHq92KjzyepQD5AYCSDdnBKRKkgkb6XAE - ODwOt3N24/F4g7rHWuHcow5frgquWCWALAFAZkoB0gAdZIezCRvoYAQYPBow7nEGcY/J - 6VnnrxaVlFaQpTmdwj3KlVg5B3n6yO54BGQHMwjfrsoIyOJxQ/zuo6fzOx0e+StWaUAe - SN4cvnw+dZBmxghIVWYWttWOCMjhcXPygcxOiEdej5yDfAMl1ksAyLgNIYFzvFgH2QdX - sbYjifAtKosAwWOfAUamnHvcELf7yOlLnRCPrCCbyG0edA6y4mVJ0ZXzmdKA7IdzkCpL - LWyo7RGgeOxnYGxG5h5nzF8ezuHxZedyjwoc5DshIGd7uTnREisCsu1JhO9QWQR4PDq5 - ec0ODJHg8c27j52ouErkKAPIz9UAyDtXzmUeSNq8jnGQVuAgYfMAXKSjsvTChtoWAYJH - 2EFHgsd1BI/nrhSVAB4/s8XVJrq2hclo3f5/wSKdHw21HzlApsZFhQQSQNqSRToIyLal - EJ6twgjI4jGKc48Ujz/4R5Lr9twj988IFSTnIAkgixlAxgAgfWCRDgJShbmFTbU5AhI8 - WoF79Jm/fN3mJILHO50Tj1IlVgBkDQPI7MMEkAGzvSYgINucQfgGVUZAgkdbpwnEPUbF - pR7JJsXVN+9qahs6HR4lDvI3LbF+/sACcn9SzLpl83w8xo22MhuMDlKVGYZttSECLB4H - mwEePQgeY5L2EzwWv6z40PncI7loFTrIbywg8wCQ26OCGUAOG2Kkjw6yDTmEp6ouAhSP - +kamwygeA0Kitqcezs7rxHiUAmRj/ecP5YyDBECuRUCqLrGwpfZEgMfj6HEePvOWSeOx - EVau/m7qPMVVpqYjD8j7Nygg1wcH+HmCgxw2xBAB2Z5swvd0NAIMHg2HEDx6+gUES+ER - 9l+V7PfYOYqrAkE2NREHyQHy8rnM/TsQkB1NJ3x/xyIgi8e1MTtY91gO7rFz4lHeQb5+ - KgVIRwaQevgs1o4lF767zREAPOr10Sd4dKR4XM+4x/tPX0NxtbPiUd5Bvii+ffls5j4E - ZJsTCN+gyggoxOPZy1Bc7cx4lAHk15p3AMjCvFOHUrevD14MDhIBqcokw7ZaHQFFeDyV - V9jZ8agEkBkEkEH+dA5yKM5BtjqL8EQVRYDD41ArWlwNAve4L/Ps5dvFLzo3HuUAWUkA - mQuAjKWAHO9oQ0us6CBVlGjYTKsiIMDjeE+/xcHrY1MPncoleKys+dp53aNkUYCgxPri - EThIAsgwAOQkWKSDgGxVCuFJqouAEI+TfPyDwgCPGV0Cj80AMjJ48aypCEjVZRm21NoI - SPBo4zh+6qwuhUeBg/wFc5CfPpQDIAtyMvYlMoAcOwoB2do0wvNUEwEej6PGMnhMpHh8 - xLrHX51waQ6zHkBywQr7s8KTdH58+1rDOchdsRwgLcgiHXSQqsk1bKXlCMjiMTJ2V1dx - jxJBEgf56ycA8j0LyLTETdRBSgDZo3vLkcQzMAIdj0D3HuSxAIOHWknwmJaRU3Ab8Pj+ - EyzN6dx4FDjIf1hAPrl3PffkQQRkxzMLW2hHBDg8WrDuEfB48GRu4b0uUFxlrlqZBwX8 - oYCso4C8VZBznAByqf/0SQSQg8h9kAjIdiQXvqXNERDicbr/0rBNiWnHeTz+7Ox45AH5 - LwVkdeVrAORFAOS2yFWLoMTqYGNhQh1k925tji2+ASPQxgh0686sXLWwcYDi6qJVDB6v - 33vyurKazD12hg3m+OqNwt84QP4PHCQB5PNHFJAJm0IRkG3MJjy9oxFg8DiIukfAYyiD - x1vUPdY1EjyyGz4qTOVOcZC7D5ID5CsOkBGrFs2c6soAsrcePvqxo7mG728xAjDZoddb - 39BEgsdt4B4vAh5fdRk8cnOQZMpDASAnMg6yLzrIFpMJT+hwBAge+xpQPE6keEwg7vHW - o+dQXCV4lNyH3ClIqORDKAFkyjYCyCmuDtYWJrCBOQKyw9mGDbQQAQEeXafOXLQqYltK - 18OjAkA+vJWfc3xvQjRxkBPHjLQ0HWSAgGwhl/DljkeAxaOp1agxPB7zbz3sUniUK7G+ - pQ7yRDoAciUCsuNZhi20MgIUj/0HmlhYO7hOkcLj265SXGUuYeVKrASQxwggl8z1RkC2 - Mp3wtA5GgMOj5cgxE739l4RGJ+w9ltP18CgFyO/1X6vfvnp899pFAOTWiJULwUHao4Ps - YKbh21sRAWk8LlwZsTUl/cTF63efvCJ4/N4V5h65Co88IG8SQMZHrxECEp9s1YqswlPa - G4FuTHHVlOJx7pI10fFdFI8ygPzCAPLCifSdW8NXLvQlgDTHEmt70wzf17oI8Hi0B/fI - 4vHCtbuPAY9f6rsUHqVKrA11n6rKnj8UANKdK7EiIFuXWnhWOyIAK8nJ3KMMHm8+fF5W - 1XXmHqUuWOE+SFik871eFpCTEZDtyC98S5siwOHR3Brw6LtwZfjWneknuioehbvr/Gyo - +1hV9gwAeebYnviNxEEygBzQtxcCsk05hie3PgIUjwMoHt29wT1upO7x5sNnZVUf6xq6 - yNIcDo/yDrIUSqwXstJ3bglfsdAX9mdFB9n61MIz2x4BAR5dJrN4zCJ4LO2C7hFkyS2a - I6tYGUA+AEAeBUCuDpzj7e5MFukgINueZ/iO1kVAHo97jp7Jv/lADo+daQcdHofyv3GC - pPuzgoMsfVzEAXIBAeQIc2NYxdoTb/NoXX7hWW2KgDQeF6wI37IzvSvjsQVATnN3trM0 - NUJAtinJ8ORWR4DHo7P7tDmBqzfGd3E88oIUAPLqecZBIiBbnVh4YnsiAHjs2bv/QGPz - EfbgHjk8Xi1i3SPsv8rehtxVrlZlHWQtKbE+uCFxkNPcnO2GIyDbk2v4npYjwODRyNTS - TohH2J5ctrjahfQoKemwgKwoLSkigEyGEuuCGYyDNEAH2XJy4RltjYA8HpPTs84TPFaQ - pTldEo/8BSstsXKAPH10d/wGKLEiINuaZHh+qyPA4XG4nbMbcY8bqHtk8FgrnHvsSnjk - BSkFyMwDyZvDV8xHQLY6u/DENkaAwaMB4x5nEPeYnJ4JeCzp0njk9SgE5KXTR3bHCQHZ - BxfptDHd8PQWIiCPx91HTud3eTzyguQA+ZI4SArI5QwgzYwN+uEcZAvphS+3LQIcHs1I - cXXG/OXhm5MPIB7JCgFuTQALyHdvoMTKADIkcLaXmxMtsSIg25ZueHYLESB47DPAyJS4 - R685gSEb4gCPlwCPb6o+dmH3KBFkE7nN4+/v9Z+rK16W3LlyjgBynQCQvXCRTgsZhi+3 - IQIUj/0MjKXxeKWo5CVfXG2ipCAZ2rV+BID80VD7kQdkFAKyDSmGp7YhAjwendy8Zgvx - +K6r45G9YpUHZBIBpA/MQVoRB4mAbEO64anNR4DgETaYMzazYtzjus1JBzLPXblD8PiZ - nXvsqniUcpAAyBoGkNlHUuMoICc42ZJFOuggm08xfLUNEZDg0ZbBY1RcKuseCR5/8I8k - 71pzj9x1Ob1ilQDyQ8XLYuIg9yfFEEB6EEAORkC2Id3w1OYjIIVHn/nL18UweCxGPFJJ - SjtIBpB52YdTt0eFBMz2AkAOMzXSR0A2n2T4aqsjIMDjBK/ZASGAx8PZtLj6rgbxCJJk - AfkbSqyN9Z8/lPOAXDbPx2PcaARkq3MNT2wxAiweB5tZjR7n4TNvGeBxP3GPgMcPjHv8 - 3dR13SMhpBCQ31gHyQAyOMDPkwByCOzPiot0Wkw1PKEVEaB41DcaMszWieAxOGo74DGP - zD0CHmH/VcmGVl3TPUoE2dQkC8gdMWsRkK3IMDylDRGQxeNaCR7LAY+NcGNHV8ejPCBf - P71/gwJyPQWkIwNIPXzUXBvyDk9VHAEGj4YUj55+AcHrGTzef/Ya8UjYSH8UOMjLZzP3 - IyAV5xQebXcE5PG4A9zjZXCPiEdOjTKA/FrzDgBZmHcKSqwIyHZnHr5RUQQAj3p99Ake - HScI8fgU8cjLUb7E+qL49uWzGfsAkEFMiXUozkEqSi881rYIcHgcyhZX18bs2Jd59vLt - 4heIRzk9wuYBcJvHj29fayoJIHNPHUqNXR+82M9zvKMNLbGig2xb9uHZshGQxuNi4h4P - ncorvE/w+BWLq7wkZR2kBJBhQf4+k2AOEgEpm1v4d5sjII1H/yCCxwzEIy9DyW9Sc5Ay - gJw1FQHZ5tTDNyiIgASPNo7jPf0Aj7GAx1yCx0rEo0SL9BcJIH8xi3RePKIOMjGGAnLs - KASkgvzCQ22KAI/HUeMm+fgHhbF4fITuUVqM8JcSQO6KjQxejIBsU9rhyUoiIMTj1FmL - gyMRj3I6lByQAuSn9+UAyIKcjDRZQPboriTYeBgj0EIEmPseBw+1GjWWwWPivoycgtsE - j59gac4vXJojUaMCQD65V5h78iAPSAuyihVLrC3kHL6sNAIcHi3APTJ43IXuUaBAmV8Z - QP75/e+vn431HCCPpyVuClvqP32SxEEiIJUmHL7QbAS69yCPBWDwOB3c46bENBaP7wGP - PxGP0oLkHCRsYA5zkNWVr5/cu04AuS1y1SJwkA42LCC7d2s26vgiRkBhBLp1Z5bmCPB4 - 8GTu9XtP2OLqP7+73g460gqU+UsIyDoA5PNHtwpyCCBDOUAOIg8KQEAqTDc82EIEGDwO - ou5xuv9SgsfjOQW3wD2+/1RH8cjqUSYtu+yfsoB8BYC8SAAZQQDpCoA0MdTvrYf7s7aQ - ePiyogjAZAdZuWpiYeMA7nHRqshtuw6evEjxWE2W5nTFDeZa+KeGAyRsYN4oAGQCBeRE - 4iAHGfRFQCrKNjzWUgRk8Bi6KYHB43MWj5L7kFtI0i70shJAphBAzpzCALI/ArKlzMPX - FUSA4LE3g0fXqTMXrYrg8PiqEvGo7N8YOUA+vJWfc3wvC8gxoyxNEZAKcg0PtRwBgse+ - BsQ9jpkI7pHD40PEozIxwnEZQL5lHGS6BJDWFiYDEZAtJx+eIRsBisf+A00srB1cp1A8 - pjDuEfHYjB7ZR82R265YB0kAeWxvQnToEn/viWNGIiBlEw3/blUEWDyaWo4cM9Eb8Bid - sPd4Tv4txGNzapQC5HeYgwRA3r1+8UR6ytaIlQvBQdojIFuVfXiSTARk8LgyYmtK+glS - XH31Ft1jc5JU6CCP7Y2PXrNkrhCQuCZAJuPwz+Yi0I1xjwwe5y4heDyGeGxOiOxrAgf5 - vf4LAPLx3WsXCCDDWUCao4NsLvHwNUUR4PFoD+5xIYvHa3cfEzzWf8e5R+XKFACyoe5T - VdnzhzeJg2QA6c45SHz0o6K0w2NKIgAryUlxlcPjmuh4gsebD5+XMUtzcO5RqSCVAHIn - AaTvZHCQCEglSYeHlUWAw6O5NeDRd+HK8K07009cYPD4BfGoVIvkBU6PdAPzuo9VZc9Y - QG4kDpIB5IC+uHmAstzD4/IREODR3XvuEgken5VVfapr+MlvEdBsZnbRFzlBwm0e1EGW - EgeZlc4C0gUBKZ9veKTZCAjw6DJZiMfSt9WIx5b+meH0yAPywc38M0f3xG9cEzjH292Z - zEEiIJtNQHxRKgIUjwOoe6R43Bi/5+gZcI+Ax49SeOy6O+g0J0pOkLD9HAvIIgrILeEr - FvjCBuYjqIPsibd5SCUd/qEsAjJ4XBG+ZWd6FnGPiMfmZCh5jdOjPCBXB86Z5u5sZwkb - mKODVJZ+eFwmAjwend295wSuZvH4APEokVzzv3CCFADyKnGQPCCNYRUrAlIm7/BPhREA - PPbs3X+gsfkIe3CPC1g8Xi1i8QgbzOFjAVqnRwrIWlJifXCDcZAEkG7OdsMRkApTDw8q - iACDRyNTSztn92kSPML+q+gem5ch/6oMICtKHxddPZ+VnkwAOYM6SGMDBKSC3MNDchGQ - x2NyetZ5gscKUlxFPPKyU/obp0cpQJ4+ujt+AwJSLuHwQLMR4PA43M7ZTRaPtcK5Ryyu - KtWjZFEA6yArSksAkJkHkjcjIJtNPnxRNgIMHg0Y9ziDuEcGjyWIR+Xyk3tFESAvnT6y - O04IyD64SEc2+/Bv2QjI4nFD/O6jp/MZ94h4lBOesgOcIOUBuXw+dZBmxgb9sMQqm334 - t0wEpPE4f3n45uQDmeAeEY/KlKf4OKdHzkG+gRIrA8iQwNlebk60xIqAlMk+/FM2AgSP - fQYYmbLuMWRD3O4jpy8BHt9UfUQ8KtaewqNUkE1NfyggP1dXvCwpukId5DoBIHvhHKRs - AuLfwghQPPYzMDYjc48zODxeKSp5icVVhbJTelAAyB8NtR/fISCFeYa/ty4CPB6d3Lxm - Bwrw+A7xqFR7Cl+QB+SdK+cyDyRtZgFpRRwkArJ1edlFzyJ4hB10JHhcR9zjuSt3CB4/ - s3OPTTTRFKYgHhREQCEgs4+kxkUxDtKWLNJBB9lFlda6jy3Boy2DxyiJeyR4/MHf94hz - jwLlKflVDpDFBJD7k2IAkD4eLvZWZoMRkK3Lyy56lgSPVuAefeYvXxeThHhUoraWD0sD - soY6yLzsw6nbo0ICZntNcLIdZmqkj4DsolprzccW4HECcY9RcalHsmlx9V0N4rFlBcqc - wQLyN5RYG+s/fyh/KQHksnk+HuNGIyBbk5Rd9xwWj4PNrEa7ePjMWwZ43E/cY/HLig/o - HmXE1oo/hYD8VisEZHCAnycBJNnAHBfpdF3FNf/JKR71jUyH2ToBHgOCo7anHs7OI3OP - gEfYYE7yUDl0j61QI5yiBJA7YtYiIJtPRXz1r78EeBwnjcdywGMj3NjxuwmLq61TInOW - LCBfP71/gzrI9RSQjgwg9fBZrCg/BRFg8Gg4hODR0w/x2BblKTlXASAvn83cj4BUkH54 - SDoCsnhcG7ODdY+IRyVya/GwFCC/1rwDQBbmnYISKwJSOvnwL7kIAB7J9uSAR0eKx/WM - e7z/9DW6xxaFp+wEWUC+KL4NgNwHgAxiSqxDcQ5SLhPxAERAIR7PXr5T/ALxqExtLR+X - AWQlAWTuqUOpseuDF/t5jne0oSVWdJAoQdkISONxcTDB46m8QorHr1hcbVl6is9QCMgM - AGRYkL/PJJiDREDKZiL+DRHg8DjUajQprgaBe9yXcfbybcSjYp219mhzgJw1FQGJ4lMc - AQkebRzHe/oBHmNTD53KJXisrEE8tlZ9Cs6TAPIXs0jnxSNwkBn7EhlAjh2FgFSckF37 - qBCPk3z8g8IQjwq01Z5DSgC5KzYyeDECsmurTvmnF+Jx6qzFwZGIx/aIT9F7pAD56X05 - ALIgJyNNFpA9uiv/dvCVLhYBHo+jxjJ4TKTu8RFbXP2FS3MUSa1Vx+QBea8w9+RBHpAW - ZBUrlli7mOSa/bgcHi3APTJ43IXusVVqa8VJPCB/NtZzgDyelrgpbKn/9EkSB4mAbDZF - u9SL3XuQxwIMHmolwWNaRk7BbcDj+0/1jT8Rj62QndJTOEDC/qw/vn2trnz95N51Asht - kasWgYN0sGEB2b1bl8o5/LBKI6AAjwdP5hbee4LFVaUqa8MLDCD//P7318/GOgrIWwU5 - BJChHCAHkQcFICCVJmgXe0GIx+n+S8M2JaYdzym4JcAju6NVG5IQT5VEQBaQrwCQFwkg - IzhAmhjq99bD/Vm7mOyUfdxu3enKVRMLGwdwj4tWRW7bdfDkxesEj9Vk7hE3mJNIq32/ - cID8HwvI548oIBMoICcSBznIoC8CUll+drXjDB4HUfcIeAzdlMDg8Tm4xzrqHhGP7RMi - +y4lgEwhgJw51RUcpIlhfwRkV9Odks8Lkx16vfUNCR5dp85ctCqCw+MrxGOHZMi/WQ6Q - D2/l5xzfywJyzChLUwSkkuzseocJHvsaUDxOVIRHyWM6+PzC39oWARlAvmUcZDoDyCmu - DtYWJrCBOTrIric++U9M8dh/oImFtYPrFIrHFMY9Ih7bJrrmzlYIyGN7E6JDl/h7Txwz - EgEpn5hd9AiLR1PLkWMoHqMT9h7Pyb/1kHOPiMfmhNbK1wSA/A5zkADIu9cvnkhP2Rqx - cuFMBGQXlZ6ijy2Dx5UR21LST5Di6qu3WFxtpdpacZoSQMZHr1kyVwhIXBOgKEm70DEh - Hr3nLgkFPB5DPLZCYW07RQjI+i8AyMd3r10ggAyngLS3NkcH2YVUp/Sj8ni0B/e4cGXE - VoLHa3cfEzzWf8e5x7bJTvnZ0oCsKnv+8GZ+zrG9DCDdOQeJj35Umqld4wVYKkeKq9Q9 - Ah7XRMcTPN5E96hcWe17RQkgdxJA+k52RUB2Db218Ck5PJpbAx59F64M37oz/cQFBo9f - EI/tk57idwkA2VD3sarsGQvIjcRBMoAc0Bc3D2ghYTv5ywI8ukvhsazqU13DT36LAMU5 - hkdbHwFZQJYSB5mVzgLSBQHZyaXWmo8nxONkxGPrxdWOMzk9/oZVrAwgH9zMP3N0T/zG - NYEASGcyB4mAbE3Wdt5zKB4HUPdI8bgxfs+xM+Aen5VVfZTCI+6g0w4FyryFEyRsP/ed - lFhLHxdRQG4JX7HAd7KL/QgssXZepbXqkwnw6AJ4XBG+ZWd6FnGPpW+r0T3KyKnDf3J6 - lAfk6sA509yd7RCQrcraznsSj0dnd+85gasBj0cBjw8Qjx0Wn6IGOEEKAHmVOEgekMaw - irUn3gfZeRXX7CcDPPbs3X+gsfkI2J7cdwGHxyIWj7DBHHufFV6tKpJXm49xeqSArCUl - 1gc3GAfJAnK4qRE6yGZTtlO/yODRyNTSztl9GuKxzfpq8xs4QbKArAAHefV8VnoyAeQM - 6iCNDRCQnVpzzXw4eTwmp2edv4p4bLPOWvsGTo8ygNwdv4EA0s3ZDgHZTL529pc4PA63 - c3bj8Qjbk0NxtVY494iXq60VXEvncYKUALIEAJmZnrwZAdnZ1dbi52PwaMC4xxnEPTJ4 - LCmtIMVVdI8tiasdr3N6FALy0ukj0oDsg4t0WkzeTniCLB43xO8+ejof8dgOmbX+LZwg - pQF5AAC5fD51kGbGBv2wxNoJ5dbSR5LG4/wV4ZuTD2SCe0Q8tl5dbT+T0yMHyDdQYiWA - jNsQEjjbi3WQCMiWkrcTvk7w2GeAkSnnHjfE7T5y+hLg8Q26x7brrNXvoIJsavpDAfm5 - uuJlSdGV85kAyHUCQPbCOchOqLhmPxLFYz8DYzMy9zhj/nIJHl+ie2y1uNpxogCQPxpq - P76TAaQTLbEiIJvN3c74Io9HJzev2YEhPB7fYXG1HTpr9VvkAXnnyrnMA0kcIK2Ig0RA - dkbNNfOZCB5hBx0JHtcR93juyp0SwONntrjaRFOn1YmGJ7YqAgoBmX0kNS6KOkgnWzIH - iYBsJnc740uyeIySuEeCxx/8fY8499gqlbXhJDlAFhNA7k+KAQfpA4t0rMwGIyA7o+aa - +UwSPFqBe/SZv3zd5iTEYxs01ZFTpQFZQx1kXvbh1O1RIQGzvSY42Q4zNdJHQDaTvZ3v - JQkebZ0mEPcYFZd6JJsWV9/VIB47orZWvJcF5G8osTbWf/5Q8VICyGXzfDzGjUZAdj7B - Nf+JWDwONrMa7eJB8BiTtJ+4x+KXFR/QPbZCUh06RQjIb7VCQAYH+HkSQJINzHGRTvM5 - 3JlepXjUNzIdRvEYEBK1PfVwdh6ZewQ8wgZzkkeSo3vskPKUvFkGkOUSQK5FQHYmmbX2 - swjwOM7DZ94yHo/lgMdGWLn6uwmLq0rEpILDsoB8/fT+Deog11NAOjKA1MNnsbY2oXX8 - PAaPhkMIHj39AoIRjyoQWVuaUADIy2cz9++IQUDquLTaM3xZPK6N2cG6R8RjW1TV/nMV - ALIw7xSUWBGQ7UloHX8P4FGvjz7BoyPF43rGPd5/+hrdY/s11qZ3ygLyRfFtAOQ+AGQQ - U2IdinOQOq6yVg9fIR7PXr5T/ALx2CZRdeBkKUB+rakEB1mYe+pQauz64MV+nuPRQbY6 - m3X/REV4PJVXSPH4FYurHVBZG96qEJAZFJD+PpNgDhIBqftKa9Un4PA41Go0Ka4GgXvc - l3H28m3EYxvk1OFTmwPkrKnjHW3oHCSWWFuV0jp9kgSPNo7jPf0WB6+PTT10KpfgsbIG - 8dhhobW2AQkgf9FFOuUvHoGDzNiXGBMWBIAcOwoBqdMqa/XghXic5OMfFIZ4bK2EVHqe - EkDuio0MXoyAbHU66/yJQjxOnYV4VKnI2tKYFCA/vSeALMiRB2SP7jqfcvgBlEeAx+Oo - sQweE6l7fMQWV3/h0py2iKoD58oD8l5h7slDPCAtyCpWdJDKc7kzvMLh0QLcI8FjZOwu - dI8dUFUH3soD8mdjPQfI42mJm8KW+k/nHSQCsjPoTtln6N6DPBZg8FArCR7TMnIKbgMe - 33+qb/yJeOyAwNr4Vg6Q//7z68e3r9WVr5/cu5578uCubZGrFoGDdLBhAdm9m7IvE4/r - egQU4PHgydzCe0+wuNpGNangdAaQf37/++tnYx0A8vmjWwU5BJChHCAHkQcFICB1XXXK - xy/E43T/pWGbEtOO5xTcEuCR3dFKBemGTbQQAVlAvgJAXpQCpImhfm893H5OeT7r+Cvd - utOVqyYWNg7gHhetity26+DJi9cJHqvJ3CNuMNeChFT7MgdI2MBcCMgECsiJZA5ykEFf - BKSOi66Z4TN4HETdI+AxdFMCg8fn4B7rqHtEPKpWcs22pgSQKdsiVi2aOdUVHKSJYX8E - ZDMJrdsvwWSHXm99Q4JHV4LHCA6PrxCPzQpHXS/KAfLhrXxwkCwgx4yyMkVA6rbkmh09 - wWNfA4rHiYrwKHlMh7ryD9uVjoAMIN+yDpIB5BRXB2sLE9jAHB1ks1mtsy9SPPYfaGJh - 7eA6ZSbBYwrjHhGP0jLR3F8KAXlsb0J06BJ/74ljRloiIHVWbi0OnMWjqeXIMRSP0Ql7 - j+fk33rIuUfEo+aEyPYkAOR3mIMEQN69fvFEesrWiJULZyIgW0xpXT5BAR7TT5Di6qu3 - WFzVuBKFgmz6Q7afY0qsxEEe2xsfvWbJXCEgcU2ALktP4diFePSeuyQU8HgM8agtIQr1 - +H9k+7lf3+u/ACAf3712gQAynALS3tocHaTCbNb5gzwe7cE9LlwZsTUF8Hjt7mOCx/rv - OPeoHWUKHGRD3aeqsucPb/KAdOccJD76Uef1J/sBYKkcKa5S9wh4XBMdT/B4E92jdnTI - 9Sp0kAJA7iSA9J3iioCUzeNO8jeHR3NrwKPvwpXhBI8XGDx+QTxy8tD8f6UA+bGq7BkL - yI3EQTKAHNAXNw/oJDKUfAwBHt2l8FhW9amu4Se/RYDmM7Jr9ygLyFLiILPSGUDC9nPo - ICU53Il+EeJxMsXjTsSjKP4h4PRISqwNdQSQD27mnzm6J37jmkAApDOZg0RAdiIp0o9C - 8TiAukeKx43xe46dAff4rKzqoxQecQcdTauUEyRXYuUAuSV8xQJfAOQILLF2NjX+JcCj - C+BxRfiWnelZxD2Wvq1G96hpBUr3x+lRHpCrA+dMc3e2s4QNzNFBdipN8nh0dveeE7gG - 8HgU8PgA8SitDa38xQkS9melc5Clj4uuEgfJA9IYVrH2xPsgO40kAY89e/cfaGw+ArYn - 913A4bGIxSNsMMfeZ4VXq1pQJKdHCsha6iBvMA6SBeRwBGSnkSL9IAwejUwt7Zzdp80J - XI141ILslHfJCZIFZAUB5Pms9GQCyBnUQSIgO5Mg5fGYnJ51/iriUblENPoKp0cZQO6O - 30AA6eZsh4DsTHL8i8PjcDtnNx6PsD05FFdrhXOPeLmqUR1KOuMEKQFkCQAyMz15Mw9I - A3SQnUWTDB4NGPc4g7hHBo8lpRWkuIruUaILbf3C6VEIyEunj0gDsg8u0ukcipTF44b4 - 3UdP5yMetaU+Bf1ygpQG5AEA5PL51EGaGRv0wxJrp9CjNB7nLw/fnHwgE9wj4lGBMLR0 - iNMjB8g3zx7cIICM2xASONvLzYk6SARk59Aj3NjRZ4CRKeseQzbE7T5y+hLg8Q26Ry3J - T75bKsgmch8kzEF+rq54WVJ05XwmAHKdAJC9cA5S9xVJ8djPwNiMzD3O4PB4pajkJbpH - eV1o64gMIN8hIHVfeYo/AXGPDB6d3LxmBwrw+A6Lq9qSn3y/8oC8c+Vc5oEkDpBWxEEi - IBXnuA4dJXiEHXQkeFxH3OO5K3cIHj+zxdUmmgzyOYJHNBcBASB/NNR+ZACZfSQ1Lopx - kLZkDhIdpA4pT/FQZfEYJXGPBI8/+Psece5Rc+JT1JMcIIsJIPcnxYCD9PFwsbcyG4yA - VJzjOnRUgkcrcI8+85ev25yEeFQkB60fkwZkDQVkXvbh1O1RIQGzvSY42Q4zNdJHQOqQ - 9hQNVYJHW6cJxD1GxaUeyabF1Xc1iEeti1A4ABaQv6HE2lj/+UPFSwkgl83z8Rg3GgGp - KMF16xiLx8FmVqNdPAgeY5L2E/dY/LLiA7pHoRq0/7sQkN9qhYAMDvDzJIAkG5jjIh3d - UqD0aCke9Y1Mh1E8BoREbU89nJ1H5h4Bj7DBnOSR5OgeRSLIpiYOkOUSQK5FQEqnta7+ - JcDjOA+fect4PJYDHhth5ervJiyual+JzAhkAfn66f0b1EGup4B0ZACph89i1VU50hs7 - +ugbDiF49PQLCEY8ikV7Csch4yAJIC+fzdy/IwYBqbMSFA5cFo9rY3aw7hHxqFAQWj6o - AJCFeaegxIqAFKa1zv4O7lGPwaMjxeN6xj3ef/oa3aOWpae4e1lAvii+DYDcB4AMYkqs - Q3EOUmfVSB4qR5bmkOIqdY8Uj2cv3yl+gXhUrAdtH5UC5NeaSnCQhbmnDhFALvbzHI8O - UnfFCCOXxuPiYILHU3mFFI9fsbiqbfEp6l8hIDMoIP19JsEcJAJSZyXJ4XEog8cgwOO+ - jLOXbyMeFSlBHMeUATIWADlr6nhHGzoHiSVWXRSlBI82juM9/QCPsamHTuUSPFbWIB7F - oT+5UUgA+Ysu0il/8QgcZMa+xJiwIADk2FEISF2UIhmzEI+TfPyDwhCPctkvvgNKALkr - NhIBqatKZMYtxOPUWYhH8WlP4YikAPnpPQFkQU5Gmiwge3TX7ezscqPn8ThqLIPHROoe - H7HF1V+4NEehHrR9UB6Q96DEepAHpAVZxYoOUtcEzeHRAtwjwWNk7C50j9oWW2v65wH5 - s7GeA+TxtMRNYUv9p/MOEgGpW4rs3oPOPQ61kuAxLSOn4Dbg8f2n+safiMfWaEMb53CA - hO3nfnz7Wl35+sm967knD+7aFrlqEZRYHWxYQHbvplsJ2bVHqwCPB0/mFt57gsVVbYis - LX0ygPzz+99fPxvrKCBvFeQQQIZygBxEHhSAgNQlhQvxON1/adimxLTjOQW3BHhkd7Rq - S6bguZqIgCwgXwEgLxJARnCANDHU762H28/pkB67dacrV00sbBzAPS5aFbltF+DxOsFj - NZl7xA3mNKGsdvbBARI2MKeAfP6IAjKBAnIimYMcZNAXAalDcvyLweMg6h4Bj6GbEhg8 - Pgf3WEfdI+KxnWpR/9uUADKFAHLmVFdwkCaG/RGQOqRHmOzQ661vSPDoSvAYQfB4EfD4 - CvGofj11uAc5QD68lQ8OkgXkmFFWpghIHVLjXxSPfQ0oHicqwqPkMR0dTh1sQA0RkAHk - W9ZBMoCc4upgbWECG5ijg9QVTVI89h9oYmHt4DplJsFjCuJRDbpRW5MKAXlsb0J06BJ/ - 74ljRloiIHVFi2ScxD0CHk0tR46heIxO2Hs8J//WQ849Ih7VpiTVNCwA5HeYgwRA3r1+ - 8UR6ytaIlQtnIiB1SYswVgV4TD9B3eNbLK6qRjDqbkUJIOOj1yyZKwQkrgnQAW0K8eg9 - d0ko4PEY4lHdElJp+0JA1n8BQD6+e+0CD0h7a3N0kDqgRDpEHo/24B4XrozYmgJ4vHb3 - 8SvAY/13nHtUqXLU1Jg0IKvKnj+8mZ9zbC8DSHfOQeKjH3VAlLBUTuIeAY9rouMJHm+i - e1STdNTSrBJA7twavnKh72RXBKQOCJEZIodHc2vAo+/CleEEjxcYPH5BPKpFPWpoVADI - hrqPVWXPWEBuJA6SAeSAvrh5gPhlKcCjuxQey6o+1TX85LcIUEMSYZMqi4AsIEuJg8xK - ZwHpgoAUvxLpCIV4nEzxuBPxqDKVaK4hTo+/YRUrA8gHN/PPHN0Tv3FNIADSmcxBIiDF - L0qKxwF07pHicWP8nmNnwD0+K6v6KIVH3EFHc+JqT0+cIGH7ue+kxFr6uIgCckv4igW+ - k13sR2CJVfxqlMw9gnt0ATyuCN+yMz2LuMfSt9XoHtujC229h9OjPCBXB86Z5u5sZwkb - mKODFLkmeTw6u3vPCVwDeDwKeHyAeNSWrtrdLydIASCvEgfJA9IYVrH2xPsgRSxJcI89 - e/cfaGw+guBxAYfHIhaPsMEce58VXq22WyeaeiOnRwrIWlJifXCDcZAsIIcjIEUsRTo0 - Bo9GppZ2zu7T5gSuRjxqSj1q6IcTJAvICnCQV89npScTQM6gDhIBKW5ByuMxOT3r/FXE - oxrUov4mOT3KAHJ3/AYCSDdnOwSkuOVI91/tO8DIdLidsxuPR9ieHIqrtcK5R7xcVb+c - Ot4DJ0gJIEsAkJnpyZt5QBqggxSvJhk8GjDucQZxjwweS0orSHEV3WPHJaLRFjg9CgF5 - 6fQRaUD2wUU6YlUk5x45PG6I3330dD7iUaMiUmVnnCClAXkAALl8PnWQZsYG/bDEKlI9 - SuNx/vLwzckHMsE9Ih5VqRFNtsXpkQPkGyixEkDGbQgJnO3l5kQdJAJSrHqEGzv68O4x - ZEPc7iOnLwEe36B71KSKVNgXFWRT0x8KyM/VFS9Liq6czwRArhMAshfOQYpRkRSP/QyM - zcjc4wwOj1eKSl6ie1ShRDTalAwg3yEgxag8xWMi7pHBo5Ob1+xAAR7fYXFVoypSYWfy - gLxz5VzmgSQOkFbEQSIgFStCq0cJHnsJ8LiOuMdzV+4QPH5mi6tN9OtVYbpgU2qOgACQ - PxpqPzKAzD6SGhfFOEhbMgeJDlKrylPcuSweoyTukeDxB3/fI849qllDKm1eDpDFBJD7 - k2LAQfrAIh0rs8EISMWK0OpRCR6twD36zF++bnMS4lGlytBOY9KArKGAzMs+nLo9KiRg - ttcEJ9thpkb6CEitak9R5xI82jpNIO4xKi71SDYtrr6rQTxqR0sq6ZUF5G8osTbWf/5Q - 8VICyGXzfDzGjUZAKpKDto+xeBxsZjXaxYPgMSZpP3GPxS8rPqB7VIkwtNSIEJDfaoWA - DA7w8ySAJBuY4yIdbStQun+KR30j02EUjwEhUdtTD2fnkblHwCNsMCd5JDm6Ry3pqt3d - ygCynAXkjpi1CEhpEYjnLwEex3n4zFvG47Ec8NgIK1d/N2Fxtd2S0OobZQH5+un9G9RB - rqeAdGQAqYfPYhWPHOmNHX30DYcQPHr6BQQjHrUqIdV2rgCQl89m7kdAikiA0kORxePa - mB2se0Q8qlYb2mhNASAL805BiRUBKS0D0fwF7lGPwaMjxeN6xj3ef/oa3aM2FKTiPmUB - +aL4NgByHwAyiCmxDsU5SNFoEQaiEI9nL98pfoF4VLE0tNKcFCC/1lSCgwRAHiKAXOzn - OR4dpJjESPSoAI+n8gopHr9icVUrGlJppwoBmUEB6e8zCeYgEZAikiSHx6FWo0lxNQjc - 476Ms5dvIx5VKgotNqYIkLkAyFgA5Kyp4x1t6BwklljFIUoJHm0cx3v6LQ5eH5t66FQu - wWNlDeJRizJSXdcSQP6ii3TKXzwCB5mxLzEmLAgAOXYUAlIcUiSjEOJxko9/UBjiUXVC - EElLSgEZiYAUjxKZkQjxOHUW4lEkElLtMKQA+ek9AWRBjjwge3QXW3Z2ufHweBw1lsFj - InWPj9ji6i9cmqNaaWilNXlA3isEB7krlgOkBVnFig5S+/Ln8GgB7pHgMTJ2F7pHrWhG - rZ3ygPzZWM8B8nha4qawpf7TeQeJgNS2Irv3II8FGDzUSoLHtIycgtuAx/ef6ht/Ih7V - KhONNc4B8t9/fv349rW68vWTe9dzTx7ctS1y1SIosTrYsIDs3k3bCdm1+1eAx4Mncwvv - PcHiqsa0opGOGED++f3vr5+NdRSQtwpyCCBDOUAOIg8KQEBq998DIR6n+y8N25SYdjyn - 4JYAj+yOVhpJGuxEbRGQBeQrAORFAsgIDpAmhvq99XD7Oa3qsVt3unLVxMLGAdzjolWR - 23YdPHnxOsFjNZl7xA3m1CYQTTfMARI2MKeAfP6IAjKBAnIimYMcZNAXAalVOf7F4HEQ - dY+Ax9BNCQwen4N7rKPuEfGoaeGoqT8lgEwhgJw51RUcpIlhfwSkVvUIkx16vfUNCR5d - p85ctCqCw+MrxKOaZKG9ZuUA+fBWPjhIFpBjRlmZIiC1qsa/KB77GlA8TlSER8ljOrSX - RdizqiIgA8i3rINkADnF1cHawgQ2MEcHqT1NUjz2H2hiYe3gOoXiMYVxj4hHVYlATO0o - BOSxvQnRoUv8vSeOGWmJgNSeFknPxD0CHk0tR46heIxO2Hs8J//WQ849Ih7FJKcOj0UA - yO8wBwmAvHv94on0lK0RKxfOREBqV4vQuwweV0ZsS0k/QYqrr95icbXD2S/CBpQAMj56 - zZK5QkDimgCtaFOIR++5S0IBj8cQjyLUkaqGJARk/RcA5OO71y7wgLS3NkcHqRUl0k55 - PNqDe1y4MmIrweO1u48JHuu/49yjqmQgnnakAVlV9vzhzfycY3sZQLpzDhIf/agVUcJS - OYl7BDyuiY4neLyJ7lE8+lH1SJQAcufW8JULfSe7IiC1IkSmUw6P5taAR9+FK8O37kw/ - cYHB4xfEo6qlII72BIBsqPtYVfaMBeRG4iAZQA7oi5sHaEOWAjy6S+GxrOpTXcNPfosA - cWQSjkIVEZAFZClxkFnpLCBdEJDaUCLtU4jHyYhHVSS7DrTB6fE3rGJlAPngZv6Zo3vi - N64JBEA6kzlIBKQ2REnxOIDOPVI8bozfc+wMuMdnZVUfpfCIO+jogM5aPUROkLD93HdS - Yi19XEQBuSV8xQJf2J91BJZYtaFGydwjuEcXwOOK8C0707OIeyx9W43usdXprXMncnqU - B+TqwDnT3J3tLGEDc3SQGtckj0dnd+85gasBj0cBjw8QjzonsbYNmBOkAJBXiYPkAWkM - q1h74n2QGpUkuMeevfsPNDYfQfC4gMNjEYtH2GCOvc8Kr1bblu6iP5vTIwVkLSmxPrjB - OEgWkMMRkBqVIu2MwaORqaWds/s0xKPoVaTCAXKCZAFZAQ7y6vms9GQCyBnUQRobICA1 - K0mFeDx/FfGowrwXa1OcHmUAuTt+AwGkm7MdAlKzYoTeODwOt3N24/EI25NDcbVWOPeI - l6tilVX7x8UJUgLIEgBkZnryZgSkxoXIdMjg0YBxjzOIe0xOzwI8lpRWkOIqusf2J7sO - vJPToxCQl04fkQZkH1ykozlxyuJxQ/zuo6fzEY86ICZVDJETpDQgDwAgl8+nDtLM2KAf - llg1pkdpPM5fEb45+UAm4lEVqa4TbXB65AD5BkqsBJBxG0ICZ3u5OVEHiYDUnB7hxo4+ - A4xMOfe4IW73kdOXAI9v0D3qhKA6OkgqyKamPxSQn6srXpYUXTmfCYBcJwBkL5yD1Iwi - KR77GRibkbnHGfOXS/D4Et1jRzNdN94vAOSPhtqP7xCQmlGe4l6Ie2Tw6OTmNTswhMfj - Oyyu6oagOjpKeUDeuXIu80ASB0gr4iARkIr1o+KjBI+wg44Ej+uIezx35U4J4PEzW1xt - ol9YR791fL9YI6AQkNlHUuOiGAdpS+Yg0UGqWHmKm5PFY5TEPRI8/uDve8S5R7HKqePj - kgNkMQHk/qQYcJA+Hi72VmaDEZCK9aPioxI8WoF79Jm/fN3mJMRjxxNcx1qQBmQNdZB5 - 2YdTt0eFBMz2muBkO8zUSB8BqWLtKWpOgkdbpwnEPUbFpR7JpsXVdzWIRx2TVfuHywLy - N5RYG+s/f6h4KQHksnk+HuNGIyAViUf1x1g8DjazGu3iQfAYk7SfuMfilxUf0D22P791 - 7Z1CQH6rFQIyOMDPkwCSbGCOi3RUr0DpFike9Y1Mh1E8BoREbU89nJ1H5h4Bj7DBnOSR - 5OgedU1ibRuvDCDLJYBci4CUlow6/xLgcZyHz7xlPB7LAY+NsHL1dxMWV9uW2bp5tiwg - Xz+9f4M6yPUUkI4MIPXwWazqlCO9saOPvuEQgkdPv4BgxKNuqkkFo1YAyMtnM/fviEFA - qlWCwsZl8bg2ZgfrHhGPKkhxnWpCASAL805BiRUBKZSMWn8H96jH4NGR4nE94x7vP32N - 7lGnxKSKwcoC8kXxbQDkPgBkEFNiHYpzkGpVI3moHFmaQ4qr1D1SPJ69fKf4BeJRFRmu - W21IAfJrTSU4yMLcU4dSY9cHL/bzHI8OUr1ihNYV4fFUXiHF41csruqWnDo+WoWAzKCA - 9PeZBHOQCEi1SpLD41AGj0GAx30ZZy/fRjx2PLd1sYXmADlr6nhHGzoHiSVWdYlSgkcb - x/GefouD18emHjqVS/BYWYN41EVFdXDMEkD+oot0yl88AgeZsS8xJiwIADl2FAJSXVIk - 7QrxOMnHPygM8djBfNb1tysB5K7YyODFCEh1apHqkSuuAh6nzkI86rqaVDB+KUB+ek8A - WZCTkSYLyB7d1Z2bXbB9Ho+jxjJ4TKTu8RFbXP2FS3NUkOG61YQ8IO8V5p48yAPSgqxi - RQepjn8uOPdoweIxMnYXukfdko/qR8sD8mdjPQfI42mJm8KW+k/nHSQCUvWK7N6Dzj0O - tZLgMS0jp+A24PH9p/rGn4hH1We7+FvkAPnvP79+fPtaXfn6yb3rBJDbIlctAgfpYMMC - sns31Sdk125RAR4PnswtvPcEi6vil436RsgA8s/vf3/9bKwDQD5/dKsghwAylAPkIPKg - AASkqv/1EOJxuv/SsE2JacdzCm4J8MjuaKW+7x5bFl8EZAH5CgB5UQqQJob6vfVw+zkV - 67Fbd7py1cTCxgGKq4tWRW7bdfDkxesEj9Vk7hE3mBOfVjQyIg6QsIG5EJAJFJATyRzk - IIO+CEgVy/EvBo+DqHsEPIZuSmDw+BzcYx11j4hHjeS/2DpRAsiUbRGrFs2c6goO0sSw - PwJSxXqEyQ693vqGBI+uBI8RHB5fIR7FphANj0cOkA9v5YODZAE5ZpSVKQJSxWr8i+Kx - rwHF40RFeJQ8pkPDyYDdaT0CMoB8yzpIBpBTXB2sLUxgA3N0kKrUJMVj/4EmFtYOrlNm - EjymMO4R8ah1PWh9AAoBeWxvQnToEn/viWNGWiIgValF0hZxj4BHU8uRYygeoxP2Hs/J - v/WQc4+IR62rQnsDEADyO8xBAiDvXr94Ij1la8TKhTMRkKrWIrSnAI/pJ0hx9dVbLK5q - Twhi6VkJIOOj1yyZKwQkrglQkTaFePT2XxIKeDyGeBSLHLQ+DiEg678AIB/fvXaBADKc - AtLe2hwdpIqUSJvh8WgP7nHhyoitKQSPdxk8fse5R60rQssDEACyoe5TVdnzhzfzc47t - ZQDpzjlIfPSjikQJS+Uk7tF77pI10fGIRy0rQFzdKwHkTgJI3ymuCEgVCZFphsOjuTXg - 0XfhynCCxwvX7j4G9/ilHvEoLm1oZTRSgPxYVfaMBeRG4iAZQA7oi5sHqEaWAjy683i8 - +fB5WdWnuoaf/BYBWkkF7FQEEZAFZClxkFnpDCAnuyAgVaNE2ooQj5MpHnciHkWgATEN - gdPjb1jF2lBHAPngZv6Zo3viN64JBEA6kzlIBKRqREnxOIDOPVI8bozfc+xM/s2Hz8qq - PkrhEXfQEZNENDsWTpBwH+R3UmLlALklfMUCXwDkCCyxqkaNkrlHcI8ugMcV4Vt2pmcR - 91iK7lGzOS/m3jg9ygNydeCcae7OdpawgTk6SBVoksejs7v3nMA1gMejgMcHiEcx60Pj - Y+MECfuzsoAsukocJA9IY1jF2hPvg+ygJME99uzdf6Cx+QiCxwUcHotYPMIGc+x9Vni1 - qnENiKlDTo8UkLXUQd5gHCQLyOEIyA5Kkb6dwaORqaWds/u0OYGrEY9iUoGIxsIJkgVk - Renjoqvns9KTCSBnUAeJgOy4IOXxmAzu8SriUURKEMdQOD3KAHJ3/AYCSDdnOwRkx+VI - 91/tO8DIdLidsxuPR9ieHIqrtcK5R7xcFYcstDcKTpASQJYAIDPTkzfzgDRAB9kxTTJ4 - NGDc4wziHgGP568WlZRWkKU56B61l/6i65nToxCQl04fkQZkH1yk0xFFcu6Rw+OG+N1H - T+cjHkUnBjEMiBOkNCAPACCXz6cO0szYoB+WWDugR2k8zl8Rvjn5QCbiUQzJL8IxcHrk - APnm2YMbBJBxG0ICZ3u5OVEHiYDsiB7hxo4+Ave4IW73kdOXAI9v0D2KUBDaHhIVZFPT - HwrIz9UVL0uKrpzPBECuEwCyF85BtleRFI/9DIzNyNzjjPnLJXh8ie5R27kvxv5lAPkO - Adle5Sl+H3GPDB6d3LxmB4bweHyHxVUxCkLbY5IH5J0r5zIPJHGAtCIOEgGpWG0tHiV4 - 7CXA4zriHs9duVMCePzMFleb6Feg7TzA/sURAQEgfzTUfmQAmX0kNS6KcZC2ZA4SHWSL - ylN8giweoyTukeDxB3/fI849ikMO2h+FHCCLCSD3J8WAg/TxcLG3MhuMgFSsthaPSvBo - Be7RZ/7ydZuTEI/aT3lRj0AakDUUkHnZh1O3R4UEzPaa4GQ7zNRIHwHZovYUnSDBo63T - BOIeo+JSj2TT4uq7GsSjqGWhvcGxgPwNJdbG+s8fKl5KALlsno/HuNEISEVSa80xFo+D - zaxGu3gQPMYk7SfusfhlxQd0j9rLeHH3LATkt1ohIIMD/DwJIMkG5rhIpzUKlD6H4lHf - yHQYxWNASNT21MPZeWTuEfAIG8xJHkmO7lHcEtHs6GQAWS4B5FoEpLTA2vaXAI/jPHzm - LePxWA54bISVq7+bsLiq2VzXhd5kAfn66f0b1EGup4B0ZACph89ibZsc6Y0dffQNhxA8 - evoFBCMedUENIhijAkBePpu5f0cMArKNEhSeLovHtTE7WPeIeBRB0ot4CAoAWZh3Ckqs - CEihwNr4O7hHPQaPjhSP6xn3eP/pa3SPIhaDGIYmC8gXxbcBkPsAkEFMiXUozkG2UY3k - oXJkaQ4prlL3SPF49vKd4heIRzHkvJjHIAXIrzWV4CALc08dIoBc7Oc5Hh1kW8UI50vj - cXEwweOpvEKKx69YXBWzHLQ/NoWAzKCA9PeZBHOQCMg2SpLD41AGj0GAx30ZZy/fRjxq - P9vFPwJlgIwFQM6aOt7Rhs5BYom19aKU4NHGcbynH+AxNvXQqVyCx8oaxKP4FaHlEUoA - +Ysu0il/8QgcZMa+xJiwIADk2FEIyNZLkZwpxOMkH/+gMMSjljNct7pXAshdsZEIyLYp - kTlbiMepsxCPuqUGEYxWCpCf3hNAFuRkpMkCskf39mRnl3sPj8dRYxk8JlL3+Igtrv7C - pTkiyHkxD0EekPegxHqQB6QFWcWKDrJ1/7RweLQA90jwGBm7C92jmNNffGPjAfmzsZ4D - 5PG0xE1hS/2n8w4SAdkaRXbvQeceh1pJ8JiWkVNwG/D4/lN940/Eo/jyX2wj4gAJ28/9 - +Pa1uvL1k3vXc08e3LUtctUiKLE62LCA7N6tNQnZtc9RgMeDJ3ML7z3B4qrY0l6842EA - +ef3v79+NtZRQN4qyCGADOUAOYg8KAAB2fK/NUI8TvdfGrYpMe14TsEtAR7ZHa3Emw04 - Mm1HQBaQrwCQ/7+9c3+oaev6+ME5HLdEKqko5VYpROVSoVCEKNcuRBclhVRUlFshVC7J - raTcKUohSipKN1QKx3OO4/1H3jHnWmvvtXflnEN7t9daY/3wPJ7zPNaec6wxns/8jjnm - HFcIIIM5QOqP0Bo4ANvP/WM89ulLK1f1jc0tQT2u9A3Ztf/omSs3CR4byN4jNpjrbV8X - xO9zgIQG5hSQzx5RQMZSQDqQPciR2oMRkP8Yjr8weBxJ1SPgMWB7LIPHZ6AeW6l6RDwK - IiJ6d5DdAHIfAeQiR1tQkPojhiIg/zEeYbNjwECtEQSPto6LVvoGc3h8gXjsXQ8X2K93 - AmTx3VxQkCwgbSaZGiAg/zEaf6F4HKxN8ejQFR5l13QIzD1wuGq2gBIgX7EKkgHkXFtL - M2N9aGCOCvL7MUnxOHS4vrGZpe1cisd9jHpEPKrZnwX/c10C8uTB2PCA1R7zHWwmmiAg - vx+L5L8l6hHwaGAy0YbiMTz24Kms3LvFnHpEPAo+TtQ1AR4gP8IeJACy8OaV0yn7dgb7 - eC5CQP5zLML/ogs8ppwmydUXrzC5qi5HFsvvdAPImPBNq5fyAYk1Ad3GJh+P8z1WBwAe - TyIexRIgap4HH5Bt7wCQjwtvXJYD0sLMCBVkt5FI/ws5Hi1APXr6BO/cB3i8UUjx2PYR - 9x7V7NEC/zlFQNZVPSu+k5t18qASIPHqx26DEkrlZOpx/tLVm8JjCB7voHoUeGD00vC7 - AWTCziAfz4VzbRGQ3QYi819weDQyAzwu9PQJIni8fKPwMajHd4jHXvJqAf8sD5DtrU11 - VWUsILcRBWlPU6zDBmPzgO7CkodHewU8VtU1t7Z/lrcIELCL4NDVaAFlQFYQBZmRwgBy - znQEZHeRSP85H49zKB4TEI9q9F7x/RQXj1+hipUBZNGd3PMnDsRs2+QNgLQme5AIyO6C - kuJxGN17pHjcFnPg5HlQj2VVdU0KeMQOOuILHdXMiAtIOAf5kaRYKx4XUEDuCNqwYiEA - chymWLuLRtneI6jH6YDHDUE7ElIyiHqsQPWoGm8V/1u5eOwMyI3eS+bZW08wgQbmqCC7 - jEk5Hq3t5y/x3gh4PAF4LEI8ij9uVDZDLiChPysHyOtEQcoBqQdVrP3xHGSnkAT12H/g - 0OF6RuMIHldweCxg8QgN5thzVrhaVZn3iu/FXDxSQLaQFGvRbUZBsoAci4DsFIr0HzB4 - 1DEwmWBtPw/xKL7Q6J0ZcQHJArIGFOT1Sxkp8QSQrlRBIiC7Csgu8XjpOuKxd9xYNL/K - xaMSIJNiwggg7awnICC7Ckfaf3XwMB2DsROs7eR4hPbkkFxt4e894nJVNLGilolwASkD - ZCkAMj0lPlIOSG1UkMoxyeBRm1GPrkQ9xqdkAB5LK2pIaQ6qR7X4rhh/hItHPiCvZqYq - AnIQFukoRiSnHjk8hsUkncjMRTyKMULUPCcuIBUBmQyAXL+cKkhDPQSkYjTSDjoDh3J4 - XL4hKDI+OR3xqGbPFefPcfHIAfIlpFgJIKPD/L3dne2mUAWJgFSISILHQTz1GBadlJp5 - FfEozghR86xoQH779jcF5NuGmvLSgvxL6QDIQDkg4W5k3IOUhSRVj0O09QzJ3qPr8vUy - PJajelSz84rw55QAWYuAlAVeN3+Q43GKnbO7t78Mjy9rMbkqwghR85Q6A/J+/sX05DgO - kKagIBGQ8tgkePydh8dAoh4v5t8vBTy+ZZOr36hR1fwh8edEYQEeID+1tzQxgDyXmhgd - yijI8WQPEhWkLCCV8RjKqUeKx0/yc4+49yiK+FD7JDoBsoQA8khcBChIFyjSMTXURUDK - w5HDoymoR5fl6wMj4xCPavdZMf+gIiAbKSBzzh0ngPRyd545ZfwYBKQsHGlpDk2ujp8y - k6jH0OjE1HMkufqytrGlHfEo5khR09xYQH6FFGtH29v6mnIZINctc5k9bTICkheODB51 - DQGPswkeI+KOEPVYUl5Tj+pRTQ4r8p/hA/JDixyQu0P9vNycCCBH6WihgqRBSdWjlo7B - GIpHL//Q3YnHz+UgHkUeIuqdnhIgq2WA3IKAlKOR/IlNrgIeJ0+b7bJsnRyP1YDHDqhc - /foNk6vq9V7x/ZoyICvLHt4mCnL3VhkgR2gNGoB3sTLqUWvEKIJHJzcvPwU8Qv9VWccO - TK6KL0zUN6MuAJl3If3I3ggEpAIflfG4JWIvqx4Rj+rzVvH/UidAPn14K+esDJBWoCAR - kGS52o+2Jwc8WlE8bmXU48OnlZBcRTyKP1DUNUNlQD4vuQeAPAyAXMukWEfjHmRn9Ujx - eCEPkquIR3V5qjR+RwGQ7xtrKykgjxEFucrNaQYCki5bu8Lj2ZxbFI/vEY/SCBX1zLJL - QKZRQHq4zII9SASkLLk6mkmurgU8Hk67kHev5DniUT1eKp1fUQLkawLI7LPHEqMAkIsB - kOaoIOXq0dxqhpPbKr+tUYnHzmYTPL5uRDxKJ1bUMtNOgHwECjLt8J6IzWsBkFMnISC5 - 5CrB4ywXj7WbEY9q8Uxp/ki3gAwBQDoiIHnJVcCj42LEozTjRG2zlgHyC1SxNtdXP390 - 71pWZ0D266uwIyed/yDH46SpDB73UPX4iFWPX7A0R22+KoUf6gzIB0RB7o/iAGks7T1I - WXKVxWNI1H5Uj1IIjN6aoxyQnwGQbxhAnjq0Z/vmNR4L5ApSqoDs249cC6A72lSGx0Np - WdfuAR7fNLd1fEY89pbfivV3OUBC+7lPH943vK588uBm9pmjAEhfoiAtzVlA9u0jnUWq - fKYcHo3leDx6JvvWgyeYXBVrQPT2vBhA/v31ry+fO1opIO9eyyKADOAAOZJcFCBNQPLx - uMBjzebtew6dUsQj29Gqt78i/r5YLKAMyBcAyCsAyF0hvisZQOqP0Bo4QJJXP/bpSytX - 9Y3NLSG5utI3ZNd+wONNgscGsveIDebEEgUaNA8OkNDAnALy2SMKyFg+IAdLE5AMHkdS - 9Qh4DGDwePfRM1CPrVQ9Ih41yJPFMZRuALlvV7DvykWOtqAgpQpI2OwYMFBrBMGjLcFj - MMHjFcDjC8SjOHxfI2fRCZDFPEA62EwyNRipLUlAEjwO1qZ4dKB4jCXqUY5H2Tlkjfys - OCiBWkAJkK9YBckAcq6tpZmxPjQwl56CpHgcCng0s7Sdu4jgcR/iUaA+LqhhdwHI3KyT - B2PDA1Z7zHewmWgiTUCyeDQwmWjD4vHgqazcu8WcekQ8CsrLhTNYHiA/wh4kALLw5pXT - Kft2Bvt4LpIsIBk8DufjMeU0VY+vMLkqHOcW4ki7BeSm1Uv5gJRUTQAfj/M9VgeExx48 - iXgUonsLbsx8QLa9A0A+LrxxWQ5ICykqSDkeLUA9evoE79xH8Fj45AXB40fcexSclwto - wIqArKt6VnyHKMiYcAVASurqxz5McpWqx/lLV28Kj0E8CsijhT3UbgCZsDPIx3PhXFsL - MyOppVg5PBqZAR4XevoEETxevlH4GPD4rg3xKGx/1/jR8wDZ3tpUV1XGAnIbAaQ9TbEO - G/y7hAAJleRk75Hg0V6OxzvFz6rqmlvbP8vvQNb4T4sDFKAFlAFZwShIBpDQfk5qgOTj - cQ7FYwLiUYB+LdQhc/H4FapYGUAW3ck9f+JAjEQBSfE4TI7HbTEHILl6p7isqq5JAY/Y - IkCoLq/Z4+YCEs5BfiQpVgrIjJSEHUEbViyUHCB5eJwOeNwQtDMhJYOoxwpUj5rtx2IZ - HRePnQG50XvJPHtrUqQjHQUpx6O1/fwl3psAjyfO594pQjyKxd81fh5cQEJ/VhaQBdcv - 8wA5zkgPqlj7S+IcJOCx/8Chw/WMxkF78oUrNgTtoHgsYPEIDebYc1a4WtV4vxbqALl4 - pIBsISnWotuMgmQAOcEEGphLJMXK4FHHwGSCtf28Jd4bEY9C9WoBj5sLSBaQNRWPC65f - ykiJ5xSkdADZNR6vIx4F7N3CGzoXj50AGUYAaWc9YaxUAMnhcewEazs5HqE9OSRXW/h7 - j7hcFZ6bC2fEXEDKAFkKgExnAOkKKVYApLYUFCSDR21GPboS9RifknGJ4LGGlOagehSO - Swt6pFw8KgAyMzUphg/IQeIv0lHGY1hM0onMXMSjoJ1biIPnAlIRkMnxkUHrl1NAGkoB - kJ3wGBmfnA54LEU8CtGpBTxmLh45QL6EFOtVAGR0mL/3EmdWQYoekASPg4bpGHDqEfCY - mnkV8Shgxxbq0GlAfvv2NwfI8tKC/EvpioAcIvI9SIrHIdp6hmTv0XX5+iDEo1DdWfDj - VgJkLR+Q7s52U2iKVeSAlONxip2zu7d/WDSLx5eYXBW8gwttAgqAfNtQU156P/9ienJc - ZCCjIE1BQULzABEX6RA8QgcdGR4DCR4v5heUltc0vGWTq9+omYT2bXG8wrMAD5Cf2lua - OEAmRof6exNAjid7kKIGZPd4rIW9x0/yc4+49yg89xbeiDsBsoQBZAQA0gX2IMUOSBke - TUE9uixfHxgZR/B4H/EoPF8Ww4gVAdnIAPLccQJIL3fnmVPGjxE3IGV4HD9lJlGPodGJ - qedIcvUl4lEM/i24ObCA/EpTrG/ra8opII/ERQSuW+Yye9pkU0NdEStIFo+6hoDH2QSP - EXFHCB5LymvqUT0KzplFMGA+ID+0MIDMAUDuDvVjATlKR0u0CpLiUUvHYAzFo5d/6O7E - 4+dyKB4bUT2KwL2FNwUeIDva3tZXywC5RfyAlONx8rTZLsvWKeKxAypXv37D5KrwfFrI - I+4MyIe3KSC3+nm5OREFOWqEWAHJ4HHEKIJHJzcvPwU8Qv9VWccOTK4K2cWFNfYuAJl3 - Mf3I3gjRA1IZj1si9rLqsRrUI+JRWH4sltEqA7LyqQIgrRhADhDhXayAxwGDtAgerSge - tzLq8eHTytrGFsSjWBxcaPNQBuTzknt5F/iAHC3OFGuXeLyQB8lVxKPQfFhM41UA5PvG - WgDkrZyzkGLd6rcKFKRoAdkVHs/m3EI8ism5hTiXLgGZdhgU5FoPugcpSkByeBxtSpOr - a0E9Hk6/kHev5DniUYheLJ4xKwHyNQFk9tljiVEAyMVOM6zMaYpVbAqSh8cZTm6r/LZG - JR47m03w+LrxPapH8bi38GbSCZCPQEESQG4GQM6aNslUhIDk43GWi8fazYDHNMSj8JxX - hCPuFpAhAEhHcQJShkdzqxmOixGPInRr4U5JBsgvf3S0NddXPwdAZqUd3sMAcqockL+I - 5ZHjcdJUBo97KB4fserxC5bmCNedBT/ybgC5P4oDpDEp0hGTglTGY0jUflSPgvdj0UxA - DsjPAMg3BJDXstIO7dkOCnLBLBkg+/UVCx/7QnvyIdq6o01leDyUlnXtHuDxTTOU5iAe - RePagpyIDJD/+/Lpw/vG15VPHtzMPnO0EyD79hFHQHJ4NGbVI+Dx6JnsWw8wuSpI9xXf - oBlA/v31ry+fO1opIO9eyzpFALmGBeRIcg5SLIDk43GBx5rN2/ccOiXH42fEo/g8XFgz - 4gAJ/VkBkA0UkFcAkLtCfFdCitXS3FifKEiR3GzVpy9TuWpsbgnJ1ZW+IbsIHm8+eFL5 - uoHsPWKDOWF5rwhHywESGphTQD57RAEZuz1AhIBk8DiSqkfAYwCDx7tUPbZ2EDyyDR9F - +KFxSoKwgDIgX4CCBEDu2xXsu3KRoy0DyIHiACRsdgwYqDVCXwGPVwCPLxCPgnBWKQyy - EyCLeYB0sJlkajBSe7A4FCTB42BtikcHisdYoh7vPnoGyVWCR9k5ZCl8d5yjZlrgu4Cc - a2tpZqwPDczFAEiKx6EUj7aOi1b6Bu/ad/QM4lEz3VK6o+oCkLlZJw/GhoOCnO9gM9FE - LIBk8WhgOslGjsfcu8WIR+k6vwbOXAmQr6iCPJ2yb2ewz8pFIgIkg8fh+sZmlrZzFfD4 - CpOrGuiXkh1S94BcvZQPSIHXBHB4NJlo4zDfY3VAeOzBk1mIR8m6vcZOnAfIj23vG169 - eFx44woDSE8ApIU4FKQiHj19gnfuSzl95WbhkxcEjx9x71Fj/VNyA1MEZF31s+I7REHG - hG/iA1LgN1v1YZKrBhSPS1dvCo9BPErO04UxYQVAvmMAefl0SsLOIB/PhQSQRsJPsXJ4 - NDKzAPXI4vHyjcLHgMd3bYhHYXiqREbJA2R7a1NdVRkfkPZcilXQgIRKcrL3qITHO8XP - qupw71Eibi6YaSoDsgIUpAyQ0H5O+IBUwONCT5+gnQkppxGPgvFQaQ2Ui8evUMUqA+T5 - EwdithEFyQBy2ODfBQxIisdhFI/280E9bqPq8U5xWVVdU2s7luZIy981frZcQMIxj49t - oCApIDNSEnYEbfBcKAJA8vA4fQ6LxwyCxwpUjxrvnBIcIBePckAW3cmlgNzovWSevTUp - 0hEyIOV4tAY8egMeD5w4n3unqBMesYOOBL1fA6fMBSTtz0oBWXD9MgPIFQSQ44z0oIq1 - v0DPQcrwOA7aky9csSFoR0IK4lED3RCHxFqAi0ceIG/zATnBBBqYC1ZByvA4wdp+3hLv - jYhHdHwNtwAXkHxAXspIiQcFKXhAAh77Dxw6XM9IAY/XC1j1CP1X2WPIuFrVcC+VzvC4 - eKSAbCF7kEU8QNpZTxgrXEAyeNQxGKuAR2hPDsnVFn5yFeNROg6v6TPlApIFZE1FacF1 - DpCujILUFqaCVMCjK1GP8SkZlwgea0hpDuJR011TkuPj4lEBkJknkmLCSIpVyIDk4dGO - qMewmCRIriIeJenmwpk0F5AKgExPjo8MWr9cyIBk8KjNqEcWj+mAx1LEo3CcU4Ij5eKR - A+RLUJBXM1OTosP85YAcJLwinS7wmJqJeJSghwtsylxAcoAsLy3Iv8QHpKGe9hDB7UFy - eDQkyVXX5euDIuOTEY8Cc01JDpeLRxaQtXxAujvbTaEpVsEBkuBx0DCaXLVzdvf2D4tO - Ss28CurxJSZXJenmwpk0Dchv3/6mgHzbUFNeej//YnpyXGQgqyAJIH8XVpEOxeMQbT1F - POYXlJbXNLxlk6vf6MSF851wpNKwAA+Qn9pbmuSADPX3JoAcT/YgBQZIOR6nKOGxFvce - peHWwp1ld4CMAEC6wB6kqeAASfAIDeb0DE0Z9RgYGZecfjH/PuJRuF4qnZErArKRAeS5 - 1MRoCsiZAgSkDI/jGTyGRiey6pHg8ZP8SnIszZGOmwtnpoqArK8pLyEK8kgcBeRsAkhd - QSlIBTy6LF8fGMHgsQTVo3CcUsIj7QqQOeeOJ+4O9fdydwZAjjHQ0RKQguThcaazu5c/ - 4PH4OZpcrW1EPErY0YUydRaQXyHF2tH2tr5aDsh1y1xmT5ssLECyeNQ1NJ08bbbLsnWA - xyNEPQIe65nk6tdvmFwVim9KcZx8QH5oYRQkA0g/LzcnAshR0J9VKEU6FI9aOqPGjJ9C - 8OgXuhvwmEP2HgGP0H9V1tAK1aMUnV0Ic+4GkHsjtggPkMp43CLDYzXgsQMOdiAeheCT - Uh6jMiArnz68TQG5lQLSigHkAEFcNcfgcQTFo5Obl99WBo8PyyoRj1L2cUHNXRmQz0vu - 511IPyJAQHbG415Qj3mgHhGPgnJJSQ9WAZDvG2sBkLdyzkKKVXCABDwOGKRF8Gg1k4/H - p4hHSXu4wCbfGZD38i6kHQZArmVSrKOFsQfZBR4Pp1/Iu1fyHPEoMJeU9HCVAPmaADL7 - 7LHEqK1+q9ycZliZ0xSr5itIRTyuIurx2NmcWw8JHt9jclXSPi6oyXcLyM1rPVxmwR6k - IADJ4XE03Xv0WLslYu/hNMSjoDwRB0ss8D1ALnYUCiBleDS3muHkBniMAjxmEzy+Rjyi - owvJAjJAfmGKdJ4/ogpyTwQF5NRJQgAkH4+zXDzWbmbx+AjVo5BcEccKFugGkPujQvxW - CQWQfDw6Ll7lF4J4RN8WqgXkgPzc0db8phoAeS0r7ZAyIPv1/UVjH+bco+5o00lTGTzu - OZyWde0ewWMzlOZ8wdIcoTqnBMfdCZBPHtzKPnNUDkhjUsWqySlWDo/GoB4ZPO5H9ShB - TxbJlBlA/v31ry88QJ46tGf75jUeC2bJFKTmArJvP3ItgByP2/ccYvH4BvD4GfEoEkeV - yDQ4QEJ/1k8f3je8rnzy4CYB5K4Q35WgIC3NWUD27aOZC9Y+fZnSHBaPviFR+4+eyb75 - 4AmbXMUOOhJxZLFMkw/IVlCQzx7dvZZFABnAAXIkuShAUwHJx+MCjzWbAY+nsq7dBfXI - 4ZHtaCWW74XzELcFlAH5AgB5hQAymADSFgCpP0Jr4AAN7c8Kmx2kclXf2NwS1ONK35Bd - gMcrFI8NpDQH8Shu7xXh7DhA/gkKkgfIWApIB6IgR2oP1lRAMngcSZOrgMeA7bEMHp8B - HltBPcrOIYvww+GURGmBbgC5jwBy0VwGkEM1FJAEjwMZPNo6LlrpG8zh8cVrxKMovVUC - k+oEyOK7uVmnDrKAtJlkYqCxgCR4HKxN8eiAeJSAr0phikqAfMUoyBQZIM2M9YdrJiAp - HocO1zc2s7SdS/G4j1GPiEcpOK5Y59glIE8ejA0PWO0x38FmosYCksWjgclEG4rH8NiD - p7Jy7xajehSrq0piXjxAfoQ9SABk4c0rp1P27Qz28SQKUlMB2QUeU06T5OqLV6geJeG5 - Ip1kN4CMCd+0eikfkBpWE8DH4/ylqwMAjycRjyL1USlNiw/ItncAyMeFNy7LAWlhZqSJ - ClKORwtQj54+wTv3AR5vFD4meGz7iHuPUnJhcc2VB8j21ua6qmfFd3KzTh5kAGnPKUgN - u/oRKslJcpWqR8DjpvAYgsc7qB7F5ZtSnE03gEzYGeTjuXCOrUYCksOjkRngcaGnTxDB - 42UGj+8Qj1J0Y9HMmYtH2sC8tamuqowF5DaiIBlADhusWc0DeHi0V8BjVV1zazuW5ojG - OaU4ES4g4ZjHR6IgK4iCzEhhATldAwHJx+MciscExKMUXVeUc+biUQ7Ioju5508ciNm2 - yRsAaU32IDULkBSPw6h6pHjcFnPg5HlQj2VVdU0KeMQOOqL0WJFPigtIaD/HArKAAnJH - 0IYVC6GB+TgNS7Hy8Dgd8LghaEdCSgZRjxWvGlA9itxZJTA9Lh47A3Kj95J59tYTNAyQ - cjxa289f4r0R8HgC8FiEeJSAs0philxA8gB5nShIOSD1oIq1v4acgwQ89h84dLie0TgL - wOMKDo8FLB6hwRx7DBlXq1JwXhHOkYtHCsgWkmItus0oSBaQYw10NEdBMnjUMTCZYG0/ - D/EoQn+U/JS4gGQBWVPxuOD6pYyUeAJIV6ogNQeQXeLx0nXEo+S9WDwG4OJRCZBJMWEE - kHbWEzQIkBwex06wtpPjEdqTQ3K1hb/3iMtV8Tio1GbCBaQMkKUAyPSU+Eg5ILU1Q0Ey - eNRm1KMrUY/xKRmAx9KKGpJcRfUoNdcV5Xy5eFQAZGaqBgJSGY9hMUknMnMRj6J0S+lO - igtIRUAmAyDXL6cK0lBPIwDZCY+R8cnpiEfpOq5IZ87FIwfIl5BivQqAjA7z93Z3ZhXk - oN6vYiV4HDRMx4BTj4DH1MyriEeRuqV0p0UD8tu3vykg3zbUlJcW5F9KVwTkkF7fg6R4 - HKKtZ0j2Hl2Xrw/i8FiO6lG6vivGmSsBslYJkFNoirXXASnH4xQ7Z3dv/7BoFo8vazG5 - Kka3lO6cOgPyfv7F9OS4yEBGQZqCgoTmAb1apEPwCB10ZHgMJHi8mF9QCnh8yyZXv9GJ - SPc74szFYQEeID+1tzQxgDyXmhgdShXklPFkD7KXAfl9PH6SX0mOe4/icEopz6ITIEsY - QEYAIF2gSKf3ASnDoymoR5fl6wMj4wge7yMepey3Yp27IiAbWUAeJ4D0cneeqQGAlOFx - PKMeQ6MTU8+R5OrL2saWdsSjWD1TovNiAfmVSbHW15RTQB6Jiwhct8xl9rTJpoa6vaog - O+ExIu4IwWNJeU09qkeJOq2Ip80H5IcWBpA5544n7g71YwA5ZpSOVi8qSIpHLR2DMeOn - zHR29/IP3Z14/FwO4lHELintqfEA2dH2tr5aBsgtmgBIFo+6hqaTp812WbYuUAGPHVC5 - +vUbJlel7cHimr0yICvLHt7mAOnmBApyzKgRvQdIBo8jRhE8Orl5+SngEfqvyvo9YnJV - XG4p3dl0Aci8i+lH9kZoACCV8bglYi+rHqtBPSIepeu14p15J0A+ZQG51c8LAGnFAHJA - r1xWDngk7ckBj1YUj1sZ9fjwaSUkVxGP4nVKKc9MGZDPS+7lXUg/rAGA7BKPF/IguYp4 - lLLHinvuCoB831hb+fThrZyzxxJ3b/Vb1buA7AqPZ3NuIR7F7ZBSn12XgEwjgFzL7EGO - 7p09SA6Po5nk6lpQj4fTL+TdK3mOeJS6z4p5/kqAfE0AmQ2AjKKAnGFlTlOs6leQinhc - 5Qfq8RiDx9eN71E9itklpT23bgG5ea2Hyywo0ukVQPLxOMvFg+IxDfEobVeVxOy/B8jF - jr0FSBkeza1mOC0GPEYBHrOJekQ8SsItpTtJGSC//NHR1lxf/fwRpFjTDu+JoICcOqk3 - ACnH46RpBI+bI/YcJnh8xKrHL1iaI12HFfnMuwHk/qgQv1UUkMakSEe9CpKPR0fAYwji - UeReiNOTWUAOyM8AyDcEkNey0g4pA7Jf31/U9jDXAuiONp00VYbHrGsUj81QmoN4lH08 - /IPoLNAJkE8e3Mw+c7QXAcnh0RjUI4PH/ageRed3OKFuLMAA8u+vf33hAHn3WtapQ3u2 - b17jsWCWTEGqD5B9+5Fbcxg8LgD1uH3PoTQGj28Aj58Rj918SPzHorAAB0hoYP7pw/uG - 15UsIHeF+K4EBWlpzirIvn3Us2Dt05epXGXx6BsStf/omeybD55Uvm4ge4/YYE4UboeT - 6M4CHCD/BEC2goJ89ogCMnZ7AAfIkeSiAHUBksHjSKoeF3isIXg8lXXtLiRX3zS3Ujyy - DR+7mw/+c7SAkC2gDMgXAMgroCB3BRNA2gIg9UdoDRygpqsfYbODHOzQNza3BPW40jdk - F+DxCuJRyB6GY/9PFvguIB2IghypPVhdgFTCY8D2WAaPz1g8ys4h/6cp4v8YLSAYC3QD - yH0EkIvmMoAcqiZAEjwOZPBo67hopW/wrn0MHl+gehSMQ+FAf84CnQBZfDc369TB2HCi - IB1sJpkYqA2QBI+DtUcawN6jA6hHDo/FiMef+8T4twVkASVAvqIK8nSKDJBmxvrD1QNI - isehw/WNzSxt5yIeBeRDONQetECXgDxJALnaY76DzUS1AZLDo8lEG4f5gMfw2IOnsnLv - Ih578GPjqzTeAjxAfoQ9SABk4c0rAMidwT6eREGqC5BKePQB9ZhymiRXX7zCvUeN9yIc - YI9ZoBtAxoRvWr2UD0gV1wQo4HHpaoLHk4jHHvvK+CKhWIAPyLZ3AMjHhTcuywFpYWak - DgUpx6MFqEdPn+CdBI83Ch8TPLZ9xNIcobgTjvNnLcADZHtrc13Vs+I7uVknDzKAtOcU - pIqvfoRKcppcpepx6epN4TEEj3dQPf7s18W/LzQLdAPIhJ1BPp4L59qqBZAcHo3MAI8L - PX2CCB4vM3h8h3gUmkvheH/CAlw8foUq1vbWprqqMhaQ24iCZAA5bPDvKgUkD4/28/l4 - rKprbm3/LG8R8BPzxL+KFhCEBbiAhGMeH4mCrCAKMiOFAST0Z1W9guTjcQ7FYwLiURC+ - g4PseQtw8SgHZNGd3PMnDsRs2+QNgLQme5CqBSTF47CRBqAeKR63xRw4eR7UY1lVXZMC - HrGDTs9/fnyjplmAC0g5IAsoIHcEbVixEAA5TsUpVh4epwMeNwTtSEjJIOqx4lUDqkdN - 8xYcj6otwMVjZ0Bu9F4yz956gooBKcejtf38Jd6bAI8nAI9FiEdVf3l8v0ZagAtI2sCc - KsiC60RBygGpB1Ws/VV0DlKGx3EWgMcVHB4LWDxC/1X2GDKuVjXSe3BQPW0BLh4pIFtI - irXoNqMgZYDUUZ2CZPCoY2Aywdp+3hLvjYjHnv6++D6BWYALSBaQNRWPC65fykiJJ4B0 - pQpSdYAEPPYfOHS4npECHq8jHgXmQzjcnrMAF49KgEyKCSOAtLOeMNZAZYDk8DhWAY+3 - qXps4e894nK15z44vkmzLcAFpAyQpQDIdAVAaqtGQTJ41Gbw6ErUY3xKxiWCxxqSXEX1 - qNmOg6NTiQW4eFQAZGaqGgDJw6MdUY9hMUknMnMRjyr5zPhSoViAC0hFQCbHRwatX04V - pKGeSgDZCY+R8cnpgMdSxKNQXAfHqQILcPHIAfIlpFivAiCjw/y93Z1ZBTmo56tYu8Bj - auZVxKMKPjG+UkgWoAH57dvfFJBvG2rKSwvyL6UrAnJIj+9Bcng0JMlV1+Xrgzg8lqN6 - FJL34Fh72gJKgKxVAuQUmmLtcUASPA4apmMwdsIUO2d3b/+w6CQGjy/rmjC52tPfGN8n - IAt0BuT9/IvpyXGRgYyCNAUFCc0DerRIh+AROujocXgMpHjMLygFPL5lk6vf6MAEZEgc - KlqgByzAA+Sn9pYmOSBDqYKcMp7sQfYwILvHYy3g8ZP83CPuPfbAF8ZXCMoC3wOkCxTp - 9DwgZXg0ZdRjYGRccvrF/PuIR0E5Dg5WJRZQBGQjA8hzqYnRFJAzVQBIGR7HM+oxNDox - 9RxJrr6sbUQ8quQj40uFYwFFQNbXlJcQBXkkLgIUpMtsAkjdHlWQCnh0Wb4+MILBYwmq - R+E4DY5UZRbgA/JDCwPInHPHE3eH+nu5OwMgxxjoaPWgguThcaazu5c/4PH4uRzEo8o+ - ML5YWBZgAfkV9iA72t7WV8sBuW6Zy+xpk3sWkCwedQ1NJ0+f7bJsHeDxCFGPgMd6Jrn6 - 9RsmV4XlQTjanrRA94D083JzIoAcNaLnAEnxqKUzasz4KQSPfqG7eXiE9uSyfo+YXO3J - j4zvEo4FugHk3ogtPQ9IHh6nETxukeGxGvDYAQc7EI/C8RwcqSosoAzIyqcPb1MFuZUC - 0ooB5IAeuYuVweMIikcnNxkeH9LkKuJRFZ8X3yk0CygD8nnJ/bwL6UdUAMjOeNwL6jEP - 1CPiUWheg+NVlQW6AOStnLOQYu1xQAIeBwzSIni0mknwuJVRjw+fVsLeI+JRVR8Y3yss - C3QG5L28C2mHAZBrmRTr6J7Zg+wSjxfy7pU8RzwKy2NwtKq0gAIg3ze+BgV5K/vsscSo - rX6r3Jxm9JiC7AqPZ3NuUTy+Rzyq8hPju4Vkge8A0sNlFuxB9gggOTyONp1Mkqtrt0Ts - PZyGeBSSo+BY1WKB7wFyMQDSnO5B/myKlYfHGU5uq/y2RiUeO5tN8Pi6EfGolg+NPyIM - C8gA+YUp0nn+iCrIPRGb1xJATuoJQPLxOMvFY+1mxKMwnANHqXYLdAPI/VEhfqsWO/YM - IGV4NLea4bgY8aj2j4w/KBwLKACyub4aAHktK+0wC8ipckD+8qOPHI+TpjJ43EPV4yM2 - ufoFS3OE4y44UhVboBMgnzwgKVY5II1JFevPKEhlPIZE7Uf1qOKviq8XrAXkgPzc0db8 - hgHkqUN7tm9eAwpSBsh+fX+Uj8ytObqjTXl4zLp2D/D4prmt4zPiUbCugwNXgQU4QEJ/ - 1k8f3je8rnzy4Gb2maMASF9GQbKA7NvnxwKSw6Mxqx4JHs9k33rwBJOrKvia+ErBW4AB - 5N9f//rCAfLutSwCyIA1Hgt+HpB9+5FL5Rg8LvBYs3n7nkOnEI+C9xqcgKos0BUgrwAg - d4X4roQUq6W5sT5RkD949WOfvkzlqrG5JUmu+gIej57Jvknw2ED2HrH/qqq+K75XoBbg - APknALIVFOSzRxSQsXJAjiQ36fyYgmTwOJKqR8BjAIPHu1Q9tlL1yPZDFqjxcNhogR62 - gDIgX4CCpIAM9l25yNGWAeTAHwMkbHaQgx36DB5X+obsAjxeQTz28CfE14nJAp0AWcwD - pANJsY7UHvxjgOyEx1iiHu8+egbJVYJH2TUdYrInzgUt8DMW6AaQ+3YRQM61tTQjCvKH - AEnwOJDBo63jopW+wRweX6B6/Jkvhn9X1BboApC5WacOxoaTFKuDzSQTgx8EJMHjYG2q - Hh2oemTwWIx4FLU/4eR+zgI8QH6EPchXVEGeTuEDcvjQHwCkDI9mlrZzKR73MeoR8fhz - Hwz/trgt0CUgTxJArvaY72Az8QcByeLRwGSiDcVjeOzBU1m5dxGP4vYmnN3PWoAPyDYK - yMIbVwCQO4N9PFkF+QOApHgcOlzfmMGjT/CufSmnSXL1xSvYe/yIe48/+9nw74vVAp0B - eSc36+TBmPBNq5fyAfmfiub4eJzvsToA8HgS8ShWF8J59aAFFAD5DhTk48Ibl+WAtIAU - 638GpCIePX2CdxI83iikeGxDPPbg58NXic0CPEC2tzbXVT0r7gqQ/+lu5D5McpWqx/lL - V28KjyF4vIPqUWy+g/PpeQt0A8iEnUE+ngvn2lqYGf1XQMrxaAHJVRaPl28UPgb1+A7x - 2POfEN8oIgtw8fgVqljbW5vqqspYQG4jCtKepliHDf79PwASDlqRvcfOeKyqa25tx9Ic - ETkPTqXnLcAFJJyD/NgGCrKCKMiMFAaQ0MD8vwKSw6ORGeBxoadP0M6ElNOIx57/cPhG - UVqAi0c5IIvu5J4/cSDmBwFJ8TiM4tGeqMdtMQdOngf1WFZV16SAR2wwJ0p/wkn9pAW4 - gFQG5I6gDZ4L/zMgeXicPofFYwbBYwWqx5/8UPjXJWEBLh67AKT30nn21qRI598ryC7w - eALwWIR4lIQz4SR/3gJcQEIDc1ZBFlwnChIAuYIActx/SLEq4XFD0I6EFMTjz38jfIN0 - LMDFIw+QtxkFudF7CQBygomBzr8FpByP1vbzlnoT9Yh4lI4r4Ux7wgJcQLKArKl4XHD9 - kgIg9aBIp/+/uElHhsdxFqAeV7B4vF7AqkdoT87e0oHJnJ74cPgOUVqAi0cKyBayB1n0 - g4Bk8KhjYDIB8LjEeyODx9uoHkXpNzgpFVmAC0gZIEspIOOJgnSlClJP+98AEvDYf+DQ - 4XpGMjzGp2RcInisIaU5iEcVfT98rbgswMWjAiAzYQ8yjChIO+sJY/+dgvweHlv4pTm4 - XBWXA+FsetYCXED+HCAZPGozeHQl6pHBYynisWc/F75N5Bbg4pEPyKuZJ5L+GyA5PI6d - YG1H1GMYJFczcxn1iHgUuQvh9HrSAjQgv337WwGQ6cnxkUHrl1MFafjPCrIrPKaDekQ8 - 9uSXwndJwQJKgKx9CSnWq5mpSdFh/nIFOej7xzwIHgcN0zGQ4zHpROZVxKMU/Afn2MMW - UADk24aacpJiJYAM/LeApHgcoq1nSJKrrsvXB0XGJyvj8Rv9mR4eOr4OLSA6C/AA+am9 - pUkBkO7OdlNoivW7gJTjcYqds7u3f1h0UirF48vaJlSPonMYnJBqLdAZkPfzL6Ynx3GA - NAUFCd11ui3SIXiEBnN6hqYMHgMj4wCP+QWl5TUNb9m9R8Sjar8hvl08FugGkInRof7e - BJDjx8Ae5HcASfGopWMwZjyDx9DoRB4eP8k7duDeo3icBmeiOgt0DcgjcRGB65a7zJ42 - 2dRQlwFk1/2S2fbkhqaTp812Wb4uMCLuSPrF/PuIR9V9MXyzmC2gCMhGRkGeO564O9TP - y81pptX4MaNIf9ZubtLh+q+OGW8108nNyy90d+LxcyS5StUj4lHMnoNzU4kFFAFZX1Ne - QhTkkb0RW9Yto4AcTQHZdX9Wcskj2558tsuydVsi9lI8lpTX1KN6VMnnwpeK3AJ8QH5o - IYB8eDuHAHKr3yo3xxlW5gSQ3XTXgWwO12COtCf32wp4PJtz+yHgsbGlHfEoctfB6anC - Aiwgv0KRTkfb2/rq8pJ7eRfSDu+N2LzWY8Esrj9rlwtWWirHXvK4wGPt5og9h9Mu5N0r - eV6NeFTFp8J3SsACyoCsfPrwVvbZY/ujQmT9WZnmAZ0zOtxBK3LJIzSYg/bkx85m33r4 - tBLw+AHxKAHnwSn2vAWUAfn80b1rWacO7dkesIa9G7mbLQ+yXB0Emx1QKgfXdECLALY9 - OcVjB5x7/PoN9x57/nvhG8VtAQVAvm98Xfnkwc0rZ46S9nPMzVZMTUC/Tt2uyHIVsjlM - LQActKIddEiDOaY9+Z9f8ZoOcXsOzk4lFlAAZPOb6mfFd2n7uW0boSZgJtQE0C2PX/sq - L1iZ5eooY3Oy2QGlcswtVrSDThviUSWfCl8qAQsoApJtP5eRAlXlsOXRfUYHNh/hZAfT - sgOyOVsiSKkcc4vVe1SPEvAbnKKKLMAHJGk/xxy7olsei+faWpoZwU1zv/dXXrAyy1Xm - ZMdCT9+QKKgFyGFvser4/AXVo4q+Fr5W7BbgAxK668CxK1ITcBgyOqvJXeXklAfU6Cgv - WKEYYODQEaOgdHUmnOwg2Ry62QGV5KTBHKpHsXsNzk9lFpABEtrPwbEruuVBMjpBG5gi - VqjRge5zfRUzOiS7CgeRTSZNneXisS4Q7iQ/fQWyOZWvoRYA8aiyb4UvFr8FZIAk7eeg - JoDJ6MBNc36rFjvSBSsUlSuXBIB8HAzZVXrLo6cv1OakwrU5xWXVb5rxkkfxuwzOUJUW - YAD5N9xs9enDe9IOktwTAEWsZMFKjiWTmjklAUlqV4cO14fs6gwnd++NdLnKnOx4R7M5 - uPeoyg+G7xa1BThAkqI56JdMLtLJgRqdnUHrmQwrNLtSFpBEPmqNoMUA8z3WbImMp8tV - WpvT/hlbBIjaXXByqraAHJB0wfr8EWxBnjgQvdVv5SJyVTmcgiQCkr8D2YfIx5EGzMnH - DcG72JNWVWS5Ks/mqHrc+H60gBgtIAPkl8/sgpVmWMOhJMAJDnkY6w8HAakQj31/lcnH - RSv9QqEhcta1e3DSqoEuV7E0R4xegnNSmwU4QNIFK8mw3rxyGkoCtpAaVtjxGDUCWnko - 7EBCOgcuzqHy0Q3k454jUAxQ+PgFza7KlqtqGz7+EFpAVBZgAQkZHViwvqkmJQFwCnIX - KyChGSQcglSOx6HDye6jHdSSb44g8hGOdsDFAK1QK4eV5KJyDpyM+i3AAvIvyLC+a6h+ - XgKHPE6CgPT1hJvKJ5uOpgkd3gYkm84xmWjjsMBjXdDO/cfoRR3Vb+BiAJCPeLBD/V8Q - f1FMFuDi8X+f25kdj/yLaYdiyQ7kXFs2ocOv0IF4JGetTCeRi6w2BO9OhI7Idx/BUat3 - bZ++cA1YxWQfnAtaQK0WYALyKwhIUqLz5MGNyxnJe7dv9HajCR1yD6tiPJL06mjTydAS - GaoBYg6eysqj98q9/0B2O+jL1Dp8/DG0gKgswMYjCEioKYdrdG5ln0mJh4oA6AUJZ66U - E6yw3cFW58DVAH5hsYfgnscCLp3zFeNRVK6Bk+kNC5CA/PY3P6FzbN+OLWs9SIIVzkAO - Vdjw6EO2O/QM4aoOx8Ve/ttIevVGIRSvknQOKx97Yw74m2gBsViAiUdI6DAlrHdyM0mC - dZ3HAgebiWMNYMPjt37yggCIR9juMDK3pNVy2+OSSTE5VOdgPIrFHXAevWwBumD9+y+o - CCAJVqjQOX8iMYq/4dFfOR5J9So9bAXbHWfgJquyl3W0OoepBujl6eDPowWEbQESkNCc - lVTowL3IZMMjaXcwPXI1yZRsQPLjkZQDQDX5eCs75yWrAyISSDwWlVXx4lHYtsDRowV6 - 2wJ0wfqVxuOripL7eVmnDkSH+KxwnQN9PAxGag3iF+hw8QjlAEugHCDhKFyEDPHIbD9S - Pvb2bPD30QICtwAE5DeIR7oBWXo/78Kpg7x4HNZdPJLyHIV4pNuPAjcFDh8t0OsWYOLx - D148xmwlfGQLdLrhI8Zjr384HIAoLfBj8YjrVVE6A06q1y3wnfUqKWBV4CPsdyjlc+jd - cvL8aq/PBgeAFhC2Bdh4pCcgO+dzFA5c0f3H7+53CNsUOHq0QG9bAMLx/779y/0O5XoA - clsHd9wK63N6+0vi74vBAiQe2XqAGubGju/WA0C9nJGZ5QxHNy9/OI6ccfkGXPaI9Tli - cAScgyZYgOIR4vFT27v66ufFUC+X+r16ObaeHFrNrYJ68sPpF6FXAL0egBxHJu/ShDnh - GNACQrUAE49w5aPsgoBj+3cEMvXk5MIOxXryfsx5KwvZeasLcN6q4lXDe3q7HHkXBqRQ - PQHHrQkW4OLxYxvTwwPOWyVEbKY3sHZx3grOI5Pr5bjzyEknsq7BeWTmOiv2PLImTArH - gBYQpgUo0r59/ZPcwAoXWkETyIzkuO2b4IK5meSCOaXzyL+Q61ehW8BE6BawbF0QXPeY - mXsHes2RTuVf/mSvlxOmIXDUaAENsACNx7/hfoD2lsbXL+gN5Ydjt/mTjgEW0OIKLmDl - 3w/wCxSwkm460Bt5/lK4Djnh6Jls+QYk3p+jAR8UhyBkCzB4pOlVeryDlJMfjAn181wI - FyKbQkcduKCcd58ViUdSEMAeuNq+N5lNsEI3HUjoICCF7As49t63ABuPNJ1DOurcyT2f - mhglP24FDQMU73ukFwQYjbOwnbsYEqwx0G0O2neQhM4H6G6F8dj7XxRHIGAL0HCE0x3k - ug4mnZNz9ug+kl5lrwdQbqjD9AugF1q5rvAJ2Z3Ev2COu/ARU6wCdgkcei9agFuuMvKR - vV4uLiLAe4nzTHqdleJ2xy+/9Ok3gEno2JD2j0E79x1jTkDWNdMLkRGQvfgx8aeFbgEW - j6QagN4OQE4/ph2KCaPpHNKxnDSAVOjfQS5E5i4oJzcExBEBWfiEaRggW7AiIIXuGTj+ - XrAAF45cuwAiH6E6Zze9HYCeftQerNSwvA9J6NCKObhhjghIuIGVbagDNyJju/Je+Ir4 - k2KxABePTP9HtmF5SsKOQOZ2OaZ9h0J69ZdfaIMrciPytDkgIIOjuIZzcIUOdPDgMjoI - SLH4CM5DbRbgwlHWH7n0PtNuDqoBnGdajR8zavjQ3/mnH8m9j5DQIQJyLNmB9Fi7hV2w - 0hJWyLBCRofp4YEBqbbPiD8kDgsw4Qh3IQMeaXcruttxIknejpXKR4XtDpLQkTcshyMe - 22IOQgdI2sKDlOjIAYkBKQ4vwVmoywI8PH4mxTmQXSXdHxN2BK3rtl05xCMISNIywBRK - ysmCddf+Y2fhDlbScq6lHbYguZoArCtX13fE3xGFBXh4hM1HOGsFd6/mZUFzq/BNsNtB - mnfQbqxK8pEIyAGkxRWzYF2zOWLvEejhQXvqvGMBiStWUTgITkKdFpCFI6hHwGNT7Uto - xpoDzVijQnxpsdw4ZrdDablKF6yw46FvbGZJM6yh0YmpmVdpDWtTKwBSnmLFFas6vyf+ - lqAtwIUjUY8Ej3A1Oc3mJMdFQC8dUpxjYjBy2GDYfeRXr9KETj+6YCUZ1tkuy9YHRsan - ZFy6XlBaAYeuFAGJASloF8HBq88CbDhCMofisbWpror0Ks9MTYoO8/diej+OGgHNyhUO - d9C+On3ognWEAfQsJ008Nm6LOQA1cwwgiYIkgGRXrBiQ6vui+EtCtgCHx7+/0uQq4LGi - tOD6pYyU+B1B65e7zIZWAYa6UJyjvNtBIrIvZFihJMBwHM3obAjakcAHJOxBylM6GJBC - dhIcu7oswIUjrFbhZAenHq+eP3EgZttGms2ZMNZAB852dF6uEgEJC1a4JMAEtiDnLfXe - RABJFeTL2saWD59gzwMDUl0fEn9HBBaQLVaZ1WoHafxYXnI/n8HjBtIpwAKyOcOHDuzf - eblKdjygJAAyOkZm9BYdHwJIkmIteV5dD1XlsGKFKh1uxYqEFIHD4BRUaQF+ONLV6vuG - 15VPH1L1SPE4z96ay+Z0yq4yGZ3+sAUJgJxoA7cEEAWZlHou59bDJy9ekZTOHwoSEgNS - ld8S3y14CyiGI12tvql+9uhe3oX05PjIoA0ryM0AZkb6gEfI5ihnV2k8Mhkd2PIggFyx - ISgy7kgaFOkUQyPIppYPHxkJiYQUvKvgBFRvAS4cSWoVxONnWK1CMudx4c0rZ48lRoeB - emTxCDfndJXNkWd0CCBBQS7x9g/dnXj0zGXY8yivftPc2s5KSFlAIiJV/1nxF4Rpgc7h - +A5Wq7DXkZt16tDeiMD1y4l6JHjU6jqbwyxYf4ManRGMgnRdvm5LROxBktKhK9a3bbDp - QXM6GJDC9BEctdoswIXjN4aOUEf+vrGuClar+RczUvbtCvHzcne2s54AtQBks6OrbA67 - YCVbHiTFOsXOyW2Vb/DO+OT0C9fuFJVVvgYJCTkdDEi1fVP8IaFagIvG/5OF44eWpjfV - 5aUFN7LPHk+KCQ9Y4+EymyRXGTx2mc1hAfn7IC1IsY6bPG3WAo/Vm8KiE4+evpR/79Gz - qtrGrgIS16xCdRoct6os0FU4NtfXVDyB3Or5k4f2Rgb5eC5ynGE1fizgEdRj19kcGSAH - a+tAkY7VjLkLV6yHFeuB1HPZNwpg06Ou8T1HSN6+B573UNVnxfcK0gKyaOTRsbW5/tWL - p0V3crPSkxN2bfXzXjLfYeokU0Oy9zjgt27xSGsCYA9SW2+06SQb+3nuq3yDdsQdPnX+ - 6q1CyOlwAfknKQyQi0hEpCD9BgetCgsoRCOpkvvyx8cPrc0NryCXczfvYsbRxOhtAWuW - uUAyx3zMKB2oJP8OHmlNAOxBDhsxiux5zHbx8PbfuishOS0r9/aDxyQg37W1f4J9SBqQ - GJGq+KD4TgFbQB6NFI5f//zfl88fP7QAHSvLiu/lXz5zPCl2+5b1sFqdOQWSObra/4BH - Akgo0iEpnbHjrWznui5bG7Bt9/6U9Au5tx+SgISkTjsUBvzvz6+KiMRVq4C9CIfeIxbg - BSOJRrrtSPYd2XC8f/3KudSDIB59V7nPc5g62dRIf4TWINh77LIWgKhH8vTpC1WskNLR - MzSdaG3ntNhz/ZbwmMSjGTQgn1fXNrxt+QBpVopIhUUrjKZHZoUvQQsI0QKK0Ui3OWCt - +qm97X3Tm5oXZcUkHE8eitsR4ue9lORWzcYY6MBex4Bfv6MemYD8lVmxQo51qgNISJ/A - iJjEYyQgH5Q+f/m6vvk9XbP+jyxalSMSQ1KIroRj/kkL8GPx/4CNEI1UOX7u+ND6tqGu - uuJp0b3r2ZknD8fv2rpxtYfrHFur8bLV6nfxyACSWbGOMQcJuWCJl29QRGwSDcjCkrLK - mjeN71o/dICK5CKSpyPZgf3k9PCvowWEYgHFUGSCkaxU//cFlCPAsbnhdVX5k6K7+Vcy - Tx5JiArdtHb5QseZ1hNJbpWsVrvf66DLVbpi/RVWrEO1dUebgIScAzkdPxKQR9Ozcm8W - FD+tgDVr83smImlIUkrC/ycojwz/M1pAUhaAGADVSNAI0fgHicaWt41val4+K314J+/y - uZOHE6LCAtatWOxkbzN5nBHNrf7japWuWPuRFSsjIafM4AIyEQIy58a9osfPX9bUQUS2 - fej4+PmPLyQk//oK2R180AIStwCEwV9//UnQ+McnEo3vmupfV1eUPSq8fe3SmROH40k4 - ero5O0wj4hEK5cjW4z+sVhkF2e+3Ab8PGQZ1rKaTrGfOdaWEjElMScu8knf7waOyiqpX - bwgj29o7PpGQ/PK///0Jz1/4oAUkawESAf+DUAQyQjB+ADY21ddWVz57XHTvZu6F08cP - xe8KC1jv6TZvFuw8jiVbHf9qtSoLSNj00BllPI4XkPuPnDx7MfcmILLsRTVEZNNbCMkP - 7R0fP33+/AcJS3zQAhK2wB9/QCh++tjR3gZobG6sr615Wf4U4JiffT796IG9O0MJHSEc - LcePHa07XItUAvxDbpUEI3ngpoD+REKONDAeN9mGEtI3MHx3wqHjGVnZ+bcLi588e1H1 - qraehGRLaxsEZXtHx0fyfMIHLSA5C1DX7+joaP/woa2t9T0EY8Ob19Uvy8tKHgIcL507 - lZIYGxmyce0KJhxNRuuNgMKcf7daZQKSSEheQLos9fLZHLZrb1JK2rmLuTfuFBY/Lqt4 - Wf2qrr6hsentu/cQla0Ql/igBSRrgdbWlpb37942NzVAMNZUvXj+tKTo/q287KyM1MP7 - YiKC/NesWEzpaGII4fhvxSMNR1oVAAGppa3LEHKOy5KV6zdtjYzZfzg14/zl3Jt3CotK - y55DSNa8rn1T39DQ2NjU1AzPW3zQApKzAPH85qamxgYIxbraV9VVleVlTx49vH87P+fC - 2VMpSXFR2wL9vJctcnaAxaqJoT4Tjv+81cEEI/lXUqYzAJKsEJBjQEPOmDPfbcUav6Dw - qLiklJOns67k3rhd8PDR46fPyl+8rKquefX6dW1tXV3dG3zQAlK0APh+be3rVzXVEIsV - z8uelBQV3r2Vl3PxXPoxgGPk1oANXh6uTvbTLGg4Qmr13+w8ysORF5BEQ06cYjtr3qJl - 3j6bQyNjEg4ePXUm63Ju/q27BQ+LSx4/LXtWXvHiReXLly+ryFOND1pAQhagTl/18mVl - 5YuK8ufPyp6UPip6cO/2jWvZF86lpx5J3LsrPMh/recSl7l2Uy3MTUZTOtJcTld3WPFj - UOHPMkJCQJpOsJru4Oi6dOU6/6BtO2P3Hzp68nTmxezc67fu3Ct8WFT8qPTxkydPn5bh - gxaQqgWePn3yuLTkUVHRg/t3b9/Iu3o562z68eSkuOiIrQE+3ssWz58zw2ay2ViSyqF0 - /Dc7j0oB+SuzZB05ysh0vMXUmXMWLF7mvWFT8PZde/YfTElNP5sFIZl3/ebtO3fvFxQ+ - ePDwYRE+aAFJWuDhw4cPCgvu37t7+9aN/Nycy1mZGaeOHUmMi44MDfRbu3Kpq5PD9CmT - xo0x+OFwpLseEJCQZdXRNxxrNtnadpaT6xLP1b6bQ7bviklIOnL0RPqZzKxLV3Jyr+Xl - X79x8+atW7fxQQtI0AK3bt26eePG9fxruVezL1/IOptx6njKwf17oyPDgvzXe3kAHGdO - s5xgamygO/wH6UhQySxZISBH6EFWZ6LlNLs58xd5rFzjGxAcviN6774DR1JST6WfPpuZ - lXXx0uXLV7Kzs3PwQQtIzgLg+FeuXL508ULW+XNnMtJOHEs+lBgfsysiNNB/vfdydxdH - h+nWk81NDEeN1NYaTFI5/3mxyqxcSUDCtseQYcN1DYxMzSdbT3eYu2AxRKTPpqDQiJ3R - exISDx5OOXr8xKm09PSM02fOnDmLD1pAchYAxz99OiM9Pe1k6rGU5ENJ++NioiK3BW/2 - WwfR6Oo8e+ZUy4njxozW14Fw/H3AD4cjJSQUBgwcoqU9Un80INLCxnaWI0Skp/d6v4Cg - 0O2RUTF74vYlJh08dPhIcgo8R5nnGD6aaAH26+C/8S3wMx+KfQ/x/OTkI4cOHkjcn7A3 - ZvfOiG0hWzb6rFm1DKJxjt30KQBHIwPdEaRmdcBvP0pHdsn6a3/YiKRrViMTs0mWU2fM - cpy/cMmyVavX+20KDA4Nj9ixa3d0TOyevXHx8fEJ8OzDBy0gGQsQj0+Ij4+L27snJmZ3 - 1M6I7WEhQZv9fdZ6e3osdiHRaG0xwRTgOJKRjr9BGcB/2uhglqrcv8KSlaRZyZoVEGls - aj7Jaqqtwxxnl8VLl6/0XrvBzz9gS1BwSGjYtvDt2yO4JxIfTbQA93nw33kW+JkPJX/N - 9vDwsNCtIUGBmzf5+axb7bXCw33hfMfZNBrHjTWkcOSk40+EIyxZGRE5kCBSd9ToMRCR - ljbT7WY7znNZ5O6xfKWX95p1G3z8/Pw3bty0KQCezfigBaRkAeL0mzZt9Pfz8/VZv3a1 - 96oVy5a6uS5wmuMwY9oUiwnjYKmqp6M9bMjPrlVZRPaRIVJLW0d3lCFE5ESLKdNs7WbP - dV7gsshticey5StWrvLy8oZnNT5oAclZgHi+t9eqlZ4rlnksdV/s6jLPcY7DzOk2lpNp - NJKl6lACR1ir/ovzx9zStNt/pwHZ/3eyaNXW0Rs12tjEbMJkS+tp02c6zJ7j6DzfxcV1 - 4aLFbm7u7kvgWYoPWkBCFiA+v8Td3c1t8aKFri4L5jnNnTPLbsZ0GyuLieamY40MIBrp - LgeTyPmptSoXoRwiYdEKEak7ysBorCmEpIWVzbTpM+zsZ82eM2euo6OTk7Oz8zx80AIS - swC4vbOTk+PcOXNmz3Kwm2k7faq1pcXE8eNMjA0N9Eg0kqVqf7iboyfgyMRkn75MXodG - 5IiRegajjceajhs/cbKF5RRriMrp021nzJg5c6YdPmgByVkAHH/GDFvb6dOnTbWZYmUx - edIEM1OTMYYGo3R1ZNFIdjl6BI4sJGlEwtbHwEGwGzlcR1ffYLTRGIhJs/ETJk6abGFh - YWlpZWU1BR+0gOQsAI5vZWkJMTB50sTx5uMgFoGMo/RGjtCmuhHY2NPRCEEJi1aGkb8P - GjwUQhIoCTFpCEFpYmoKcWlmZm5uPh4ftIDkLACOb25mNm6cqanJ2DHGRqMNRunr6kAw - wkJ1IFmpqiAaCSXZiKSQJCEJmBypq6c/ygDC0tDIyMgYnjH4oAUkZgHi98ZGRoaGo0cb - QCjqQSwOBzIOgZQqKcdRUTSSiKS7kb/++huEJFByyFCtYRCUI3QgLHX19PT0uWcUPmgB - aViAc3lwf13dkSMhEodr01gEMrJo7FndSMOQ9y8MJJmQBDEJQQlRCWFJn+H4oAWkaAHG - /YcN09ICLA5mYpGsU3s4icOLQ94faUhCGR1gEjj5+8CBgwYNGjx48BD5MxQfTbSA/APh - n2QW+JkPJXvJEIhCiMNBA4GKvw8Y0B9iEZapqiUjLyJh3UqyO/36wdr1t/79IS5JYOKD - FpCyBSAKIBZ+I6FIY7Entzf4wdfdn2lQsmH5Kzy/4YMWkKgFiP+TOCSRCFjs0a3G7uKv - m39Ofh0eGAc+aAHpWoAJA3VDsZugxH+MFkALoAXQAmgBtABaAC2AFkALoAXQAmgBtABa - AC2AFkALoAXQAmgBtABaoFct8P/b5umcCmVuZHN0cmVhbQplbmRvYmoKMjQgMCBvYmoK - NDQ4NjUKZW5kb2JqCjIwIDAgb2JqCjw8IC9MZW5ndGggMjEgMCBSIC9UeXBlIC9YT2Jq - ZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMjU2IC9IZWlnaHQgMjU2IC9Db2xvclNw - YWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxhdGVE - ZWNvZGUgPj4Kc3RyZWFtCngB7dCFQQIAAABBsTswEAxsBQWD/XdzkL8b4Vartj8MGDBg - IDnwiwEDBgwkB34wYMCAgeTANwYMGDCQHFhiwIABA8mBBQYMGDCQHPjCgAEDBpIDnxgw - YMCAgeDAHAMGDBhIDswwYMCAgeTABwYMGDCQHHjHgAEDBpIDbxgwYMBAcuAVAwYMGEgO - vGDAgAEDBoIDzxgwYMBAcuAJAwYMGEgOPGLAgAEDyYEHDBgwYCA5MMWAAQMGkgP3GDBg - wEBy4A4DBgwYSA7cYsCAAQMGggM3GDBgwEByYIIBAwYMJAfGGDBgIDpwjQED2YERBgxk - B64wYCA7cIkBA9mBCwyEB84xYCA7MMSAgezAGQYMZAdOMWAgO3CCAQPZgWMMGMgOHGHA - QHbgEAMGsgMHGDCQHdjHQHhgDwMGsgO7GDCQHdjBgIHswDYGDGQHtjBgIDuwiQED2YEN - DBjIDqxjwEB2YIABA9mBNQyEB/4BLgXylgplbmRzdHJlYW0KZW5kb2JqCjIxIDAgb2Jq - CjM2NgplbmRvYmoKMjUgMCBvYmoKPDwgL0xlbmd0aCAyNiAwIFIgL1R5cGUgL1hPYmpl - Y3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCAyNTYgL0hlaWdodCAyNTYgL0NvbG9yU3Bh - Y2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURl - Y29kZSA+PgpzdHJlYW0KeAHt3Qs/k2EYB+A5j2HOZpjz+TxzNkQSSSJJJJEkkkgStq/e - B+n6CPtte9/nuQ//K51KPT483N//vbv7c3v7++bm1/X11dXPy8sfFxffz8/Pzr6dnn49 - OflyfPz56Ojw8NPBwcf9/Q97e7u773d23m1vv93aerO5ubHxen391dray9XVFysry8vP - l5aeLS4+XViYn38yNzc7OzOTTCanp6empiYnJyYmxsfHxsZGR0dGEonE8HA8Hh8aGhwc - HBjo7+/v6+vt7e3p6e7u6urq7Ozo6Ghvb2tra21taWlpbm5qampsbGiIxWL19XV1dbW1 - 0Wi0piYSiVRXV1VVVVZWVJSXl5eVlZaWlpSEw+Hi4qKiosLCUChUUJCfHwwG8/Jyc3Nz - crKzs7OyMjMzMzICgbTP7/v3+/f/9/zz/Pf+8/53/nH+c/51/nf/cf9z/3X/V/9Q/1H/ - Uv9T/1T/Vf9W/9f/0P/R/9L/0//U/9X/1v83/2D+w/yL+R/zT+a/zL+Z/zP/aP7T/Kv5 - X/PP5r/Nv5v/t/9g/8P+i/0f+0/2v+y/2f+z/2j/0/6r/V/7z/a/7b/b/5d/IP9B/oX8 - D/kn8l/k38j/kX8k/0n+lfwv+Wfy3+Tfyf+Tfyj/Uf6l/E/5p/Jf5d/K/5V/LP9Z/rX8 - b/nn8t/l38v/5x/wH/gX/A/+Cf+Ff8P/4R/xn/hX/C/+Gf+Nf8f/4x/yH/mX/E/+Kf+V - f8v/5R/zn/nX/G/+Of89IxBIp1L8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8 - d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/ - zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf - +e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47 - /53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/nv/Pf+e/8d/47/53/zn/n - vwfSqdTjw3/sv/8DK6twSQplbmRzdHJlYW0KZW5kb2JqCjI2IDAgb2JqCjgxNwplbmRv - YmoKMTcgMCBvYmoKPDwgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMCA+PgplbmRvYmoKMTgg - MCBvYmoKPDwgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMSA+PgplbmRvYmoKMjcgMCBvYmoK - PDwgL0xlbmd0aCAyOCAwIFIgL04gMSAvQWx0ZXJuYXRlIC9EZXZpY2VHcmF5IC9GaWx0 - ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+zTYShIhBhXiIdwoJlSms - rKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQoZuXosCsS9cgqSAIPHXo - +83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuDHylFHdROWKYV+OlicYyx - 67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mfKGWAs8Adlq/YPgE8WA6s - GvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD/lyPZtaOvbPqqtFM1LT3 - RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZSNWS5n2pOnXXgdRi7XbqT - 4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9bUcOTwCdhP2SHedatH/YX - rlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x1BmY90Y5pgsxd5aqEzeA - O2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJWBR9i7BJDjw+zh5V4Heo - mMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx213t8/+njFXXXtj48+Y16 - 3DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEywDCjEfwU+l/qSE1Xc1e7t - uEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5eHfYInpt+U1XsuuG/vr2 - evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ/klFED+FOVoq8hRV9FZQ - 1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+jSfCwaSHiEqCKgzPUTlRj - jQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjI4IDAgb2JqCjcwNAplbmRv - YmoKMTIgMCBvYmoKWyAvSUNDQmFzZWQgMjcgMCBSIF0KZW5kb2JqCjI5IDAgb2JqCjw8 - IC9MZW5ndGggMzAgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIg - L0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Aa2TzWsTQRjGn02QCtZQi0jx4oJSPERdkhbb - W9t8SOwSlySlfhw02d1soslm3d1ErR561H+gFEQQPOjBmxc9tSeR4ieC9OBdUU9a6qGU - 9Z0Zd4Ng8eK7zMxvH555Z+adXSC+UXWcVgxA2/bd0qkZ+ey58/LAOiQcQgJJyFXdc6Y1 - TSXLDrH5gdwU74+xXF9iz7c+fdtz58Li7bXDSw9bO0wK5YRLCwJSkoT9luApxjXBFcbX - fMcnT4Ox3qgaxLeIk26llCF+RJywBD9lXBP8gnFPt9jcdWLFNpo2ENtNPGGYnk48RWwZ - nt4mpjwS2u0O5Y+znEd1x6W58bfER1hdaKS4mgAmv5J+r69dPAE8WQMOaH1tdBkYvgQ8 - m+xrP97wWkkjNa+eTvF00uBBYNdqEHwPgAHyb78Ogq3lINheojU2gJWi3nV73EsblF4B - /3oXZxbZgXd0Bgp+R39nURfuUoAHq0BlEVBpvEvj6E9g301AA+lUpnQ6bKKGJAN7szlV - lVNjynhem+fKf+zarS7dFY9h6gftWvEMjSPUPju+RpsS7PXKuZDrzXwhZKOanQ15oZEp - hlx386WQL1dPswPynKY9Vw7ZafFv//daM5Hf9HKRZ6FRYWfmHrdbmgv5Smc28htmNtqb - 3Sqy/4n7m34h2j+yyEGlR0YKY1AwjjyVfV58kzQDQ4+B+0PKyXR55eNLJvwRvnmd33Wm - 49xwm1bDl6fpjzSTcsHWjyfllKJM4BeDarM/CmVuZHN0cmVhbQplbmRvYmoKMzAgMCBv - YmoKNTY1CmVuZG9iagoyMiAwIG9iagpbIC9JQ0NCYXNlZCAyOSAwIFIgXQplbmRvYmoK - MzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VS - R0IgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBhZRNSBRhGMf/s40EsQbR - lwjF0MEkVCYLUgLT9StTtmXVTAlinX13nRxnp5ndLUUihOiYdYwuVkSHiE7hoUOnOkQE - mXWJoKNFEAVeIrb/O5O7Y1S+MDO/eZ7/+3y9wwBVj1KOY0U0YMrOu8nemHZ6dEzb/BpV - qEYUXCnDczoSiQGfqZXP9Wv1LRRpWWqUsdb7NnyrdpkQUDQqd2QDPix5PODjki/knTw1 - ZyQbE6k02SE3uEPJTvIt8tZsiMdDnBaeAVS1U5MzHJdxIjvILUUjK2M+IOt22rTJ76U9 - 7RlT1LDfyDc5C9q48v1A2x5g04uKbcwDHtwDdtdVbPU1wM4RYPFQxfY96c9H2fXKyxxq - 9sMp0Rhr+lAqfa8DNt8Afl4vlX7cLpV+3mEO1vHUMgpu0deyMOUlENQb7Gb85Br9i4Oe - fFULsMA5jmwB+q8ANz8C+x8C2x8DiWpgqBWRy2w3uPLiIucCdOacadfMTuS1Zl0/onXw - aIXWZxtNDVrKsjTf5Wmu8IRbFOkmTFkFztlf23iPCnt4kE/2F7kkvO7frMylU12cJZrY - 1qe06OomN5DvZ8yePnI9r/cZt2c4YOWAme8bCjhyyrbiPBepidTY4/GTZMZXVCcfk/OQ - POcVB2VM334udSJBrqU9OZnrl5pd3Ns+MzHEM5KsWDMTnfHf/MYtJGXefdTcdSz/m2dt - kWcYhQUBEzbvNjQk0YsYGuHARQ4ZekwqTFqlX9BqwsPkX5UWEuVdFhW9WOGeFX/PeRS4 - W8Y/hVgccw3lCJr+Tv+iL+sL+l3983xtob7imXPPmsara18ZV2aW1ci4QY0yvqwpiG+w - 2g56LWRpneIV9OSV9Y3h6jL2fG3Zo8kc4mp8NdSlCGVqxDjjya5l90WyxTfh51vL9q/p - Uft89klNJdeyunhmKfp8NlwNa/+zq2DSsqvw5I2QLjxroe5VD6p9aovaCk09prarbWoX - 346qA+Udw5yViQus22X1KfZgY5reyklXZovg38Ivhv+lXmEL1zQ0+Q9NuLmMaQnfEdw2 - cIeU/8NfswMN3gplbmRzdHJlYW0KZW5kb2JqCjMyIDAgb2JqCjc5MgplbmRvYmoKNyAw - IG9iagpbIC9JQ0NCYXNlZCAzMSAwIFIgXQplbmRvYmoKMTkgMCBvYmoKPDwgL0xlbmd0 - aCAzMyAwIFIgL0Z1bmN0aW9uVHlwZSAwIC9CaXRzUGVyU2FtcGxlIDggL1NpemUgWyAx - MzY1IF0gL0RvbWFpbgpbIDAgMSBdIC9SYW5nZSBbIDAgMSAwIDEgMCAxIF0gL0ZpbHRl - ciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBzcLXcQJAEAXByT8vjLDCO4HwIoobfRPA - K7arW4f22V1akT1anX3ae/t85hfWOcAih1jnCIscY50TLHKKdX5jkTMsco51LrDIJda5 - wiLXWOcGQ7cYusPEPYYeMPEHQ4+YeMLQXww9Y+IFQ6+YeMPQO4Y+MPGJoX+Y+MLAf+tF - vN4KZW5kc3RyZWFtCmVuZG9iagozMyAwIG9iagoxMzAKZW5kb2JqCjMgMCBvYmoKPDwg - L1R5cGUgL1BhZ2VzIC9NZWRpYUJveCBbMCAwIDUxMiA1MTJdIC9Db3VudCAxIC9LaWRz - IFsgMiAwIFIgXSA+PgplbmRvYmoKMzQgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1Bh - Z2VzIDMgMCBSIC9WZXJzaW9uIC8xLjQgPj4KZW5kb2JqCjM1IDAgb2JqCjw8IC9MZW5n - dGggMzYgMCBSIC9MZW5ndGgxIDUwMzIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3Ry - ZWFtCngB7TiNfxNVtufcOzOZNkDT0pbQAJl0aJWm2QIKlEJpaJKWNkILVDepsCb9kADF - Flo+n9Iqq2L4sK7a1d+u6K6rFaw6bZENRZevxdUVfn6ivLfig4X14z0R9Af7VoHOO5Nq - BZd9f8Gbk3vn3nPOveeej3vu3AACwBBoAw7u2mXhJpBhGmEOU7HWrmpR3tm342NqnwaQ - V9zetGhZ6hcziZ4QABDKFzWsvT0yatrbAEN/RzyvR+rDdWeXqscBhjVQf3KEEMPGCEQf - ZtDHRpa1rJH3Yxf1X6e+3NBYG4Y6SKc+8YC0LLymiT0q3k39Y9RX7ggvqx+59bl11P8H - 9dWmxuYWvQpuB0gaRf3sphX1TWeOuN6jvpfWEyYcEhjPEJCoADgMjNgLILbBGCojeA9k - 6hf0v1L5zCj9s4j2NCT31wDwEmpvi4+/qhJP0OyeAZT+L56rBlyzMzAQDE2Ncu2nHMxQ - AltABAsI8Az1zsJxuA8klGEyJEM+vIAfgQcq4R4shJ8TTwaUwQuwGz7ARfolEPSgfgCW - QidOIv0zoAAWwF44T3x/gp9CGNZAK96j30XWSYQxkAk3kDVXwDo4SRwJkAY2yMQsNo0f - gxE0sgHaYAPsFir0Z/XjNCaBoAKeheegH6sxou/STxEmH6aCD+bDHcT7AIqYJo7R/6Kf - 18/DRFrnQlhE8yyHx2AXmnA4OvEPrIh3wDjSsxGaIAod8Ev4M2bjm7xS3w4uggkwh+a7 - FWpozi3QB2/ANyixGraGvcB28RX8ogDCUfFtyae/ph+hyBXBSmMKaMRtFE+Lad4H4R34 - EP4KX8HXmIaZOAEn4wwsw6WsQTJLP9X30BgzjAaFbJADebTSAigmmEe2uBMehS54BV4l - OABfokJwHcE4vBWfwR48xZKYwg6zd9g3PJ/7+aOCVVgo3Ck+Jp6UcnSPvosslQJ2UGEK - zVhOFrsVamlVzWT9X0InwYuwE2LwHvwFTsHfaH0j0Iqj0IOlWI7nGGePs8/5ZL5OkPpH - 6xP19fGoTqLVziAoJ7gJZsNcuJk8GoB68vY6+De4C9bDPRQRD0I7gSFnQEof7IPXKeLe - JXv8B/n5FPwXnKOI+BYukz+SSLIDc/AGzMfp6CXwYQVBBFfj/bgZ2/Fh7CKNN7KH2Vc8 - kafycl7P7+ab+JN8Lz/IjwjZwiyhR+gVC8RScROBJh4TP5G45JEekj4zbTe9IlvlIrlM - Xiz/+tLOfug/2n9On6HP0bfoW/V2/b/j3pPIYjL5YwhFeCpFrRNupIgqp+iZD1UQ/M5+ - yyhSmwlWwipYC/fC/bCZYAs8RBH0G3geeuBl2A9/hNdIUwOO0c75mOA07aF/kK4ymnEo - aWwhGIVjcCzFnBNzMQ8nYSG6yf5zMIj1uAI34TZ8GV/Ft/AjBuRtG1NZAZvO6sgKz7Od - bC/55zryUD6/iS8iazwpJAluEcQO8TOpU3oV3sPptN+ufh6Br/RUYQucod2zGt7neXod - r8Xl0CLehk74lnbGbtJF5ZSLcRycE75AJ1vN0nAjS2OT2GnxFXykP4qJ5MuPIIdW5hM6 - 4N+hkM+gvbqW+4WF7PdCNu6kCK3BL9lC9ivmE9ewaijGF9GF5XwcHDFlSZ+wevycZ5pC - cBFXkRaV8Du2AzYyF/4Pm9a/T3KJE2G78BHzwHY4xjJMEkvjF9m77Am4gz1Ee+IRirpv - 4Be03qG4gnKOCwvwXYqmg/g+5d8XxDb9vHgnK2TT8R32N4ogEJ4QwgNc/yJx/j86bgF4 - iS0zzaKsO0I8IB4w2uwQa+Qu7mImOEJ1IzOxD4Ri+AXXTDoWiptQkd6U3sQlUCciZEOF - 8DPswK/xIPQKU+A8fg0opEAFZkvT8AlxGlSII+ExlgkP0Sn3Br7I18DnOJrGLGGHTLMw - X7gICzEffisUC5/wDvYImlkOnsT78O8EDZRdnbgW1ksvwWq+EfJ42PQ+OtjP2R5oYaWU - ZeewbKzkb8Eh2CMVsJvpnQ37+TYWoCyXJx+GM9ggbBA24AdQxuZBG2sVEJLwuHAJGqQW - uFP8EO7C1XEpfYYc2vO/IVmT8E902m2gHJNNZ8sewn4IRZBLuXsN5e0dlAOClCmQzsYz - KFFmMHLeKbYTGfweZsHD3Mct0sNwN/sWMyjD1BE2C5bBVlQpSxRS1jyIH9M5GqBT73pe - A3NN24HhcNqhIG6lk0eFE/AqlsNP4EPMoMyoAjKB34htcAmrWEd/jVACiXw53yAuxRLa - Ty8C6qnwZz0i0PeGe1L+lBsmjM/7iSvXmTPu+uuys8aqmQ7FPmb0KFvGSOuI9LTU4SnJ - lqRhQ4eYExNkkyQKnCHk+tSSkKJlhzQhW501y2X01TAhwlcgQppCqJKreTTFGBcm0lWc - buK8/Uec7gFO9yAnWpTpMN2Vq/hURTviVZUYVs8NUHuLVw0q2pl4e3a8LWTHO0Op43DQ - CMVnjXgVDUOKTyvVhCwtsSrg0MqCqyJRX8jrysVuc6JH9dQnunKhO9FMTTO1tBK1qRtL - ZmC8wUp8Bd0M5KGkrlauen1amUpDaUae5QvXaZVzAz6vzeEIunI19NSqNRqoxVqSM84C - nrgYTfJoprgYZbFGmsEmpTt3X3RzzAI1IeeQOrUuvCCg8TDN4dOSnVqp6tVK1522unJj - +GxVQEvwxBCqAruhXG/rLmvzeoOGtBRP4P4r2W086rMuVozR0ej9ivbU3MAVk9kcxpTB - IE3qyvXPCzho1apvs2KoMS8Q14AmRWseLdzAGWoOKFyv+gxMaImiJajFaiS6JER+y4hq - MG+toyej3L1bPwHlPiVaFVAdWpFNDYa9o7pTITpvbW+ZWym7muLK7bYkD1i6e1jSd40h - Q69s1JMXBmjxVpzdaNGqvzc1GitSyzQ3hVutQisJqBrLyjeq+nyI1uaTR+gJIll0Mdkv - FLUUkHaamGVRlegFoJhQz3xxNSb8HUbKslwAg2hEzmD0aRj+vq05nVpOjhEpJg+5llY2 - I96f5MpdpfnVJoui+clkUBmgQcGCPDK5w2F4eVPMDTXU0drmBgb6CtTYesCd5wxqLGRQ - 9n1PSbvZoLR9TxkcHlIpsnfGbxJpmpw9+EuypA/3RQo0TP8/yPUD9BLax9FoiaqUREPR - cExvq1EVixrt9vujTT7afwMrj+l9m2xayeagZglFkMynDfcEuI0ZsUctZuNBF31GUGKg - nERAX0smutQkO5KzqKLTFS4pfN8ltwgXQRH2ERcw6NKPMyvdY0wwHCrciRIKAJQeuRDD - ZW6b/PwwM98q3CfhSrO0MjmttLTc/HxyWeqCVVbnHMv52Zfn+Oq9n8y2nCY4fwaKLn9Z - hMkpU4HK1AnjcQTjKqNPn4mUwCQ1M3vSjZPx0wlTb1non3ggtTwSKS+LLBK3Zfe/cfkW - thyvL7z4noGKlJVHaG2GGgzgsulXoduSpl8Am2ysGA6VNvQMvmn1pOk24k2I8xsEGiex - y81wWt7f/1j/4/ITgxSDajxMIhTbT9/tQPfJOqoHZC0geQvITIzuU6kwnRgLhR6yokFF - +ko33jQ5fXeCd25xZdktTk+4YXHz7KriRrrC0lqNR7/JuHNe4zHoZNwYf7Rn+Uh7jF/s - pdeUGJrdGWNW22+hspCK0jq+1d3KX37Qa59iWWfpQw6MHd7VNNZ+6ORwewz7e0+OtOfN - TMAHoIgKg5PsIF3F7Oyge/5rqr2pta2VtZofND9pfsm81/yWme5hlgT2dsKJhHMJPInb - OftPfpbrnOcpaM+8LfOsoitCkpKnFCkVSqPSqrykmJIy7ZkVmbxtOVpmOlgTKFTGU3FT - aafyFBVpEGtgeJxWSS02iCd9qW9hTe5EtmNdpr1tHW7siumHe63p8bf7emv6U5+a7E99 - +owpfUnnnqyBquPp8faOpxPGpz/dmZMwUMVwQs/jZnsfToDH8Ua3xXwFLSVZdsdY/ss3 - 2xJsCe1/wOcoktvx1/Fachea2i+a2ttM7UtN7YtM7SFT+89M7QHTWDlTVuQx8ig5gy4c - 6XKqnCJb5GHyEDlRlmVJFmQmg5wa00+4JxiuT6V/HRDSJYvxkowdAkK8bSElKZTIsxQb - DGVG9xD0a/tqwV+jaH+fr8YwcW61JqrFqKX4wV9VbEVtOPcz//xiLd/pj8kwT5vi9GsJ - lbcGuhG3BgmrsY3x4yWGIw3UvTbjZNlNXy7z7t1iM976vVuCQUhfVWQtSpmRPLXEe40q - 9AMy5HX+82P9AYX+yrV7wY5nyWh2VOJ1aq/J/qTJ4PHPJ2J7nNgeJ7YjEdsHiNbRWod/ - fkDbMTqoTTQa+uhgb3XfhqM+OqRCqq+eSkjbtCpi1dpqFKV7Q59BoLMiO1RTGzHe4Xqt - T633ahtUr9JdHR/3I/JRg1ytervhqK8q0H3UXe/tqXZX+9SwN9jb2dLYdZWsBwZlNbZc - Q1aLMVmjIaszPu5HsroMcqchq8uQ1WXI6nR3xmWhb/H8YrJVoFuG4qBnwcC7l5kTyT0h - myNYHPfTNId1va2PXcACMNMpMoQ+PoZSMVzomumaSSQP88RJw4zvku9I1vXTHLY+LGAX - 4iQLoZMpaPAHLxmtZmdzc/PKFqpaVkLLSoJm4miOU5zQMsBMwfi/LcjbTgplbmRzdHJl - YW0KZW5kb2JqCjM2IDAgb2JqCjM0NTYKZW5kb2JqCjM3IDAgb2JqCjw8IC9UeXBlIC9G - b250RGVzY3JpcHRvciAvQXNjZW50IDc1MSAvQ2FwSGVpZ2h0IDY5NSAvRGVzY2VudCAt - MzE5IC9GbGFncyAzMgovRm9udEJCb3ggWy0xNzYgLTIyNyAxMDc2IDkxM10gL0ZvbnRO - YW1lIC9EUUJQSVYrQ2FsaXNNVEJvbCAvSXRhbGljQW5nbGUgMAovU3RlbVYgMCAvTGVh - ZGluZyAxMTEgL01heFdpZHRoIDEwOTQgL1hIZWlnaHQgNDcxIC9Gb250RmlsZTIgMzUg - MCBSID4+CmVuZG9iagozOCAwIG9iagpbIDM0NCBdCmVuZG9iagoxMSAwIG9iago8PCAv - VHlwZSAvRm9udCAvU3VidHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9EUUJQSVYrQ2Fs - aXNNVEJvbCAvRm9udERlc2NyaXB0b3IKMzcgMCBSIC9XaWR0aHMgMzggMCBSIC9GaXJz - dENoYXIgMzMgL0xhc3RDaGFyIDMzIC9FbmNvZGluZyAvTWFjUm9tYW5FbmNvZGluZwo+ - PgplbmRvYmoKMSAwIG9iago8PCAvVGl0bGUgKFVudGl0bGVkKSAvQXV0aG9yIChQcmVz - dG9uIEphY2tzb24pIC9DcmVhdG9yIChPbW5pR3JhZmZsZSBQcm9mZXNzaW9uYWwpCi9Q - cm9kdWNlciAoTWFjIE9TIFggMTAuNS41IFF1YXJ0eiBQREZDb250ZXh0KSAvQ3JlYXRp - b25EYXRlIChEOjIwMDgxMTE3MTg0NzE0WjAwJzAwJykKL01vZERhdGUgKEQ6MjAwODEx - MTcxODQ3MTRaMDAnMDAnKSA+PgplbmRvYmoKeHJlZgowIDM5CjAwMDAwMDAwMDAgNjU1 - MzUgZiAKMDAwMDA2OTExNCAwMDAwMCBuIAowMDAwMDAxMDk4IDAwMDAwIG4gCjAwMDAw - NjQ5NjMgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAxMDc5IDAwMDAw - IG4gCjAwMDAwMDEyMDIgMDAwMDAgbiAKMDAwMDA2NDYxNCAwMDAwMCBuIAowMDAwMDAy - Njk4IDAwMDAwIG4gCjAwMDAwMTM5NDkgMDAwMDAgbiAKMDAwMDAwMTQ1NSAwMDAwMCBu - IAowMDAwMDY4OTM5IDAwMDAwIG4gCjAwMDAwNjI5MzcgMDAwMDAgbiAKMDAwMDAwMTYx - MyAwMDAwMCBuIAowMDAwMDAyNjc4IDAwMDAwIG4gCjAwMDAwMTM5NzAgMDAwMDAgbiAK - MDAwMDAxNTM2NiAwMDAwMCBuIAowMDAwMDYyMDE5IDAwMDAwIG4gCjAwMDAwNjIwNjQg - MDAwMDAgbiAKMDAwMDA2NDY1MCAwMDAwMCBuIAowMDAwMDYwNDQ4IDAwMDAwIG4gCjAw - MDAwNjA5ODggMDAwMDAgbiAKMDAwMDA2MzY2MiAwMDAwMCBuIAowMDAwMDE1Mzg3IDAw - MDAwIG4gCjAwMDAwNjA0MjYgMDAwMDAgbiAKMDAwMDA2MTAwOCAwMDAwMCBuIAowMDAw - MDYxOTk5IDAwMDAwIG4gCjAwMDAwNjIxMDkgMDAwMDAgbiAKMDAwMDA2MjkxNyAwMDAw - MCBuIAowMDAwMDYyOTc0IDAwMDAwIG4gCjAwMDAwNjM2NDIgMDAwMDAgbiAKMDAwMDA2 - MzY5OSAwMDAwMCBuIAowMDAwMDY0NTk0IDAwMDAwIG4gCjAwMDAwNjQ5NDMgMDAwMDAg - biAKMDAwMDA2NTA0NiAwMDAwMCBuIAowMDAwMDY1MTEwIDAwMDAwIG4gCjAwMDAwNjg2 - NTYgMDAwMDAgbiAKMDAwMDA2ODY3NyAwMDAwMCBuIAowMDAwMDY4OTE1IDAwMDAwIG4g - CnRyYWlsZXIKPDwgL1NpemUgMzkgL1Jvb3QgMzQgMCBSIC9JbmZvIDEgMCBSIC9JRCBb - IDw0OWU2MjQzZGUwYzBiMTQ0NmRmMDQzNjRjNzc1ZGNlZj4KPDQ5ZTYyNDNkZTBjMGIx - NDQ2ZGYwNDM2NGM3NzVkY2VmPiBdID4+CnN0YXJ0eHJlZgo2OTMzNgolJUVPRgoxIDAg - b2JqCjw8L0F1dGhvciAoUHJlc3RvbiBKYWNrc29uKS9DcmVhdGlvbkRhdGUgKEQ6MjAw - ODExMTQyMzU4MDBaKS9DcmVhdG9yIChPbW5pR3JhZmZsZSBQcm9mZXNzaW9uYWwgNS4x - IHJjIDEpL01vZERhdGUgKEQ6MjAwODExMTcxODQxMDBaKS9Qcm9kdWNlciAoTWFjIE9T - IFggMTAuNS41IFF1YXJ0eiBQREZDb250ZXh0KS9UaXRsZSAoUmVwb3J0ZXJJY29uLmdy - YWZmbGUpPj4KZW5kb2JqCnhyZWYKMSAxCjAwMDAwNzAyNzQgMDAwMDAgbiAKdHJhaWxl - cgo8PC9JRCBbPDQ5ZTYyNDNkZTBjMGIxNDQ2ZGYwNDM2NGM3NzVkY2VmPiA8NDllNjI0 - M2RlMGMwYjE0NDZkZjA0MzY0Yzc3NWRjZWY+XSAvSW5mbyAxIDAgUiAvUHJldiA2OTMz - NiAvUm9vdCAzNCAwIFIgL1NpemUgMzk+PgpzdGFydHhyZWYKNzA0OTgKJSVFT0YK - - QuickLookThumbnail - - TU0AKgAALDSAACBQOCQWDQeEQmFQuGQ2HQ+IRGJROKQoViABCsQhoAiEKA8AhR2PF/ux - vuZ/t9quB/NWKy+YTGZTOaTWbTecTmdTucAYCAADHwwUEzlADGcLA8ABaISd/N9PLV9p - 5FKZ9op9PwAPqeV2vV+wWGxWOyWWCiAMAEQMRMgtihsJAANAABAKBAoEgB/gYDAAAgO7 - P9+v2/Pp9gB/PV7P4BP9/gJpt1+tMnHh8E5wOh/uCzZ3PZ/QaHRaOCT6gN5XA1vhsIv8 - NP8HA6BBII366wYAv+BbqB7x/P6BO94QJ4vMAMxsP1mDs0vcd1mt6TpdPqdXrdNIHEEp - I3lIBm0AbGBBQKwfgQjHboA+uB8DHQJ+ul2PwCPZ6gQ9Jl8npDqR9kO68AwFAcCQKh4G - LyBx2FsBp1r4AIDACDoQIEwC9Pe9iDt496/AC3qDH8wh8G2cR8sUf56BAKp6hAeh7gAe - kDRlGcaRqsxGDaBBJjmKwCDYAAIgmvQIAgv0jSO9MOt3DEMve3T1IOfZ2HcfgCnmeICD - uS58juqqrxtMEwzFMaIAUA4AAYdpcAadgEQjM4OhCgTbt2hbeQ/KEPTrPaCRCAB8m6cR - 9OKfx4BCKp7BCex8gAe0yUfSFIxkQw0gQRo8i0Ag5H+B64gCCIKIE3ML1FI9R1IgzeSa - 872Mc4E9ABKUqAKeksDkSZ8jkR5VH2R9JV/YFgs7NwAAVNQGnaBUIgQAAOBFCqfz4gkn - r1I1YWpKD0NwgZ+K0fRvnCfZ2ngfx2BEK57BEfCuHxYV3XfeCZj+MYDkOQAwAKPAAAhI - R/gi8sPT0f73IG9dryXUsLvVVdq1FgVq1gfR0nafYDHseACjaR58jaShXH2Sl45FkeSI - M0wEHcXIHHaBYDn+BR/g6Eq/AGAeCt288j4bhuGSVVGeYPVFW27WJvm+fZ1Hcfx0hHdA - RugrmS6lqdJDwLwDkAQ4ygKP4AAfIQAAkDE8YhDeISNalYT5D20oLbGdW2fJ0nSfQDnu - eIDDQRZ8DQTJZH4TOqcFwcZgLmwDzVlYGgSf4F2aEyBAIAsPz3DiC1hnODyTtW1WnVKB - rsgWiH2cBvH4cp1H8cgTCyewTH2wjD8J2faNIOQsgOPRGjUApCn+BshJCudSbTnudSfD - Gyc5gWCYd5GHc09+JHVup8bwMZDnwMZPFsfhPdr8HwrFCwC8SdoH8YBtmhRyK+z5O+2M - RuFp/hymd214/6/e+CtH4cI3X/DoH8OEE4Wh7AnH6cAwj4oGQNJoGoKYBg5iVDgAYRgA - HgECAmBxPCqlTtuaE8ZJbCyCNsYGz6EMHXnIfHwOcdA+QED6HkAcLwhB8BeFGLkfgo4H - Q9h8Q8ASHgCDsFwA8dgEQFD9KUBwFRenJPzIUbpV5DU7m9VVFZhL9FssOfsk8fZXB/Dj - G8P0bg5B/DcBUFwewKh/RSh/G+OBAgyBNAMGwTYdgDCTTQv0CgHW0J2Q1Fx+61FRJOZv - Id4jZyGJ3iqAAfA5RywwH4PMA4WA/j4CwKkXw/BUxxk8+JPQAx1C2AeOoCgDR+lxA2Cs - gQBX3QgQ4/GFDOWEIdka/dz0UZEPPj+3A3kXwAD9HIN0fw1xwD9GsC4L49wXNmk/M9qg - XAkAFDIKMPYBxNgAAXHwD8KJYwlZxFl+kWXLOeliteQktm1zgaE/pao9xyDiHwAkfo9A - EBTD2PcKYrhhD9FdNCgDJABDoFqA8dIFwHD9VCBsFjkUzv5Z252dMsn7SyQyb8hU6JCu - VkQnVtshx/j6UYP8csxBpGSGkDEMQ9wY0BpcsIKwQwCheFSIAA4oVilxH+BRZ6GZzLWi - 6zeNznXMNueS9GEjZFStBlxR9hI9hxjhHwAof09gnB3HuE4WYxh+izpfV9MYAhyiyAgO - YDQER+AXAABmhpQC8wpL0qyir+Jbl+mctKQNEYsPHYLIyQCsV2j+HNMQZpyRmg2DMPcG - 1YLGIzCeD0AgVxYCGAQKinJAgKgkkC/Wdzb6JV6kXFGRtTmfSGShaNgsHyBD2HEN+qY/ - x6gICQHMe4SBcjKH6LmxtuzrACHCLACA4wPATH4a8DILS/AGAVXmEEunPrai3R6Dz9rm - xUupZtgo+kXj/HONwf4xxqD9GODsNRzreXnNEEgG4BAoC3EYAgV4AAEm1H+BYE8UGFTe - ivUapLP6O17VHOeLE7rQRanVLijcWTgD1HENwe7jh7gJCGG8e4QxfDOH6L69GGyxgBG8 - K0CA4AQgWH4B4AAGLkAAAOAyv8Vb9zfv3f65kuSE1+kdAtdaFTAgML65y67lG1G8Hyo4 - AA6RuAAGCM8fowQgBuHuEDDmUSeBBBkAMJIvhIgJFsAABCRQAAXBTfxDrAqJ3Wc+5tVr - ya+tuH4YQAI+CtSOdlLQg60WvLMLpc+vipa/D0HCNse4DABYRB8GsewPhhjSH8MPKWjS - ZgBGyKoCA3ATAZH4s8DALiBYrrxOSutd8g56nYqhDg+XZZwdEzlO7oQHA5labUAA7KvE - FdDBih4BXQ6huciYgQ6sji7GWPwXYRg5D4CNo7ZBEwdgtAGEEYglgEi+H+AgpQAQL3Ic - 3qNs0W7SIfim0FnJ0B/6mMLqpkzwwJhKg0E3TdaiCpqIEOEQxAh/IvIKBSt8QWEPFlqh - keg3xsD2AYAOqYOQzj2ByMgaw/hkbJ4dRkaopwIjYBUBwfbkAL6avkUq6uNVU11Paed2 - BetyABH1nRPYAnHJACEQICIRyBANBhIIiA7xgkCG8HZOZuwJF5YDj+D8tx8HGABr4AAt - hjj8FsEsOw+Al8P6gQMGoKABg7GUJsBIxMVcc0zqKkCTIunn3EPkrQAeR3VADQ8B4OuX - BEIEA4HCFaHk1HWLEgQ4t5lA1Znh+GoMbEH3+NXgQBB9AKBoGQewNBmjZH8M3qOyAAjQ - FGBEaYLwQD7lYBbFN8682d5CQIedI8234uT28G5AgIBBIEA8HaFa3lhHEI4gQ6xVF3J+ - P8BLk2Db9xpyAgQ9zh6xG8AAWAwh+CwCiHsfAUfH5RBeCQAQNBnifAUMrtIDkPAYpaw2 - pzbU9OYN4O7IgArlnh1cvsH3pkK54NGNpH4AB5+Ogw+401EHPRTo9UDeiMBweCAWAGHy - ASBgDCHuBgpOH8Gk+at2ACGWFAAiGeBoBGH2BeAAAq2wASeC48qM5oN4Hg3sBKe+vkQo - QMGkCSIEH2Hi5czw30p+5+f2IUPOHwHeIEJMAAFWF+H4FWCsD8HwCtAUq+BSIwBcGqFE - AUGg7SAa+yBoIeeQYWYeWqVeHoUYAAA2EC9Q9aQEH1BmAAGo3YT2AkzwSazWwKWqzQqK - WoHqG8GmHsAUAGH0AQBYC8HsBYGuHCH+GvB+meACGME2AgGUByBQH5CWAo40AUVCwI46 - r+HsaiAgC+IEAwC0QGHmGeIEG2DcQqN2AeTPBc28/0VOrqbU5QHsHaIEHaG+AAFMF2H2 - FMC2EEHyC3DyjgBKA4ACBUGyFMAWGoQgAYQ8Ay9OT2o0z47BA2wO7IIEAMB+IEA+X0QE - HUFgIEHIEbGOdCAY7m88rw34o42+YSHoG6GeHsASAGH2AOBSjUBSG2HIH+G3FigcGCEu - AgGMB8BYH41dEILu3cwQxpE+unGIowVixMAABMEqQGHGEhBovivkWiAQcmues6VU7+qK - cuIGHqHWIEHdFOFAFsH2FADCEOHyDDHYfABCAyACBOG6FSAXDwAMAWPWAw/OzSv6nGue - SatGjaL86IAABcFkQGG2DiIEHoGcL0AW90AMZsz4bKl2rk36eYYSliPeHoHAGcHsAQAE - H4AMBMgMBMG+HOJTJCcGF2EkAgGCCIBiH4/SAmxSAWAy4+lg/1DKSYc606HiHqIEBQss - KAbAOoGoCnBPFI/mcjKM4826s8Z05QIQHqHQOCHCAAE2FkH2E2DMEWHyDNK8ZKA6AsAC - BGHAFYAYG2AEAKASNyAy9a93ESxmrm/yTy9A3sA+ES5jAoNIH5LoAAGmCYbcAgWYp8Ig - hOl8kQMIljBYQ5JtKgGaHsQiPoBICwHsBIHGHUH+HHMqXgFoEaAgF0CWBsH4CKH+AkuQ - ACAYeHA0kXH4xcnIIGHsXbAqDWPG6eNIHqGwIEG0DUL1KMACAdDCx+xkeOVZLiME5oly - N8HoHKMeHiHGACEqFcH0EqDYEeH0/fOiUkAyAmACA+HIFeAYG9M+ASLsA1GSz2IAAACA - AA/4NAoJBIPCYS/4IAYHBodA4HCoLDoE+n3BAWTIIGzNDJFI5JJZNJ5E7V3BHGiIIBAF - BAYB4S/oTEYLAoxFpHGIhF4nOYtO5/PIuAHq4GU9wIAH6AhCVnsIXO7X+55RWa1W65Xa - 9X7BYbFY7JJFciQetCiOn6SwAEhbBAaHaNJp3DZLO7vN7xPH2/IIAxjBBCgLLh5E5k9B - HUp4IB6aAASBZrYL1KL3dYVPoi83C/wC8XIAUgqn0kDik30ccRrddr9hsdlYgsEACG3O - sgY4gEBARMQ0QYfMYdQbzIoXFZzQeVDOLOYpBH7gAA+wrBBOmdnYnAg4I8GHBMnBchAu - bJH/NqJy4PEPPBPVfPRzou/QA9nAyHuAX8/n+EIqqmdR4H+dTtwPBEEwVBYAFQQgHlcK - 4fn6KIAAiuIAAaD75uczjMsyk71vg+R/vsAB5uoFhXuHBiTmyNCCHubyZJoACYIezbjM - wvrkR5HaSJsfx5G+fwBHmcwBEUUp9EUO5MH0O8WylKcqSqAAJgcAALnSWYHHKAYCgMAY - AA0ISHzG9cQPons2JGirkqEkp5nsggSk4x4MSshZpiehR8oKBoEIEmLLM3HyHoi9LzR4 - 5SDxEhTAPwZB8H8flKhAKp6hAdp5AAdsrVBUNRLGUI/AcVAvCKfwrwsFlABFRcOIan04 - qyjCFoQzUOome0/gADo/rkGUrHydaCGwLscIIBwFR44r2qLWqjADW9HxNXM3varSHH6e - Btn8AZ6nQARClCfRCj4Th9D5Ud23dd6CAgBkrnWWoHHSAgCALMYNCKwMx2krdqLq56H0 - c+WEJtOLlHufSCAoMmHiVKx5mgghvD0l6KgXQSR4UkVGrxNOFx7XWSrynabHub5iHwfZ - 9n+fQPioeoPngegAHheGd55BZNDyBxQjKJR/C9CwVrkEllYCrdn0RNc1TVQ1cgAfLqAZ - icyDFKx2FqghykqggDUIBMa6Yvbnujk017PH9HoOfp3GofoBnudwBj+Tp8j+QRQH2QWe - 8DwTEAaBIAAgdpcAedYCgIAYCH+DQjUGyNtq/XDj6W57mMq6rqAJYYABBjMqnKTaCHaW - GxMi8aj5BWfNWrzWEzogzAIG6h/9yjcRoK6k4owfs6Huc51HyfB8n+ewPinmp5nvE/B+ - l6atEmOgGk0Ngnn+MvD6QAAHBMu2EKH8jl/NtiGPfRWlvUfqbACfgLoIExJSsb/AROZS - CgQygApiR6jooY/noLUV8P8fB0k6EFgSQR3gAGPtvKArEoRBn4HNIGPseY9R+AFH0PoA - gehMj5D0IcUg+xDvUhVCtjj4B3C4AgOwAwBQAgFH+BsJJ5jKNUUeh12ZfVGsjfhDx1x7 - y+k7HqiYFRjoKILGyGogg+RyEcAMQQATCh/DxOkPMhQ9SFMOh4rci0F1sk5iGTeMrVCG - H9aWyQgp9h8DpHkPkeg9R/jzUwpoesCYvQrj8zwRobgGCTDkFUAAbAAAPBUvGRcRVDpu - jErJzLJ31NTkoQQej0AAJ2bEBJBRCxor+Oqp8AADIHu8Oax+NLA1lPskuUYzkln0yPOS - TYfcc4Oj7HyAQOolR8h1EYKgfYjI/zFVEAmKoCx3i5AgO4A5lIqgcLcAAAUO4xQCZDG4 - 5C0D0E+kirFXDBSdMIj2QQD53gAALBSgofA5iCDOBsSMCS8yhrabRGhEUrkQHKWuTibD - sCJEInuoiLEUR1DyH0PAeY/h3oAKmw0AEmpjUTQWIUNIDBGh6C0AAOQ/wHTrACBFV0rW - PldakyVtL61tRoIVSVDg93eAXDSQQCIQEFDwGMQQawVjAkVWY08gtLo1ENPijhtE3FnI - /VzK59Eb04y3ZcAYfg+gChvEiPkN4khWD7ftRSrxspnmSmWBEd0yB/qCA2R4AAA2zI5q - GrapUk2mnQqXUIfR1AHhQIIBaniCR0CmYuHZsTAIWvtkeSVRrCnMVARKwsopyZ8wRJPK - whg/T7D6HYPQfY6x3j+HUCMK49gRj5I2r6r9pyyB+DGAsQwgQwABDy+AFFNAXohlm2wn - Ftk2xEcufCWI/2XkCAQDkggHA2oKHAIYgg5hLGPh2AomlASIIguoiGVSPGFLRdhUue0k - nOyVaqO9hoBx/D7AMGoRo+A1CXFgPwS9qL4FeX2AAA47xdARHeAu8jhgNhNMCoJtM3ag - NMlYh+ult2SXSpVUZqY+h0wOk8AAFcTEEDYJCAAdwtiCAKiqACGcbaiNPwVdV11Aq6Uu - h6UKbNQcRLQMuTyNg+7Mj7HMOwf45gShYHsCUfZ9oH3xyASMO4XAFB/EQGcARhgGgnII - BIGd37wQVVotOw8r5tWKJItFW7Ch+IGOrg+CEYB7gLIIDMZKChohHIIPUapcmOgDYAtG - xVJzmofyxG3EjJbH5zsni8kg+B3j2H0Ah3QBgyCIHwGQTotR+CdyDo+tZMQC32AkO8mY - /AFgBA4n0f4A3DXaiOdCk59IBSXglqVN51MuwOHQQqB5yj1Dxi8AEGo2DA1tNgMmdZTo - uPgcNNRgD5yJ4FpZixkeCsoomxSfPAN27Hn2KIwOyGPh2wcHEOgf44QThaHsCd95TtIW - oDgFcBQdxHhsAES4Br4krg1J7qOb7lrcNMrgAAfg7oHDji+iSoRDB5M4AAC4Xh4gRmwH - 1vgAAzbauuAes2JsQK3HnMzsSWRD87wUz9LO6RIqhRGghREdzyHDD8AOF8Qg+AviiFyP - wUW4aJgCIGAQdwuQJjuAeAkfYDQAAbQqjbhzJ5/Ym3rONN2zrtxrgWPocB8GcYjbXOIA - I9YFgjMWhYH5sB5jPIINQJzBllz0YOojjNSnZMgUSfbj0QbHdlsR2zEh/t7DuHoP0bo5 - R/jcBUFwewKu4b95c4EMwUAEBuEyHMAgkZSglYeDqw+BuvQVqaTyb/Ht7EEH1vre2YGA - lEqPqhGMmgNLBAABgLhsB1orAANwNzGiCgK0/Bi7ERc6ocLuiDjqiSgyx8ks/Yca2E2M - uyQMew7R7D4AUAEfoCAsiAHwFkVAvR+Co7+4MioAx2i5AoO0CICh8gP52FMggBZ6LSOT - Eaxa294EE1W1UcJCTqbSyn8C7xInkZNDDOa2Jrxx+IAAOSYjDxgBsrp7iBhDtxkR8zsa - 3ZqD+JqiyQzTZo6QmxboeofwbAcIfwa4FoLwe4FreL6ZdoMIJYBANITwPAAi5oBhpQf4 - CgHyoaCRtbKsBQhqMAfAbaN5nS6bKjULoripXSD48QIZ+i5o14bgOYggdYVS5wggBDDr - 87FUDx87LTPL3yH7KxD6e6C7eaWBQwezkL4wAT5IKgPge4KgVoYIfoVsD5d4AQdYW4Cg - dYCgBgfKTwDYKT8L7yuY47UozAjAfiUgfIbrVz+beiAMFzLL9SB7xQAAFoWQ2AaiQxE4 - ZA8TDpxsQ53qbUBJ4C6yxxRhR7PkKrfr+L8qlqN7aAeIe4fwaQbsVIGIMQe4wcNRUILA - IgA4MAU4P4AoT6dJpQAACw4TZDd4rhqROBEwfMGx3RYziSRz3SpkSzj5NkUY+BEwe5jo - GgZw2AZqeIAAfQrCdJGrOCbSer3qbccaHjvyI8UR8q7Q4ruDUCMyNTtQnjFbj4eodofD - MYAYfwBIJwO4e4JwWYYwfoWcWJKYAQdAWoCodIC4Bwe4ChMgKgx4CK3ZbLUpp0eC7BnR - qobQ+CBplC70YCHzoUeL8wjAeSPoGrNqtbn4sAfyMAZMXgoQBzX6t8kMkbAScbBRkKC0 - mh18dEYKNTsalKgC7qCBIIeUVAZobAf0bIMwe8bUghBIKQH4AwLIVoQgAywABZWEXpyb - Fi3q3QhgfQcTyzpcGSbcQbycm8eJ8ZE6BYFoXDDbdgsJlYggaEFokSn8PJOBgjPEHccx - NyNJgLArxwgUUMQbEJRYeodge7MYAkfQJIOge4JIXAZIfsuEqA2QAQcoWYCwcwDICAew - C426voAwCcKMnsZ7oZ3SBga4gQfodiH7jbfkcryCR8ebqDFSMptIeqTQEh05CxMwsQeA - YIgga70qagiIBjT81D3joRRjFTZ0tI+C7JqZaLtRtKxbaK68S8LR9j+DizaAeQfAf4Y4 - agfwY4HYNQe4HczA14JYHIAwKYWgRQAwVgAABQEAggC6HKcEwiyhRKM4hSTQe4aQ+CBb - eUjxWricizykKal5XwDYPoggDBowsQdAUYggb50hxzDbXAuzF825Dkiiobi7jzEkaKCr - jpNJRTLUKi8AegdQe4ewBgAwf4BQIgOAe4IgXoZofoXs9osgAIcQWACwcgDoCYewDRMi - voA468sy3hkofk2CiIawi4jdFrEE6pZzibo7Ubo1LUn8H4t4L6cwPYsYcAQoggc4TBsS - HZ/sHTjibypTWE2wmqorjAm9E7Ok7c71L4o7ANOgpxEwehhwYIZ4foYIIANwe6m1IAr4 - IYGYAoJQXgSAA4Wof4BJDYAIDLrq3SHqb4fIb7y0QNTxEhWkdMHptsPMmtLQjC4M+8II - AAE0IYsIbKmbDAWkJcShytUxg1OUsBtik870wNPL2TeL2ySBacK5WTKYeYdQfAewBtGo - BQHwNYewHwYYaQfw8NRwrIAIbwVoC4cAEICweoD1JcJZ+boskD2oggfDWw6qKddk3Dob - d6AUJzKcnJQxka3QfhEwATdgFoWIsYaStQeoaMJbACGghDyj3aVpD0vjojozFEBFZLEr - Kkw0nrjYy78rF5SzNZhwXgZgfgXgIoOIfCUVbokgHYFoAgIQYgSwBFH4BNc4AADLnsQj - 2UUiiNArezLz872dnKMMBVB1i8Hlo0GDGBhQfLhwGgZgsYZQFw6Qd7DbX4AdhrWETNYp - hbF5NUc5NrPcGMLZk1osTUeQgYeYdIfAeoBoA4f4BYHIM4ewHIZAawf0SVlQh4bIVQC4 - bgEwDIepWADUSABIDaR0m7yp5TrT5DfFjtXtpKbs2jo4zaIboL2FiLK1yiNSDYggG1eA - AZjorIfjgAZaRooQBbhxQkcNzVhsA5HUCEBrjquU09YVO8HNxycET8mxkVj7qJhwWwY4 - fgWwJYOwfCadRwGwFIAgHYZITQBAYgAABADgj6vskLEwiYfyBoe1p6CDgDzb9Ir0vdBU - n9zMtBEL+IebgAF9H4yTgorQeteAaUrooQBjMjojZbEs6VslsUZ9/FVVnNPrxr2kZi7J - qVZwfNtltwBYGgMgewGgZobMpczAAIaoVADAbAFQDYeh8QDKvoBQul/17LNbM6CFA7tj - jViETDKl8F61yZ2MKrilpIeyBYEwUBeMu4rIdwXQggbJiIf5QgAIBTn9VBXV8TzlZUGM - nbtKgCfF/ji9VVEa3LKJRTaL9xEweojYWIYYfgWIKAPQfCvUNQF4EgAQGgZ4T4BQZQAI - BADRagDYLckS7CBIf4erM4/l70tWF1rks8i8Hd3GFsv1EK7lytiwnce4ggDoQk/QLIrY - c7RwAAcAQIl5QgBF0JzdhmF9h0/svtpMZrecBljj3UrzPRN86iSye73LAb31tOBAmdGw - GAMIe4GEVUVLlwAIaAUgDAagF4D4eiRYDMSABYEMHqBCTFvGOlzGF0kGQFKF8uItZdQG - TOZxgIfJXwCU44DJ7orQcoSAxj6QAESq+jDtoUBdo82seU5o91ndBFYNLOUbjTA5zVjM - wS7dfwggewwAVYX4fgVYKwPwfF6q+IFQEAAQF4agUYBQZ4AIA4DIgYDlMl3JPyTAYqLs - vlT9E58l/S6mIjYUnmc8tiV6cKoAjSKJP9fmZwA9Xd/lZY4+QmdEBVr8Kzx8K8LMAlpE - wYlFr6ygh1tIfQeoBdGoBIFoL4ewFoawcAf9Kq04AIZgUIDAZ4GYEQegF4f4DMiAAIBc - RSNZXweuiiCDXtBOsNP1dsr+sSWjPx9b4NMGPloJt9PSxlEE5+AauKpM1CNk5lrZk+ji - oV8Rttebx6x+uLyw6ge4+wUwXYfYUwLYQQfOOCigEoDgAIFQbIU4Bgah/4CwgYDwMYno - wAf4el6A/iLSerEFBktePW08cmTEnBbTFdYVL2s+uVswheu46c6eQIitDjSI+WGKNzAs - 7Y52tVsYk1ErUKMhkVFgorWGU1/eu25hg9yV2gvFZwfYeoBSGwBAFLvQFIbYcgf8GyP4 - Y4ToDAZgHAEwegGYf4DGq4Bi2Z3oegY46TL0mswMwh87Bmc+KW2VVmZNMGJUmmjW4ExG - 2xqqA92dyAjBfNNqNoistetEn2QY82tNo+I+tjUdEu0zzuOM6rOkxAhYfgjAe4wAUIW4 - fYUIMAQwfIMCFQEWNoFAbgVIBgax/4CggYDoM6oAewZaByKbyTBG1GPUJy29L21+Tmsl - 1dw9pAfxEwfCBohYhYA1dQBSRoBZ74ATX7Nme4ald0stVQA5ju3V/+PPDk6uUvCi2+nc - TdsFPzKWTOGNoPNoo4eYdm6oBIpoA4EzbgEwb4c4f9URwQYITIDAYwHwFQei4gDD8BDK - kYe5iyBEQNy9P+eJDu4+PmZiAO1sKtYabfSuj98Bascuu+Q51wBYGAggEYRTDerQsAfd - qgAAb70Qdr1D84A5GucOALUliWvXClinBjeMc7ANssUWULsUvpOFOU2T9RhWwoAATYWQ - fYTYMwRYfLC5eAD2zIEgcAVoBkjYAoCYiAD4NbyxGaiLrVD8w8vzUyld8ikxt1FybNFH - IJhXUYf4yIDb1bnZGAgTYI2IdoW5i5KI6rhAhgBLN91XIpXWnCw1VedvAFjOKJ9WE+ur - FaykxG4IAAegdgfgew8oAoEi0IEgcQdQf8sZdoXYSgDAYIIgF4ekFoC7noBVJRE48Ih2 - mt8ethH2FmPXS4zG4Qu+4EBMaPJ73R479Q6gEpsJK8/hKge79oAAaSUR4RpfgqK1YmnJ - WVQNBLj2mNFzBHYetdsztuU9o4fXJgmwSwVwfYSwNYR4fPcRUADXb4EAcYWABobyaoB/ - G2znjAXw+CVHndBk6G/pNvI9xG2VoHnN82kAoWu9GQggCa/yTb/hd1C5i7/IhgAqHY8r - K+UGJ0sHhXOA9G5nMWusmtemmcTIy4egdfjYAomIAYEQqQEQcwqydxKYWwR4C4XYJIGg - eoIkXtToAJT5EpTsKV1ejHTnCXwe+8oGdKx6SayL+SH/iCNIfRXwAMPAFwXL8MiRnoaq - jYAAeIYRpYBV0MecHviqCcHK3GsmttfKulY/YypHSXYvBDrw9M2htHso0B5IgABSKrfS - ROCSfRwAELhkNh0PiERhoXCIBDjmWIOcICAoNAQACo2hb7c8PAMMf7/iQAlMLk8Llsrl - UymENmcRmM3l8smYBl8xm0MAM3oMOoFEoUwmb4e0LDJphYdOcrqlVq1XhbwYsLaxXlEL - BIIhYCnc7mc6m9npAAoc0hj+l1mr8spNvmsutcxnd0nkmtUunFzvU7uGAllwejsfj2Ac - nAIhKr2ELpd7/dNYzEOV6LCy1KA4exKAARG8sAdNn0Nn9ph9ou8quGOiFnmsqvdGmW0u - dsoz/2Op1tK3eEusRfz9hb3e8LEqVhYTJGZ6XTiL7eELZYsuYHA0LAgE1uFiXil9m8XF - oHB39U3102243mz4XBtlIwes1+1tk/lD5fh/AEfQAAERhTn0Rg6ksfQ6uoqoKAeAAMnS - WYIHIAQCAQj4IhCwz4Pooq7w83a+LlEcTN7D6cMK4D0vlFLhoW47kuWAAYF+hYEA9Bsd - x4ZocIWfJxoWAwCu88D4r5D61tUwqdRHJcVpQnqfvOuazLWtq+yQo8Otc16exA2bkHqd - p/OWuB/BAKp6hAdh4gAdkeIcVRDAqV4qh6e4oAABoQRwBz5xc3jdS3JclylLqiqJMEQr - 5Q0wpMlEVyour2odFiZn8wp8uQAAbGsuM5VEzJrC8rJeoWAsjgM7stJtRkYog4irS5JE - SUQ/K8Rc8z2K+nS9vwvVcNuux/HzTUAwGQ5Rn0Q49E0fQ9TkCIGpAdZaggc4B22AYAAm - Ezi1wiT7TBR8UKuvNDsFYdiUdSEX1zQr5nupoABkZMhgpUd9qsaAhoWexsVTVoC26w1h - N3dVY0ut9YQ8/D40tYFBRBcj1w63CUvfLElp3TqWntMp7n65B+A+Kh6g+d55gAd7qFIQ - ILFULYhHsKoAAYDSwAqwSVSc2csXFRVZUJV+DpavcrxjKdG4q9Dw17S7VuSeqFhMTyFg - iH9+a4hx+nwhZlBOmB+IWA4DoXbcur+u+lP2u1aY5E9eSSAFJp437y0zuWmvpLMW761e - L6+44Bn2AABkET59EEP5PH0P7MAeBYAAkdhbAgdQCW6AZ/gmFK2AEj9XaKwMk7dRdE19 - pFMYx0q5vJoEYKNKstqFoufr4fR8qcN6Fg2NWu+EAB5mghZpiZXQAASBUTqBEss6M+qs - bZW75JTvL54nJUQ+jhXvOE+9I7gmy4Hudp/nwfMBHxNU2Hjqs3qoTo+AmUYxCOfIuAAB - YMoWAsCyjXqnsYU3VQLpkwrmgSa13K73pEOdqh5qZd1NFjA+QsFosSxpFeGqIbweyFjo - FCkZIcHCcMQXMix2rbjVLDYUpY+DdDgKObulp6Lpm/wKPQlEr4/B7j/H6ARsoAw+ibHy - H0Qgoh9iEIiA0BIAAIDsFuA4dQBgCABSK58lgAVurtMOuhdT2DeIldOz1UK8YDH0YhGV - L5dYctRjY9InY+EaAYDQQsDxU4OnUHgMQrgWCHgIie9NqRMHYohYgeWCLCYapJkaW9Tp - wG/u3RcwgvpsD9m3Z8oN1ZcWmKuh47QAA+B3D/HyPZsCbGUJ+IgH0MACBCCCDGASED/X - /wBaO6s96HyhwFXS2s3MEo0upbrA2Q0Z3AQQUrDWZLPx/tlAA+shYKhWELAaDCPZVR+M - sAANFf80RzJDbQ4h0cLIyF5ke+Q4o/mHENlCYOY7TZNwzfK+OGz33qw6dOAFKrGm3gAM - XM8AhyACBqEaPh4JDwBjeFYA8b4IQLj9A6AACgKyXJHhafOZLsi3TEhPPZwEloHonb6o - eRb2lxLtkOpZSw/lqgABEIlrIQJskMHuN8hY3HfPEGcqmDgA4OPbYfMt10657HkjWlZc - UKVJRnUcrAvShHtpZnZUUlcoZhoxHkpoYQ0R+jCIgA4fIvwGjsAMAgA6RQJAoJ5LuSsB - VETzds3WQ6UjYq2edVBRTHWoPjYkiWZrT1zxsmekBsBIJAAAA+Hw7zlEGkxHQJ8hY4RD - oxRoAVVoBITVNkIZhiSIFZ0frxPF6JJ65T6bbUs9ytob0odW9lvsyl5MRIYNoao/RxAW - IrS9AZDAMj+GEAwcYAQDALJOBFcDC1Dl/mM0KBjFJKwOudGqBClGMRme68qqtrHyQTsI - p0fjhy2KAT4DMhYCqLP8vSAOQY9RqkLvcQsejxpRjeJc6MAsHABMGnhF+0ZD3apev63Z - dEjT8UqPFO27ryrA2pV22yYhZSlV3koREZozB+DeBgCQAUF1UkMA+PEXQDRpgOAWhhb1 - 6Y0sRwTGCYOAFKzuXDa5VzpqPLEhhYCT9T1BXek/DCjOQCYKdgqABkmQ25nlYMAN0boo - BEmutCzGc8YY3WozjVLtWLUV/bg61hdc3rOnWCw6qWMl5K/IWOQbw/R3F0sOABVoAAQj - FEwAwXIOqLQXAk6BxGccbVwgPW8t1sWh4MxtaC7Fo1anjsE7kolK5E4LnvUSf6SZnaRk - RMDSuAczX/qwsO1V/56q2tRpbB6gW9aJwroxvxL8itVAALEYY/BcEMowB4KQPgBh8FaI - UBIYQAAIAmSwBoHNRaLP0bKS5dNlYNv7jnQKl2fSPerF5QMzq6pN1Xd5WaXoETDx/BHH - 5PVCUiyuTeutUG2JZy9ivb+DJmQontautx+t6xpbcW2MRPrvHFn5Da1o5Bwj9HuBwCQA - gEhTD2PcMRxQLlkAAEQbgqQFiYBABkAICgAgOBAScA6EI1aAyxYPQq8D4Uez/YJiNSVX - Rkr2rJhNz5/q1cBCrlTQcAbxqdugla7dFt8ulzrTOm3upQ5uoKvXMcHQ2OMX6UY9TfAH - H6P8AI1hwD+HGC4L49wZEQAYQwGQLAQgCDKM0ToCgtX534AwDZQwDgS5nswqtG9A77RZ - y+5rzoHaO1RzLHi8MvbP6FYTdONJLc25JMjA+iMv6hnpOrTVQ9REoU6uO65u6V6ftXPS - AZdK72mKFv8ho9x6KaAGPwlWRx+g2DKPcMA1Bvj+FeRBgwAANkMCGEIGQAwvivEMAgHm - JouD/AGAfqgBgHEnAHnHa3I0RXZ2j5bd27249HdVdLbHio4cux70qz3fOl95+m9xHdJ+ - TfU/HqYiWUldmtH7OweQ8iUgP40AId38h8hUD4PgR4vxnh+hLCGByiqHmjmCGAgAQAMA - Agjg/AwADAbAtgjACAJEiPHqawLwMQMwNQNwOQOwPF9h9B9jfBShdB+BwhBBQB9BQBwB - 0B/hYCGBtqbCsLyKYCGLzCFgXlqM5AUgPgBALAQgMgBAGFVPJnhO6QPwkQkwlQlwmQNB - +GShvhzh/B2urB/Brh4B6AABliGKeiFr7CFpuEGwCgAALsQLfCGQaITHRwmw2Q2w3Q3w - 4Q2DxLxAAB5CGJwrJiGB1CGF6muPapBgAQxpxrevLw4xDRDxERExFO5nyHeGAQZCFvKx - FxJxKRKxLRLxMRMxNRNxOROxPRPxQRQxRRRxSRSxTRTxURUxVRVxWRWxXRXxYRYxZRZx - aRaxbRbxcRcxdRdxeRexfRfxgRgxhRhxiRixjRjxkRkxlRlxmRmxnRnxoRoxpRpxqRqx - rRrxsRsxtRtxuRuxvRvxwRwxxRxxyRyxzRzx0R0x1R1x2R2x3R3x4R4x5R5x6R6x7R7x - 8R8x9R9x+R+x/R/yASAyBSByCSCyDSDyESEyFSFyGSGyHSHyISIyJSJx4iAgAA8BAAAD - AAAAAQBxAAABAQADAAAAAQCZAAABAgADAAAABAAALO4BAwADAAAAAQAFAAABBgADAAAA - AQACAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAEAAABFgADAAAAAQEh - AAABFwAEAAAAAQAALCwBHAADAAAAAQABAAABPQADAAAAAQACAAABUgADAAAAAQABAAAB - UwADAAAABAAALPaHcwAHAAAD9AAALP4AAAAAAAgACAAIAAgAAQABAAEAAQAAA/RhcHBs - AgAAAG1udHJSR0IgWFlaIAfYAAEAHwAOACwAIGFjc3BBUFBMAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD21gABAAAAANMtYXBwbOoCxvvn7AuJW4CIyiOWp2wAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAADnJYWVoAAAEsAAAAFGdYWVoAAAFAAAAAFGJYWVoA - AAFUAAAAFHd0cHQAAAFoAAAAFGNoYWQAAAF8AAAALHJUUkMAAAGoAAAADmdUUkMAAAG4 - AAAADmJUUkMAAAHIAAAADnZjZ3QAAAHYAAAAMG5kaW4AAAIIAAAAOGRlc2MAAAJAAAAA - Z2RzY20AAAKoAAABAG1tb2QAAAOoAAAAKGNwcnQAAAPQAAAAJFhZWiAAAAAAAABxDgAA - OesAAAOdWFlaIAAAAAAAAF8vAACzygAAFlBYWVogAAAAAAAAJpgAABJgAAC5OVhZWiAA - AAAAAADzzwABAAAAARhic2YzMgAAAAAAAQwaAAAFwP//8v8AAAdgAAD9zv//+5j///2W - AAAD9AAAv05jdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAGN1cnYAAAAAAAAA - AQHNAAB2Y2d0AAAAAAAAAAEAANF0AAAAAAABAAAAANF0AAAAAAABAAAAANF0AAAAAAAB - AABuZGluAAAAAAAAADAAAKPAAABUgAAATMAAAJuAAAAm9wAAEXsAAFAAAABUAAACMzMA - AjMzAAIzM2Rlc2MAAAAAAAAADURFTEwgMjQwNUZQVwAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAbWx1YwAAAAAAAAASAAAADG5iTk8AAAAYAAAA6HB0UFQAAAAYAAAA6HN2 - U0UAAAAYAAAA6GZpRkkAAAAYAAAA6GRhREsAAAAYAAAA6HpoQ04AAAAYAAAA6GZyRlIA - AAAYAAAA6GphSlAAAAAYAAAA6GVuVVMAAAAYAAAA6HBsUEwAAAAYAAAA6HB0QlIAAAAY - AAAA6GVzRVMAAAAYAAAA6HpoVFcAAAAYAAAA6HJ1UlUAAAAYAAAA6GtvS1IAAAAYAAAA - 6GRlREUAAAAYAAAA6G5sTkwAAAAYAAAA6Gl0SVQAAAAYAAAA6ABEAEUATABMACAAMgA0 - ADAANQBGAFAAV21tb2QAAAAAAAAQrAAAoBAwNzNTv9zMAAAAAAAAAAAAAAAAAAAAAAB0 - ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOAA= - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - NO - SmartDistanceGuidesActive - NO - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{2002, 20}, {1215, 1180}} - ListView - - OutlineWidth - 142 - RightSidebar - - Sidebar - - SidebarWidth - 157 - VisibleRegion - {{-4.5, 0.5}, {522, 535.5}} - Zoom - 2 - ZoomValues - - - Canvas 1 - 2 - 4 - - - - saveQuickLookFiles - YES - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender-Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender-Info.plist deleted file mode 100644 index 976687e11..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDisplayName - ${EXECUTABLE_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - crash_report_sender - CFBundleIdentifier - com.Breakpad.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${EXECUTABLE_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - LSHasLocalizedDisplayName - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.h b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.h deleted file mode 100644 index 6a29d48a1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// This component uses the HTTPMultipartUpload of the breakpad project to send -// the minidump and associated data to the crash reporting servers. -// It will perform throttling based on the parameters passed to it and will -// prompt the user to send the minidump. - -#import - -#include "client/mac/sender/uploader.h" -#import "GTMDefines.h" - -// We're sublcassing NSTextField in order to override a particular -// method (see the implementation) that lets us reject changes if they -// are longer than a particular length. Bindings would normally solve -// this problem, but when we implemented a validation method, and -// returned NO for strings that were too long, the UI was not updated -// right away, which was a poor user experience. The UI would be -// updated as soon as the text field lost first responder status, -// which isn't soon enough. It is a known bug that the UI KVO didn't -// work in the middle of a validation. -@interface LengthLimitingTextField : NSTextField { - @private - NSUInteger maximumLength_; -} - -- (void)setMaximumLength:(NSUInteger)maxLength; -@end - -@interface Reporter : NSObject { - @public - IBOutlet NSWindow *alertWindow_; // The alert window - - // Grouping boxes used for resizing. - IBOutlet NSBox *headerBox_; - IBOutlet NSBox *preEmailBox_; - IBOutlet NSBox *emailSectionBox_; - // Localized elements (or things that need to be moved during localization). - IBOutlet NSTextField *dialogTitle_; - IBOutlet NSTextField *commentMessage_; - IBOutlet NSTextField *emailMessage_; - IBOutlet NSTextField *emailLabel_; - IBOutlet NSTextField *privacyLinkLabel_; - IBOutlet NSButton *sendButton_; - IBOutlet NSButton *cancelButton_; - IBOutlet LengthLimitingTextField *emailEntryField_; - IBOutlet LengthLimitingTextField *commentsEntryField_; - IBOutlet NSTextField *countdownLabel_; - IBOutlet NSView *privacyLinkArrow_; - - // Text field bindings, for user input. - NSString *commentsValue_; // Comments from the user - NSString *emailValue_; // Email from the user - NSString *countdownMessage_; // Message indicating time - // left for input. - @private - NSTimeInterval remainingDialogTime_; // Keeps track of how long - // we have until we cancel - // the dialog - NSTimer *messageTimer_; // Timer we use to update - // the dialog - Uploader* uploader_; // Uploader we use to send the data. -} - -// Stops the modal panel with an NSAlertDefaultReturn value. This is the action -// invoked by the "Send Report" button. -- (IBAction)sendReport:(id)sender; -// Stops the modal panel with an NSAlertAlternateReturn value. This is the -// action invoked by the "Cancel" button. -- (IBAction)cancel:(id)sender; -// Opens the Privacy Policy url in the default web browser. -- (IBAction)showPrivacyPolicy:(id)sender; - -// Delegate methods for the NSTextField for comments. We want to capture the -// Return key and use it to send the message when no text has been entered. -// Otherwise, we want Return to add a carriage return to the comments field. -- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView - doCommandBySelector:(SEL)commandSelector; - -// Accessors to make bindings work -- (NSString *)commentsValue; -- (void)setCommentsValue:(NSString *)value; - -- (NSString *)emailValue; -- (void)setEmailValue:(NSString *)value; - -- (NSString *)countdownMessage; -- (void)setCountdownMessage:(NSString *)value; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.icns b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.icns deleted file mode 100644 index e8c21242b..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.icns and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.m b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.m deleted file mode 100644 index 88d26fb03..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.m +++ /dev/null @@ -1,755 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import "client/mac/sender/crash_report_sender.h" - -#import -#import -#import -#import -#import - -#import "client/apple/Framework/BreakpadDefines.h" -#import "common/mac/GTMLogger.h" -#import "common/mac/HTTPMultipartUpload.h" - - -#define kLastSubmission @"LastSubmission" -const int kUserCommentsMaxLength = 1500; -const int kEmailMaxLength = 64; - -#define kApplePrefsSyncExcludeAllKey \ - @"com.apple.PreferenceSync.ExcludeAllSyncKeys" - -#pragma mark - - -@interface NSView (ResizabilityExtentions) -// Shifts the view vertically by the given amount. -- (void)breakpad_shiftVertically:(CGFloat)offset; - -// Shifts the view horizontally by the given amount. -- (void)breakpad_shiftHorizontally:(CGFloat)offset; -@end - -@implementation NSView (ResizabilityExtentions) -- (void)breakpad_shiftVertically:(CGFloat)offset { - NSPoint origin = [self frame].origin; - origin.y += offset; - [self setFrameOrigin:origin]; -} - -- (void)breakpad_shiftHorizontally:(CGFloat)offset { - NSPoint origin = [self frame].origin; - origin.x += offset; - [self setFrameOrigin:origin]; -} -@end - -@interface NSWindow (ResizabilityExtentions) -// Adjusts the window height by heightDelta relative to its current height, -// keeping all the content at the same size. -- (void)breakpad_adjustHeight:(CGFloat)heightDelta; -@end - -@implementation NSWindow (ResizabilityExtentions) -- (void)breakpad_adjustHeight:(CGFloat)heightDelta { - [[self contentView] setAutoresizesSubviews:NO]; - - NSRect windowFrame = [self frame]; - windowFrame.size.height += heightDelta; - [self setFrame:windowFrame display:YES]; - // For some reason the content view is resizing, but not adjusting its origin, - // so correct it manually. - [[self contentView] setFrameOrigin:NSMakePoint(0, 0)]; - - [[self contentView] setAutoresizesSubviews:YES]; -} -@end - -@interface NSTextField (ResizabilityExtentions) -// Grows or shrinks the height of the field to the minimum required to show the -// current text, preserving the existing width and origin. -// Returns the change in height. -- (CGFloat)breakpad_adjustHeightToFit; - -// Grows or shrinks the width of the field to the minimum required to show the -// current text, preserving the existing height and origin. -// Returns the change in width. -- (CGFloat)breakpad_adjustWidthToFit; -@end - -@implementation NSTextField (ResizabilityExtentions) -- (CGFloat)breakpad_adjustHeightToFit { - NSRect oldFrame = [self frame]; - // Starting with the 10.5 SDK, height won't grow, so make it huge to start. - NSRect presizeFrame = oldFrame; - presizeFrame.size.height = MAXFLOAT; - // sizeToFit will blow out the width rather than making the field taller, so - // we do it manually. - NSSize newSize = [[self cell] cellSizeForBounds:presizeFrame]; - NSRect newFrame = NSMakeRect(oldFrame.origin.x, oldFrame.origin.y, - NSWidth(oldFrame), newSize.height); - [self setFrame:newFrame]; - - return newSize.height - NSHeight(oldFrame); -} - -- (CGFloat)breakpad_adjustWidthToFit { - NSRect oldFrame = [self frame]; - [self sizeToFit]; - return NSWidth([self frame]) - NSWidth(oldFrame); -} -@end - -@interface NSButton (ResizabilityExtentions) -// Resizes to fit the label using IB-style size-to-fit metrics and enforcing a -// minimum width of 70, while preserving the right edge location. -// Returns the change in width. -- (CGFloat)breakpad_smartSizeToFit; -@end - -@implementation NSButton (ResizabilityExtentions) -- (CGFloat)breakpad_smartSizeToFit { - NSRect oldFrame = [self frame]; - [self sizeToFit]; - NSRect newFrame = [self frame]; - // sizeToFit gives much worse results that IB's Size to Fit option. This is - // the amount of padding IB adds over a sizeToFit, empirically determined. - const float kExtraPaddingAmount = 12; - const float kMinButtonWidth = 70; // The default button size in IB. - newFrame.size.width = NSWidth(newFrame) + kExtraPaddingAmount; - if (NSWidth(newFrame) < kMinButtonWidth) - newFrame.size.width = kMinButtonWidth; - // Preserve the right edge location. - newFrame.origin.x = NSMaxX(oldFrame) - NSWidth(newFrame); - [self setFrame:newFrame]; - return NSWidth(newFrame) - NSWidth(oldFrame); -} -@end - -#pragma mark - - -@interface Reporter(PrivateMethods) -- (id)initWithConfigFile:(const char *)configFile; - -// Returns YES if it has been long enough since the last report that we should -// submit a report for this crash. -- (BOOL)reportIntervalElapsed; - -// Returns YES if we should send the report without asking the user first. -- (BOOL)shouldSubmitSilently; - -// Returns YES if the minidump was generated on demand. -- (BOOL)isOnDemand; - -// Returns YES if we should ask the user to provide comments. -- (BOOL)shouldRequestComments; - -// Returns YES if we should ask the user to provide an email address. -- (BOOL)shouldRequestEmail; - -// Shows UI to the user to ask for permission to send and any extra information -// we've been instructed to request. Returns YES if the user allows the report -// to be sent. -- (BOOL)askUserPermissionToSend; - -// Returns the short description of the crash, suitable for use as a dialog -// title (e.g., "The application Foo has quit unexpectedly"). -- (NSString*)shortDialogMessage; - -// Return explanatory text about the crash and the reporter, suitable for the -// body text of a dialog. -- (NSString*)explanatoryDialogText; - -// Returns the amount of time the UI should be shown before timing out. -- (NSTimeInterval)messageTimeout; - -// Preps the comment-prompting alert window for display: -// * localizes all the elements -// * resizes and adjusts layout as necessary for localization -// * removes the email section if includeEmail is NO -- (void)configureAlertWindowIncludingEmail:(BOOL)includeEmail; - -// Rmevoes the email section of the dialog, adjusting the rest of the window -// as necessary. -- (void)removeEmailPrompt; - -// Run an alert window with the given timeout. Returns -// NSRunStoppedResponse if the timeout is exceeded. A timeout of 0 -// queues the message immediately in the modal run loop. -- (NSInteger)runModalWindow:(NSWindow*)window - withTimeout:(NSTimeInterval)timeout; - -// This method is used to periodically update the UI with how many -// seconds are left in the dialog display. -- (void)updateSecondsLeftInDialogDisplay:(NSTimer*)theTimer; - -// When we receive this notification, it means that the user has -// begun editing the email address or comments field, and we disable -// the timers so that the user has as long as they want to type -// in their comments/email. -- (void)controlTextDidBeginEditing:(NSNotification *)aNotification; - -- (void)report; - -@end - -@implementation Reporter -//============================================================================= -- (id)initWithConfigFile:(const char *)configFile { - if ((self = [super init])) { - remainingDialogTime_ = 0; - uploader_ = [[Uploader alloc] initWithConfigFile:configFile]; - if (!uploader_) { - [self release]; - return nil; - } - } - return self; -} - -//============================================================================= -- (BOOL)askUserPermissionToSend { - // Initialize Cocoa, needed to display the alert - NSApplicationLoad(); - - // Get the timeout value for the notification. - NSTimeInterval timeout = [self messageTimeout]; - - NSInteger buttonPressed = NSAlertAlternateReturn; - // Determine whether we should create a text box for user feedback. - if ([self shouldRequestComments]) { - BOOL didLoadNib = [NSBundle loadNibNamed:@"Breakpad" owner:self]; - if (!didLoadNib) { - return NO; - } - - [self configureAlertWindowIncludingEmail:[self shouldRequestEmail]]; - - buttonPressed = [self runModalWindow:alertWindow_ withTimeout:timeout]; - - // Extract info from the user into the uploader_. - if ([self commentsValue]) { - [[uploader_ parameters] setObject:[self commentsValue] - forKey:@BREAKPAD_COMMENTS]; - } - if ([self emailValue]) { - [[uploader_ parameters] setObject:[self emailValue] - forKey:@BREAKPAD_EMAIL]; - } - } else { - // Create an alert panel to tell the user something happened - NSPanel* alert = - NSGetAlertPanel([self shortDialogMessage], - @"%@", - NSLocalizedString(@"sendReportButton", @""), - NSLocalizedString(@"cancelButton", @""), - nil, - [self explanatoryDialogText]); - - // Pop the alert with an automatic timeout, and wait for the response - buttonPressed = [self runModalWindow:alert withTimeout:timeout]; - - // Release the panel memory - NSReleaseAlertPanel(alert); - } - return buttonPressed == NSAlertDefaultReturn; -} - -- (void)configureAlertWindowIncludingEmail:(BOOL)includeEmail { - // Swap in localized values, making size adjustments to impacted elements as - // we go. Remember that the origin is in the bottom left, so elements above - // "fall" as text areas are shrunk from their overly-large IB sizes. - - // Localize the header. No resizing needed, as it has plenty of room. - [dialogTitle_ setStringValue:[self shortDialogMessage]]; - - // Localize the explanatory text field. - [commentMessage_ setStringValue:[NSString stringWithFormat:@"%@\n\n%@", - [self explanatoryDialogText], - NSLocalizedString(@"commentsMsg", @"")]]; - CGFloat commentHeightDelta = [commentMessage_ breakpad_adjustHeightToFit]; - [headerBox_ breakpad_shiftVertically:commentHeightDelta]; - [alertWindow_ breakpad_adjustHeight:commentHeightDelta]; - - // Either localize the email explanation field or remove the whole email - // section depending on whether or not we are asking for email. - if (includeEmail) { - [emailMessage_ setStringValue:NSLocalizedString(@"emailMsg", @"")]; - CGFloat emailHeightDelta = [emailMessage_ breakpad_adjustHeightToFit]; - [preEmailBox_ breakpad_shiftVertically:emailHeightDelta]; - [alertWindow_ breakpad_adjustHeight:emailHeightDelta]; - } else { - [self removeEmailPrompt]; // Handles necessary resizing. - } - - // Localize the email label, and shift the associated text field. - [emailLabel_ setStringValue:NSLocalizedString(@"emailLabel", @"")]; - CGFloat emailLabelWidthDelta = [emailLabel_ breakpad_adjustWidthToFit]; - [emailEntryField_ breakpad_shiftHorizontally:emailLabelWidthDelta]; - - // Localize the privacy policy label, and keep it right-aligned to the arrow. - [privacyLinkLabel_ setStringValue:NSLocalizedString(@"privacyLabel", @"")]; - CGFloat privacyLabelWidthDelta = - [privacyLinkLabel_ breakpad_adjustWidthToFit]; - [privacyLinkLabel_ breakpad_shiftHorizontally:(-privacyLabelWidthDelta)]; - - // Ensure that the email field and the privacy policy link don't overlap. - CGFloat kMinControlPadding = 8; - CGFloat maxEmailFieldWidth = NSMinX([privacyLinkLabel_ frame]) - - NSMinX([emailEntryField_ frame]) - - kMinControlPadding; - if (NSWidth([emailEntryField_ bounds]) > maxEmailFieldWidth && - maxEmailFieldWidth > 0) { - NSSize emailSize = [emailEntryField_ frame].size; - emailSize.width = maxEmailFieldWidth; - [emailEntryField_ setFrameSize:emailSize]; - } - - // Localize the placeholder text. - [[commentsEntryField_ cell] - setPlaceholderString:NSLocalizedString(@"commentsPlaceholder", @"")]; - [[emailEntryField_ cell] - setPlaceholderString:NSLocalizedString(@"emailPlaceholder", @"")]; - - // Localize the buttons, and keep the cancel button at the right distance. - [sendButton_ setTitle:NSLocalizedString(@"sendReportButton", @"")]; - CGFloat sendButtonWidthDelta = [sendButton_ breakpad_smartSizeToFit]; - [cancelButton_ breakpad_shiftHorizontally:(-sendButtonWidthDelta)]; - [cancelButton_ setTitle:NSLocalizedString(@"cancelButton", @"")]; - [cancelButton_ breakpad_smartSizeToFit]; -} - -- (void)removeEmailPrompt { - [emailSectionBox_ setHidden:YES]; - CGFloat emailSectionHeight = NSHeight([emailSectionBox_ frame]); - [preEmailBox_ breakpad_shiftVertically:(-emailSectionHeight)]; - [alertWindow_ breakpad_adjustHeight:(-emailSectionHeight)]; -} - -- (NSInteger)runModalWindow:(NSWindow*)window - withTimeout:(NSTimeInterval)timeout { - // Queue a |stopModal| message to be performed in |timeout| seconds. - if (timeout > 0.001) { - remainingDialogTime_ = timeout; - SEL updateSelector = @selector(updateSecondsLeftInDialogDisplay:); - messageTimer_ = [NSTimer scheduledTimerWithTimeInterval:1.0 - target:self - selector:updateSelector - userInfo:nil - repeats:YES]; - } - - // Run the window modally and wait for either a |stopModal| message or a - // button click. - [NSApp activateIgnoringOtherApps:YES]; - NSInteger returnMethod = [NSApp runModalForWindow:window]; - - return returnMethod; -} - -- (IBAction)sendReport:(id)sender { - // Force the text fields to end editing so text for the currently focused - // field will be commited. - [alertWindow_ makeFirstResponder:alertWindow_]; - - [alertWindow_ orderOut:self]; - // Use NSAlertDefaultReturn so that the return value of |runModalWithWindow| - // matches the AppKit function NSRunAlertPanel() - [NSApp stopModalWithCode:NSAlertDefaultReturn]; -} - -// UI Button Actions -//============================================================================= -- (IBAction)cancel:(id)sender { - [alertWindow_ orderOut:self]; - // Use NSAlertDefaultReturn so that the return value of |runModalWithWindow| - // matches the AppKit function NSRunAlertPanel() - [NSApp stopModalWithCode:NSAlertAlternateReturn]; -} - -- (IBAction)showPrivacyPolicy:(id)sender { - // Get the localized privacy policy URL and open it in the default browser. - NSURL* privacyPolicyURL = - [NSURL URLWithString:NSLocalizedString(@"privacyPolicyURL", @"")]; - [[NSWorkspace sharedWorkspace] openURL:privacyPolicyURL]; -} - -// Text Field Delegate Methods -//============================================================================= -- (BOOL) control:(NSControl*)control - textView:(NSTextView*)textView -doCommandBySelector:(SEL)commandSelector { - BOOL result = NO; - // If the user has entered text on the comment field, don't end - // editing on "return". - if (control == commentsEntryField_ && - commandSelector == @selector(insertNewline:) - && [[textView string] length] > 0) { - [textView insertNewlineIgnoringFieldEditor:self]; - result = YES; - } - return result; -} - -- (void)controlTextDidBeginEditing:(NSNotification *)aNotification { - [messageTimer_ invalidate]; - [self setCountdownMessage:@""]; -} - -- (void)updateSecondsLeftInDialogDisplay:(NSTimer*)theTimer { - remainingDialogTime_ -= 1; - - NSString *countdownMessage; - NSString *formatString; - - int displayedTimeLeft; // This can be either minutes or seconds. - - if (remainingDialogTime_ > 59) { - // calculate minutes remaining for UI purposes - displayedTimeLeft = (int)(remainingDialogTime_ / 60); - - if (displayedTimeLeft == 1) { - formatString = NSLocalizedString(@"countdownMsgMinuteSingular", @""); - } else { - formatString = NSLocalizedString(@"countdownMsgMinutesPlural", @""); - } - } else { - displayedTimeLeft = (int)remainingDialogTime_; - if (displayedTimeLeft == 1) { - formatString = NSLocalizedString(@"countdownMsgSecondSingular", @""); - } else { - formatString = NSLocalizedString(@"countdownMsgSecondsPlural", @""); - } - } - countdownMessage = [NSString stringWithFormat:formatString, - displayedTimeLeft]; - if (remainingDialogTime_ <= 30) { - [countdownLabel_ setTextColor:[NSColor redColor]]; - } - [self setCountdownMessage:countdownMessage]; - if (remainingDialogTime_ <= 0) { - [messageTimer_ invalidate]; - [NSApp stopModal]; - } -} - - - -#pragma mark Accessors -#pragma mark - -//============================================================================= - -- (NSString *)commentsValue { - return [[commentsValue_ retain] autorelease]; -} - -- (void)setCommentsValue:(NSString *)value { - if (commentsValue_ != value) { - [commentsValue_ release]; - commentsValue_ = [value copy]; - } -} - -- (NSString *)emailValue { - return [[emailValue_ retain] autorelease]; -} - -- (void)setEmailValue:(NSString *)value { - if (emailValue_ != value) { - [emailValue_ release]; - emailValue_ = [value copy]; - } -} - -- (NSString *)countdownMessage { - return [[countdownMessage_ retain] autorelease]; -} - -- (void)setCountdownMessage:(NSString *)value { - if (countdownMessage_ != value) { - [countdownMessage_ release]; - countdownMessage_ = [value copy]; - } -} - -#pragma mark - -//============================================================================= -- (BOOL)reportIntervalElapsed { - float interval = [[[uploader_ parameters] - objectForKey:@BREAKPAD_REPORT_INTERVAL] floatValue]; - NSString *program = [[uploader_ parameters] objectForKey:@BREAKPAD_PRODUCT]; - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSMutableDictionary *programDict = - [NSMutableDictionary dictionaryWithDictionary:[ud dictionaryForKey:program]]; - NSNumber *lastTimeNum = [programDict objectForKey:kLastSubmission]; - NSTimeInterval lastTime = lastTimeNum ? [lastTimeNum floatValue] : 0; - NSTimeInterval now = CFAbsoluteTimeGetCurrent(); - NSTimeInterval spanSeconds = (now - lastTime); - - [programDict setObject:[NSNumber numberWithDouble:now] - forKey:kLastSubmission]; - [ud setObject:programDict forKey:program]; - [ud synchronize]; - - // If we've specified an interval and we're within that time, don't ask the - // user if we should report - GTMLoggerDebug(@"Reporter Interval: %f", interval); - if (interval > spanSeconds) { - GTMLoggerDebug(@"Within throttling interval, not sending report"); - return NO; - } - return YES; -} - -- (BOOL)isOnDemand { - return [[[uploader_ parameters] objectForKey:@BREAKPAD_ON_DEMAND] - isEqualToString:@"YES"]; -} - -- (BOOL)shouldSubmitSilently { - return [[[uploader_ parameters] objectForKey:@BREAKPAD_SKIP_CONFIRM] - isEqualToString:@"YES"]; -} - -- (BOOL)shouldRequestComments { - return [[[uploader_ parameters] objectForKey:@BREAKPAD_REQUEST_COMMENTS] - isEqualToString:@"YES"]; -} - -- (BOOL)shouldRequestEmail { - return [[[uploader_ parameters] objectForKey:@BREAKPAD_REQUEST_EMAIL] - isEqualToString:@"YES"]; -} - -- (NSString*)shortDialogMessage { - NSString *displayName = - [[uploader_ parameters] objectForKey:@BREAKPAD_PRODUCT_DISPLAY]; - if (![displayName length]) - displayName = [[uploader_ parameters] objectForKey:@BREAKPAD_PRODUCT]; - - if ([self isOnDemand]) { - // Local variable to pacify clang's -Wformat-extra-args. - NSString* format = NSLocalizedString(@"noCrashDialogHeader", @""); - return [NSString stringWithFormat:format, displayName]; - } else { - // Local variable to pacify clang's -Wformat-extra-args. - NSString* format = NSLocalizedString(@"crashDialogHeader", @""); - return [NSString stringWithFormat:format, displayName]; - } -} - -- (NSString*)explanatoryDialogText { - NSString *displayName = - [[uploader_ parameters] objectForKey:@BREAKPAD_PRODUCT_DISPLAY]; - if (![displayName length]) - displayName = [[uploader_ parameters] objectForKey:@BREAKPAD_PRODUCT]; - - NSString *vendor = [[uploader_ parameters] objectForKey:@BREAKPAD_VENDOR]; - if (![vendor length]) - vendor = @"unknown vendor"; - - if ([self isOnDemand]) { - // Local variable to pacify clang's -Wformat-extra-args. - NSString* format = NSLocalizedString(@"noCrashDialogMsg", @""); - return [NSString stringWithFormat:format, vendor, displayName]; - } else { - // Local variable to pacify clang's -Wformat-extra-args. - NSString* format = NSLocalizedString(@"crashDialogMsg", @""); - return [NSString stringWithFormat:format, vendor]; - } -} - -- (NSTimeInterval)messageTimeout { - // Get the timeout value for the notification. - NSTimeInterval timeout = [[[uploader_ parameters] - objectForKey:@BREAKPAD_CONFIRM_TIMEOUT] floatValue]; - // Require a timeout of at least a minute (except 0, which means no timeout). - if (timeout > 0.001 && timeout < 60.0) { - timeout = 60.0; - } - return timeout; -} - -- (void)report { - [uploader_ report]; -} - -//============================================================================= -- (void)dealloc { - [uploader_ release]; - [super dealloc]; -} - -- (void)awakeFromNib { - [emailEntryField_ setMaximumLength:kEmailMaxLength]; - [commentsEntryField_ setMaximumLength:kUserCommentsMaxLength]; -} - -@end - -//============================================================================= -@implementation LengthLimitingTextField - -- (void)setMaximumLength:(NSUInteger)maxLength { - maximumLength_ = maxLength; -} - -// This is the method we're overriding in NSTextField, which lets us -// limit the user's input if it makes the string too long. -- (BOOL) textView:(NSTextView *)textView -shouldChangeTextInRange:(NSRange)affectedCharRange - replacementString:(NSString *)replacementString { - - // Sometimes the range comes in invalid, so reject if we can't - // figure out if the replacement text is too long. - if (affectedCharRange.location == NSNotFound) { - return NO; - } - // Figure out what the new string length would be, taking into - // account user selections. - NSUInteger newStringLength = - [[textView string] length] - affectedCharRange.length + - [replacementString length]; - if (newStringLength > maximumLength_) { - return NO; - } else { - return YES; - } -} - -// Cut, copy, and paste have to be caught specifically since there is no menu. -- (BOOL)performKeyEquivalent:(NSEvent*)event { - // Only handle the key equivalent if |self| is the text field with focus. - NSText* fieldEditor = [self currentEditor]; - if (fieldEditor != nil) { - // Check for a single "Command" modifier - NSUInteger modifiers = [event modifierFlags]; - modifiers &= NSDeviceIndependentModifierFlagsMask; - if (modifiers == NSCommandKeyMask) { - // Now, check for Select All, Cut, Copy, or Paste key equivalents. - NSString* characters = [event characters]; - // Select All is Command-A. - if ([characters isEqualToString:@"a"]) { - [fieldEditor selectAll:self]; - return YES; - // Cut is Command-X. - } else if ([characters isEqualToString:@"x"]) { - [fieldEditor cut:self]; - return YES; - // Copy is Command-C. - } else if ([characters isEqualToString:@"c"]) { - [fieldEditor copy:self]; - return YES; - // Paste is Command-V. - } else if ([characters isEqualToString:@"v"]) { - [fieldEditor paste:self]; - return YES; - } - } - } - // Let the super class handle the rest (e.g. Command-Period will cancel). - return [super performKeyEquivalent:event]; -} - -@end - -//============================================================================= -int main(int argc, const char *argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -#if DEBUG - // Log to stderr in debug builds. - [GTMLogger setSharedLogger:[GTMLogger standardLoggerWithStderr]]; -#endif - GTMLoggerDebug(@"Reporter Launched, argc=%d", argc); - // The expectation is that there will be one argument which is the path - // to the configuration file - if (argc != 2) { - exit(1); - } - - Reporter *reporter = [[Reporter alloc] initWithConfigFile:argv[1]]; - if (!reporter) { - GTMLoggerDebug(@"reporter initialization failed"); - exit(1); - } - - // only submit a report if we have not recently crashed in the past - BOOL shouldSubmitReport = [reporter reportIntervalElapsed]; - BOOL okayToSend = NO; - - // ask user if we should send - if (shouldSubmitReport) { - if ([reporter shouldSubmitSilently]) { - GTMLoggerDebug(@"Skipping confirmation and sending report"); - okayToSend = YES; - } else { - okayToSend = [reporter askUserPermissionToSend]; - } - } - - // If we're running as root, switch over to nobody - if (getuid() == 0 || geteuid() == 0) { - struct passwd *pw = getpwnam("nobody"); - - // If we can't get a non-root uid, don't send the report - if (!pw) { - GTMLoggerDebug(@"!pw - %s", strerror(errno)); - exit(0); - } - - if (setgid(pw->pw_gid) == -1) { - GTMLoggerDebug(@"setgid(pw->pw_gid) == -1 - %s", strerror(errno)); - exit(0); - } - - if (setuid(pw->pw_uid) == -1) { - GTMLoggerDebug(@"setuid(pw->pw_uid) == -1 - %s", strerror(errno)); - exit(0); - } - } - else { - GTMLoggerDebug(@"getuid() !=0 || geteuid() != 0"); - } - - if (okayToSend && shouldSubmitReport) { - GTMLoggerDebug(@"Sending Report"); - [reporter report]; - GTMLoggerDebug(@"Report Sent!"); - } else { - GTMLoggerDebug(@"Not sending crash report okayToSend=%d, "\ - "shouldSubmitReport=%d", okayToSend, shouldSubmitReport); - } - - GTMLoggerDebug(@"Exiting with no errors"); - // Cleanup - [reporter release]; - [pool release]; - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/Localizable.strings deleted file mode 100644 index 2b8bb9693..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/da.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/InfoPlist.strings deleted file mode 100644 index 3180973ea..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/Localizable.strings deleted file mode 100644 index 73da36f48..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/de.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/InfoPlist.strings deleted file mode 100644 index a82c013e0..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/Localizable.strings deleted file mode 100644 index c31d6f48b..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/es.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/Localizable.strings deleted file mode 100644 index c32f8ff7a..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/fr.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/goArrow.png b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/goArrow.png deleted file mode 100644 index f318a5671..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/goArrow.png and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/Localizable.strings deleted file mode 100644 index a4b7fd3ac..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/it.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/Localizable.strings deleted file mode 100644 index 1f1a4fee5..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/ja.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/Localizable.strings deleted file mode 100644 index a4a54f759..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/nl.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/Localizable.strings deleted file mode 100644 index 725ef5a26..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/no.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/InfoPlist.strings deleted file mode 100644 index 585f6221d..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/Localizable.strings deleted file mode 100644 index b7dfeeceb..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sl.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/InfoPlist.strings deleted file mode 100644 index 4cfd32c54..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/Localizable.strings deleted file mode 100644 index f7d125166..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/sv.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/InfoPlist.strings deleted file mode 100644 index 088fb4f6c..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/Localizable.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/Localizable.strings deleted file mode 100644 index a82f990ed..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/tr.lproj/Localizable.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.h b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.h deleted file mode 100644 index 5f6aa464d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// This component uses the HTTPMultipartUpload of the breakpad project to send -// the minidump and associated data to the crash reporting servers. -// It will perform throttling based on the parameters passed to it and will -// prompt the user to send the minidump. - -#include - -#import "common/mac/GTMDefines.h" - -#define kClientIdPreferenceKey @"clientid" - -extern NSString *const kGoogleServerType; -extern NSString *const kSocorroServerType; -extern NSString *const kDefaultServerType; - -@interface Uploader : NSObject { - @private - NSMutableDictionary *parameters_; // Key value pairs of data (STRONG) - NSData *minidumpContents_; // The data in the minidump (STRONG) - NSData *logFileData_; // An NSdata for the tar, - // bz2'd log file. - NSMutableDictionary *serverDictionary_; // The dictionary mapping a - // server type name to a - // dictionary of server - // parameter names. - NSMutableDictionary *socorroDictionary_; // The dictionary for - // Socorro. - NSMutableDictionary *googleDictionary_; // The dictionary for - // Google. - NSMutableDictionary *extraServerVars_; // A dictionary containing - // extra key/value pairs - // that are uploaded to the - // crash server with the - // minidump. -} - -- (id)initWithConfigFile:(const char *)configFile; - -- (id)initWithConfig:(NSDictionary *)config; - -// Reads the file |configFile| and returns the corresponding NSDictionary. -// |configFile| will be deleted after reading. -+ (NSDictionary *)readConfigurationDataFromFile:(NSString *)configFile; - -- (NSMutableDictionary *)parameters; - -- (void)report; - -// Upload the given data to the crash server. -- (void)uploadData:(NSData *)data name:(NSString *)name; - -// This method adds a key/value pair to the dictionary that -// will be uploaded to the crash server. -- (void)addServerParameter:(id)value forKey:(NSString *)key; - -// This method process the HTTP response and renames the minidump file with the -// new ID. -- (void)handleNetworkResponse:(NSData *)data withError:(NSError *)error; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.mm deleted file mode 100644 index 42a43bfc3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/sender/uploader.mm +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import -#import -#include -#import - -#import - -#import "common/mac/HTTPMultipartUpload.h" - -#import "client/apple/Framework/BreakpadDefines.h" -#import "client/mac/sender/uploader.h" -#import "common/mac/GTMLogger.h" - -const int kMinidumpFileLengthLimit = 2 * 1024 * 1024; // 2MB - -#define kApplePrefsSyncExcludeAllKey \ - @"com.apple.PreferenceSync.ExcludeAllSyncKeys" - -NSString *const kGoogleServerType = @"google"; -NSString *const kSocorroServerType = @"socorro"; -NSString *const kDefaultServerType = @"google"; - -#pragma mark - - -namespace { -// Read one line from the configuration file. -NSString *readString(int fileId) { - NSMutableString *str = [NSMutableString stringWithCapacity:32]; - char ch[2] = { 0 }; - - while (read(fileId, &ch[0], 1) == 1) { - if (ch[0] == '\n') { - // Break if this is the first newline after reading some other string - // data. - if ([str length]) - break; - } else { - [str appendString:[NSString stringWithUTF8String:ch]]; - } - } - - return str; -} - -//============================================================================= -// Read |length| of binary data from the configuration file. This method will -// returns |nil| in case of error. -NSData *readData(int fileId, ssize_t length) { - NSMutableData *data = [NSMutableData dataWithLength:length]; - char *bytes = (char *)[data bytes]; - - if (read(fileId, bytes, length) != length) - return nil; - - return data; -} - -//============================================================================= -// Read the configuration from the config file. -NSDictionary *readConfigurationData(const char *configFile) { - int fileId = open(configFile, O_RDONLY, 0600); - if (fileId == -1) { - GTMLoggerDebug(@"Couldn't open config file %s - %s", - configFile, - strerror(errno)); - } - - // we want to avoid a build-up of old config files even if they - // have been incorrectly written by the framework - if (unlink(configFile)) { - GTMLoggerDebug(@"Couldn't unlink config file %s - %s", - configFile, - strerror(errno)); - } - - if (fileId == -1) { - return nil; - } - - NSMutableDictionary *config = [NSMutableDictionary dictionary]; - - while (1) { - NSString *key = readString(fileId); - - if (![key length]) - break; - - // Read the data. Try to convert to a UTF-8 string, or just save - // the data - NSString *lenStr = readString(fileId); - ssize_t len = [lenStr intValue]; - NSData *data = readData(fileId, len); - id value = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - - [config setObject:(value ? value : data) forKey:key]; - [value release]; - } - - close(fileId); - return config; -} -} // namespace - -#pragma mark - - -@interface Uploader(PrivateMethods) - -// Update |parameters_| as well as the server parameters using |config|. -- (void)translateConfigurationData:(NSDictionary *)config; - -// Read the minidump referenced in |parameters_| and update |minidumpContents_| -// with its content. -- (BOOL)readMinidumpData; - -// Read the log files referenced in |parameters_| and update |logFileData_| -// with their content. -- (BOOL)readLogFileData; - -// Returns a unique client id (user-specific), creating a persistent -// one in the user defaults, if necessary. -- (NSString*)clientID; - -// Returns a dictionary that can be used to map Breakpad parameter names to -// URL parameter names. -- (NSMutableDictionary *)dictionaryForServerType:(NSString *)serverType; - -// Helper method to set HTTP parameters based on server type. This is -// called right before the upload - crashParameters will contain, on exit, -// URL parameters that should be sent with the minidump. -- (BOOL)populateServerDictionary:(NSMutableDictionary *)crashParameters; - -// Initialization helper to create dictionaries mapping Breakpad -// parameters to URL parameters -- (void)createServerParameterDictionaries; - -// Accessor method for the URL parameter dictionary -- (NSMutableDictionary *)urlParameterDictionary; - -// Records the uploaded crash ID to the log file. -- (void)logUploadWithID:(const char *)uploadID; -@end - -@implementation Uploader - -//============================================================================= -- (id)initWithConfigFile:(const char *)configFile { - NSDictionary *config = readConfigurationData(configFile); - if (!config) - return nil; - - return [self initWithConfig:config]; -} - -//============================================================================= -- (id)initWithConfig:(NSDictionary *)config { - if ((self = [super init])) { - // Because the reporter is embedded in the framework (and many copies - // of the framework may exist) its not completely certain that the OS - // will obey the com.apple.PreferenceSync.ExcludeAllSyncKeys in our - // Info.plist. To make sure, also set the key directly if needed. - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - if (![ud boolForKey:kApplePrefsSyncExcludeAllKey]) { - [ud setBool:YES forKey:kApplePrefsSyncExcludeAllKey]; - } - - [self createServerParameterDictionaries]; - - [self translateConfigurationData:config]; - - // Read the minidump into memory. - [self readMinidumpData]; - [self readLogFileData]; - } - return self; -} - -//============================================================================= -+ (NSDictionary *)readConfigurationDataFromFile:(NSString *)configFile { - return readConfigurationData([configFile fileSystemRepresentation]); -} - -//============================================================================= -- (void)translateConfigurationData:(NSDictionary *)config { - parameters_ = [[NSMutableDictionary alloc] init]; - - NSEnumerator *it = [config keyEnumerator]; - while (NSString *key = [it nextObject]) { - // If the keyname is prefixed by BREAKPAD_SERVER_PARAMETER_PREFIX - // that indicates that it should be uploaded to the server along - // with the minidump, so we treat it specially. - if ([key hasPrefix:@BREAKPAD_SERVER_PARAMETER_PREFIX]) { - NSString *urlParameterKey = - [key substringFromIndex:[@BREAKPAD_SERVER_PARAMETER_PREFIX length]]; - if ([urlParameterKey length]) { - id value = [config objectForKey:key]; - if ([value isKindOfClass:[NSString class]]) { - [self addServerParameter:(NSString *)value - forKey:urlParameterKey]; - } else { - [self addServerParameter:(NSData *)value - forKey:urlParameterKey]; - } - } - } else { - [parameters_ setObject:[config objectForKey:key] forKey:key]; - } - } - - // generate a unique client ID based on this host's MAC address - // then add a key/value pair for it - NSString *clientID = [self clientID]; - [parameters_ setObject:clientID forKey:@"guid"]; -} - -// Per user per machine -- (NSString *)clientID { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSString *crashClientID = [ud stringForKey:kClientIdPreferenceKey]; - if (crashClientID) { - return crashClientID; - } - - // Otherwise, if we have no client id, generate one! - srandom((int)[[NSDate date] timeIntervalSince1970]); - long clientId1 = random(); - long clientId2 = random(); - long clientId3 = random(); - crashClientID = [NSString stringWithFormat:@"%lx%lx%lx", - clientId1, clientId2, clientId3]; - - [ud setObject:crashClientID forKey:kClientIdPreferenceKey]; - [ud synchronize]; - return crashClientID; -} - -//============================================================================= -- (BOOL)readLogFileData { -#if TARGET_OS_IPHONE - return NO; -#else - unsigned int logFileCounter = 0; - - NSString *logPath; - size_t logFileTailSize = - [[parameters_ objectForKey:@BREAKPAD_LOGFILE_UPLOAD_SIZE] intValue]; - - NSMutableArray *logFilenames; // An array of NSString, one per log file - logFilenames = [[NSMutableArray alloc] init]; - - char tmpDirTemplate[80] = "/tmp/CrashUpload-XXXXX"; - char *tmpDir = mkdtemp(tmpDirTemplate); - - // Construct key names for the keys we expect to contain log file paths - for(logFileCounter = 0;; logFileCounter++) { - NSString *logFileKey = [NSString stringWithFormat:@"%@%d", - @BREAKPAD_LOGFILE_KEY_PREFIX, - logFileCounter]; - - logPath = [parameters_ objectForKey:logFileKey]; - - // They should all be consecutive, so if we don't find one, assume - // we're done - - if (!logPath) { - break; - } - - NSData *entireLogFile = [[NSData alloc] initWithContentsOfFile:logPath]; - - if (entireLogFile == nil) { - continue; - } - - NSRange fileRange; - - // Truncate the log file, only if necessary - - if ([entireLogFile length] <= logFileTailSize) { - fileRange = NSMakeRange(0, [entireLogFile length]); - } else { - fileRange = NSMakeRange([entireLogFile length] - logFileTailSize, - logFileTailSize); - } - - char tmpFilenameTemplate[100]; - - // Generate a template based on the log filename - sprintf(tmpFilenameTemplate,"%s/%s-XXXX", tmpDir, - [[logPath lastPathComponent] fileSystemRepresentation]); - - char *tmpFile = mktemp(tmpFilenameTemplate); - - NSData *logSubdata = [entireLogFile subdataWithRange:fileRange]; - NSString *tmpFileString = [NSString stringWithUTF8String:tmpFile]; - [logSubdata writeToFile:tmpFileString atomically:NO]; - - [logFilenames addObject:[tmpFileString lastPathComponent]]; - [entireLogFile release]; - } - - if ([logFilenames count] == 0) { - [logFilenames release]; - logFileData_ = nil; - return NO; - } - - // now, bzip all files into one - NSTask *tarTask = [[NSTask alloc] init]; - - [tarTask setCurrentDirectoryPath:[NSString stringWithUTF8String:tmpDir]]; - [tarTask setLaunchPath:@"/usr/bin/tar"]; - - NSMutableArray *bzipArgs = [NSMutableArray arrayWithObjects:@"-cjvf", - @"log.tar.bz2",nil]; - [bzipArgs addObjectsFromArray:logFilenames]; - - [logFilenames release]; - - [tarTask setArguments:bzipArgs]; - [tarTask launch]; - [tarTask waitUntilExit]; - [tarTask release]; - - NSString *logTarFile = [NSString stringWithFormat:@"%s/log.tar.bz2",tmpDir]; - logFileData_ = [[NSData alloc] initWithContentsOfFile:logTarFile]; - if (logFileData_ == nil) { - GTMLoggerDebug(@"Cannot find temp tar log file: %@", logTarFile); - return NO; - } - return YES; -#endif // TARGET_OS_IPHONE -} - -//============================================================================= -- (BOOL)readMinidumpData { - NSString *minidumpDir = - [parameters_ objectForKey:@kReporterMinidumpDirectoryKey]; - NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey]; - - if (![minidumpID length]) - return NO; - - NSString *path = [minidumpDir stringByAppendingPathComponent:minidumpID]; - path = [path stringByAppendingPathExtension:@"dmp"]; - - // check the size of the minidump and limit it to a reasonable size - // before attempting to load into memory and upload - const char *fileName = [path fileSystemRepresentation]; - struct stat fileStatus; - - BOOL success = YES; - - if (!stat(fileName, &fileStatus)) { - if (fileStatus.st_size > kMinidumpFileLengthLimit) { - fprintf(stderr, "Breakpad Uploader: minidump file too large " \ - "to upload : %d\n", (int)fileStatus.st_size); - success = NO; - } - } else { - fprintf(stderr, "Breakpad Uploader: unable to determine minidump " \ - "file length\n"); - success = NO; - } - - if (success) { - minidumpContents_ = [[NSData alloc] initWithContentsOfFile:path]; - success = ([minidumpContents_ length] ? YES : NO); - } - - if (!success) { - // something wrong with the minidump file -- delete it - unlink(fileName); - } - - return success; -} - -#pragma mark - -//============================================================================= - -- (void)createServerParameterDictionaries { - serverDictionary_ = [[NSMutableDictionary alloc] init]; - socorroDictionary_ = [[NSMutableDictionary alloc] init]; - googleDictionary_ = [[NSMutableDictionary alloc] init]; - extraServerVars_ = [[NSMutableDictionary alloc] init]; - - [serverDictionary_ setObject:socorroDictionary_ forKey:kSocorroServerType]; - [serverDictionary_ setObject:googleDictionary_ forKey:kGoogleServerType]; - - [googleDictionary_ setObject:@"ptime" forKey:@BREAKPAD_PROCESS_UP_TIME]; - [googleDictionary_ setObject:@"email" forKey:@BREAKPAD_EMAIL]; - [googleDictionary_ setObject:@"comments" forKey:@BREAKPAD_COMMENTS]; - [googleDictionary_ setObject:@"prod" forKey:@BREAKPAD_PRODUCT]; - [googleDictionary_ setObject:@"ver" forKey:@BREAKPAD_VERSION]; - [googleDictionary_ setObject:@"guid" forKey:@"guid"]; - - [socorroDictionary_ setObject:@"Comments" forKey:@BREAKPAD_COMMENTS]; - [socorroDictionary_ setObject:@"CrashTime" - forKey:@BREAKPAD_PROCESS_CRASH_TIME]; - [socorroDictionary_ setObject:@"StartupTime" - forKey:@BREAKPAD_PROCESS_START_TIME]; - [socorroDictionary_ setObject:@"Version" - forKey:@BREAKPAD_VERSION]; - [socorroDictionary_ setObject:@"ProductName" - forKey:@BREAKPAD_PRODUCT]; - [socorroDictionary_ setObject:@"Email" - forKey:@BREAKPAD_EMAIL]; -} - -- (NSMutableDictionary *)dictionaryForServerType:(NSString *)serverType { - if (serverType == nil || [serverType length] == 0) { - return [serverDictionary_ objectForKey:kDefaultServerType]; - } - return [serverDictionary_ objectForKey:serverType]; -} - -- (NSMutableDictionary *)urlParameterDictionary { - NSString *serverType = [parameters_ objectForKey:@BREAKPAD_SERVER_TYPE]; - return [self dictionaryForServerType:serverType]; - -} - -- (BOOL)populateServerDictionary:(NSMutableDictionary *)crashParameters { - NSDictionary *urlParameterNames = [self urlParameterDictionary]; - - id key; - NSEnumerator *enumerator = [parameters_ keyEnumerator]; - - while ((key = [enumerator nextObject])) { - // The key from parameters_ corresponds to a key in - // urlParameterNames. The value in parameters_ gets stored in - // crashParameters with a key that is the value in - // urlParameterNames. - - // For instance, if parameters_ has [PRODUCT_NAME => "FOOBAR"] and - // urlParameterNames has [PRODUCT_NAME => "pname"] the final HTTP - // URL parameter becomes [pname => "FOOBAR"]. - NSString *breakpadParameterName = (NSString *)key; - NSString *urlParameter = [urlParameterNames - objectForKey:breakpadParameterName]; - if (urlParameter) { - [crashParameters setObject:[parameters_ objectForKey:key] - forKey:urlParameter]; - } - } - - // Now, add the parameters that were added by the application. - enumerator = [extraServerVars_ keyEnumerator]; - - while ((key = [enumerator nextObject])) { - NSString *urlParameterName = (NSString *)key; - NSString *urlParameterValue = - [extraServerVars_ objectForKey:urlParameterName]; - [crashParameters setObject:urlParameterValue - forKey:urlParameterName]; - } - return YES; -} - -- (void)addServerParameter:(id)value forKey:(NSString *)key { - [extraServerVars_ setObject:value forKey:key]; -} - -//============================================================================= -- (void)handleNetworkResponse:(NSData *)data withError:(NSError *)error { - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - const char *reportID = "ERR"; - if (error) { - fprintf(stderr, "Breakpad Uploader: Send Error: %s\n", - [[error description] UTF8String]); - } else { - NSCharacterSet *trimSet = - [NSCharacterSet whitespaceAndNewlineCharacterSet]; - reportID = [[result stringByTrimmingCharactersInSet:trimSet] UTF8String]; - [self logUploadWithID:reportID]; - } - - // rename the minidump file according to the id returned from the server - NSString *minidumpDir = - [parameters_ objectForKey:@kReporterMinidumpDirectoryKey]; - NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey]; - - NSString *srcString = [NSString stringWithFormat:@"%@/%@.dmp", - minidumpDir, minidumpID]; - NSString *destString = [NSString stringWithFormat:@"%@/%s.dmp", - minidumpDir, reportID]; - - const char *src = [srcString fileSystemRepresentation]; - const char *dest = [destString fileSystemRepresentation]; - - if (rename(src, dest) == 0) { - GTMLoggerInfo(@"Breakpad Uploader: Renamed %s to %s after successful " \ - "upload",src, dest); - } - else { - // can't rename - don't worry - it's not important for users - GTMLoggerDebug(@"Breakpad Uploader: successful upload report ID = %s\n", - reportID ); - } - [result release]; -} - -//============================================================================= -- (void)report { - NSURL *url = [NSURL URLWithString:[parameters_ objectForKey:@BREAKPAD_URL]]; - HTTPMultipartUpload *upload = [[HTTPMultipartUpload alloc] initWithURL:url]; - NSMutableDictionary *uploadParameters = [NSMutableDictionary dictionary]; - - if (![self populateServerDictionary:uploadParameters]) { - [upload release]; - return; - } - - [upload setParameters:uploadParameters]; - - // Add minidump file - if (minidumpContents_) { - [upload addFileContents:minidumpContents_ name:@"upload_file_minidump"]; - - // If there is a log file, upload it together with the minidump. - if (logFileData_) { - [upload addFileContents:logFileData_ name:@"log"]; - } - - // Send it - NSError *error = nil; - NSData *data = [upload send:&error]; - - if (![url isFileURL]) { - [self handleNetworkResponse:data withError:error]; - } else { - if (error) { - fprintf(stderr, "Breakpad Uploader: Error writing request file: %s\n", - [[error description] UTF8String]); - } - } - - } else { - // Minidump is missing -- upload just the log file. - if (logFileData_) { - [self uploadData:logFileData_ name:@"log"]; - } - } - [upload release]; -} - -- (void)uploadData:(NSData *)data name:(NSString *)name { - NSURL *url = [NSURL URLWithString:[parameters_ objectForKey:@BREAKPAD_URL]]; - NSMutableDictionary *uploadParameters = [NSMutableDictionary dictionary]; - - if (![self populateServerDictionary:uploadParameters]) - return; - - HTTPMultipartUpload *upload = - [[HTTPMultipartUpload alloc] initWithURL:url]; - - [uploadParameters setObject:name forKey:@"type"]; - [upload setParameters:uploadParameters]; - [upload addFileContents:data name:name]; - - [upload send:nil]; - [upload release]; -} - -- (void)logUploadWithID:(const char *)uploadID { - NSString *minidumpDir = - [parameters_ objectForKey:@kReporterMinidumpDirectoryKey]; - NSString *logFilePath = [NSString stringWithFormat:@"%@/%s", - minidumpDir, kReporterLogFilename]; - NSString *logLine = [NSString stringWithFormat:@"%0.f,%s\n", - [[NSDate date] timeIntervalSince1970], uploadID]; - NSData *logData = [logLine dataUsingEncoding:NSUTF8StringEncoding]; - - NSFileManager *fileManager = [NSFileManager defaultManager]; - if ([fileManager fileExistsAtPath:logFilePath]) { - NSFileHandle *logFileHandle = - [NSFileHandle fileHandleForWritingAtPath:logFilePath]; - [logFileHandle seekToEndOfFile]; - [logFileHandle writeData:logData]; - [logFileHandle closeFile]; - } else { - [fileManager createFileAtPath:logFilePath - contents:logData - attributes:nil]; - } -} - -//============================================================================= -- (NSMutableDictionary *)parameters { - return parameters_; -} - -//============================================================================= -- (void)dealloc { - [parameters_ release]; - [minidumpContents_ release]; - [logFileData_ release]; - [googleDictionary_ release]; - [socorroDictionary_ release]; - [serverDictionary_ release]; - [extraServerVars_ release]; - [super dealloc]; -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.h b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.h deleted file mode 100644 index 7b3be2d69..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import - -#import - -enum BreakpadForkBehavior { - DONOTHING = 0, - UNINSTALL, - RESETEXCEPTIONPORT -}; - -enum BreakpadForkTestCrashPoint { - DURINGLAUNCH = 5, - AFTERLAUNCH = 6, - BETWEENFORKEXEC = 7 -}; - -@interface Controller : NSObject { - IBOutlet NSWindow *window_; - IBOutlet NSWindow *forkTestOptions_; - - BreakpadRef breakpad_; - - enum BreakpadForkBehavior bpForkOption; - - BOOL useVFork; - enum BreakpadForkTestCrashPoint progCrashPoint; -} - -- (IBAction)crash:(id)sender; -- (IBAction)forkTestOptions:(id)sender; -- (IBAction)forkTestGo:(id)sender; -- (IBAction)showForkTestWindow:(id) sender; -- (void)generateReportWithoutCrash:(id)sender; -- (void)awakeFromNib; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.m b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.m deleted file mode 100644 index 87c43024b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.m +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import - -#import "Controller.h" -#import "TestClass.h" -#import "GTMDefines.h" -#include -#include - -@implementation Controller - -- (void)causeCrash { - float *aPtr = nil; - NSLog(@"Crash!"); - NSLog(@"Bad programmer: %f", *aPtr); -} - -- (void)generateReportWithoutCrash:(id)sender { - BreakpadGenerateAndSendReport(breakpad_); -} - -- (IBAction)showForkTestWindow:(id) sender { - [forkTestOptions_ setIsVisible:YES]; -} - -- (IBAction)forkTestOptions:(id)sender { - NSInteger tag = [[sender selectedCell] tag]; - NSLog(@"sender tag: %d", tag); - if (tag <= 2) { - bpForkOption = tag; - } - - if (tag == 3) { - useVFork = NO; - } - - if (tag == 4) { - useVFork = YES; - } - - if (tag >= 5 && tag <= 7) { - progCrashPoint = tag; - } - -} - -- (IBAction)forkTestGo:(id)sender { - - NSString *resourcePath = [[NSBundle bundleForClass: - [self class]] resourcePath]; - NSString *execProgname = nil; - if (progCrashPoint == DURINGLAUNCH) { - execProgname = [resourcePath stringByAppendingString:@"/crashduringload"]; - } else if (progCrashPoint == AFTERLAUNCH) { - execProgname = [resourcePath stringByAppendingString:@"/crashInMain"]; - } - - const char *progName = NULL; - if (progCrashPoint != BETWEENFORKEXEC) { - progName = [execProgname UTF8String]; - } - - int pid; - - if (bpForkOption == UNINSTALL) { - BreakpadRelease(breakpad_); - } - - if (useVFork) { - pid = vfork(); - } else { - pid = fork(); - } - - if (pid == 0) { - sleep(3); - NSLog(@"Child continuing"); - FILE *fd = fopen("/tmp/childlog.txt","wt"); - kern_return_t kr; - if (bpForkOption == RESETEXCEPTIONPORT) { - kr = task_set_exception_ports(mach_task_self(), - EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | - EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT, - MACH_PORT_NULL, - EXCEPTION_DEFAULT, - THREAD_STATE_NONE); - fprintf(fd,"task_set_exception_ports returned %d\n", kr); - } - - if (progCrashPoint == BETWEENFORKEXEC) { - fprintf(fd,"crashing post-fork\n"); - int *a = NULL; - printf("%d\n",*a++); - } - - fprintf(fd,"about to call exec with %s\n", progName); - fclose(fd); - int i = execl(progName, progName, NULL); - fprintf(fd, "exec returned! %d\n", i); - fclose(fd); - } -} - -- (IBAction)crash:(id)sender { - NSInteger tag = [sender tag]; - - if (tag == 1) { - [NSObject cancelPreviousPerformRequestsWithTarget:self]; - [self performSelector:@selector(causeCrash) withObject:nil afterDelay:10.0]; - [sender setState:NSOnState]; - return; - } - - if (tag == 2 && breakpad_) { - BreakpadRelease(breakpad_); - breakpad_ = NULL; - return; - } - - [self causeCrash]; -} - -- (void)anotherThread { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - TestClass *tc = [[TestClass alloc] init]; - - [tc wait]; - - [pool release]; -} - -- (void)awakeFromNib { - NSBundle *bundle = [NSBundle mainBundle]; - NSDictionary *info = [bundle infoDictionary]; - - - breakpad_ = BreakpadCreate(info); - - // Do some unit tests with keys - // first a series of bogus values - BreakpadSetKeyValue(breakpad_, nil, @"bad2"); - BreakpadSetKeyValue(nil, @"bad3", @"bad3"); - - // Now some good ones - BreakpadSetKeyValue(breakpad_,@"key1", @"value1"); - BreakpadSetKeyValue(breakpad_,@"key2", @"value2"); - BreakpadSetKeyValue(breakpad_,@"key3", @"value3"); - - // Look for a bogus one that we didn't try to set - NSString *test = BreakpadKeyValue(breakpad_, @"bad4"); - if (test) { - NSLog(@"Bad BreakpadKeyValue (bad4)"); - } - - // Look for a bogus one we did try to set - test = BreakpadKeyValue(breakpad_, @"bad1"); - if (test) { - NSLog(@"Bad BreakpadKeyValue (bad1)"); - } - - // Test some bad args for BreakpadKeyValue - test = BreakpadKeyValue(nil, @"bad5"); - if (test) { - NSLog(@"Bad BreakpadKeyValue (bad5)"); - } - - test = BreakpadKeyValue(breakpad_, nil); - if (test) { - NSLog(@"Bad BreakpadKeyValue (nil)"); - } - - // Find some we did set - test = BreakpadKeyValue(breakpad_, @"key1"); - if (![test isEqualToString:@"value1"]) { - NSLog(@"Can't find BreakpadKeyValue (key1)"); - } - test = BreakpadKeyValue(breakpad_, @"key2"); - if (![test isEqualToString:@"value2"]) { - NSLog(@"Can't find BreakpadKeyValue (key2)"); - } - test = BreakpadKeyValue(breakpad_, @"key3"); - if (![test isEqualToString:@"value3"]) { - NSLog(@"Can't find BreakpadKeyValue (key3)"); - } - - // Bad args for BreakpadRemoveKeyValue - BreakpadRemoveKeyValue(nil, @"bad6"); - BreakpadRemoveKeyValue(breakpad_, nil); - - // Remove one that is valid - BreakpadRemoveKeyValue(breakpad_, @"key3"); - - // Try and find it - test = BreakpadKeyValue(breakpad_, @"key3"); - if (test) { - NSLog(@"Shouldn't find BreakpadKeyValue (key3)"); - } - - // Try and remove it again - BreakpadRemoveKeyValue(breakpad_, @"key3"); - - // Try removal by setting to nil - BreakpadSetKeyValue(breakpad_,@"key2", nil); - // Try and find it - test = BreakpadKeyValue(breakpad_, @"key2"); - if (test) { - NSLog(@"Shouldn't find BreakpadKeyValue (key2)"); - } - - BreakpadAddUploadParameter(breakpad_, - @"MeaningOfLife", - @"42"); - [NSThread detachNewThreadSelector:@selector(anotherThread) - toTarget:self withObject:nil]; - - NSUserDefaults *args = [NSUserDefaults standardUserDefaults]; - - // If the user specified autocrash on the command line, toggle - // Breakpad to not confirm and crash immediately. This is for - // automated testing. - if ([args boolForKey:@"autocrash"]) { - BreakpadSetKeyValue(breakpad_, - @BREAKPAD_SKIP_CONFIRM, - @"YES"); - [self causeCrash]; - } - - progCrashPoint = DURINGLAUNCH; - [window_ center]; - [window_ makeKeyAndOrderFront:self]; -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/InfoPlist.strings b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/InfoPlist.strings deleted file mode 100644 index b8c6c6bf0..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/MainMenu.xib b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/MainMenu.xib deleted file mode 100644 index 840c0db33..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/English.lproj/MainMenu.xib +++ /dev/null @@ -1,3748 +0,0 @@ - - - - 1050 - 10F569 - 788 - 1038.29 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 788 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - - NSApplication - - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{945, 874}, {320, 188}} - 1886912512 - Window - NSWindow - - View - - {1.79769e+308, 1.79769e+308} - {213, 107} - - - 256 - - YES - - - 301 - {{14, 140}, {292, 32}} - - - YES - - 67239424 - 134217728 - Crash! (Airbag Installed) - - LucidaGrande - 13 - 1044 - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 301 - {{14, 76}, {292, 32}} - - - 2 - YES - - 67239424 - 134217728 - Crash! (Airbag NOT Installed) - - - 2 - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 301 - {{14, 108}, {292, 32}} - - - 1 - YES - - 67239424 - 134217728 - Crash! (Airbag Installed w/10sec delay) - - - 1 - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 268 - {{14, 44}, {292, 32}} - - - YES - - 67239424 - 134217728 - Fork Test - - - -2038284033 - 129 - - - 200 - 25 - - - - - 268 - {{14, 12}, {292, 32}} - - - YES - - 67239424 - 134217728 - Generate report without crash - - - -2038284033 - 129 - - - 200 - 25 - - - - {320, 188} - - - - {{0, 0}, {1440, 878}} - {213, 129} - {1.79769e+308, 1.79769e+308} - - - MainMenu - - YES - - - NewApplication - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - NewApplication - - YES - - - About NewApplication - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - - Services - - - YES - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide NewApplication - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit NewApplication - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - - File - - - YES - - - New - n - 1048576 - 2147483647 - - - - - - Open... - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - - Open Recent - - - YES - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save - s - 1048576 - 2147483647 - - - - - - Save As… - S - 1048576 - 2147483647 - - - - - - Revert - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup… - P - 1048576 - 2147483647 - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - - Edit - - - YES - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - - Find - - - YES - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1048576 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling - - 1048576 - 2147483647 - - - submenuAction: - - Spelling - - YES - - - Spelling… - : - 1048576 - 2147483647 - - - - - - Check Spelling - ; - 1048576 - 2147483647 - - - - - - Check Spelling as You Type - - 1048576 - 2147483647 - - - - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - - Window - - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 1048576 - 2147483647 - - - submenuAction: - - Help - - YES - - - NewApplication Help - ? - 1048576 - 2147483647 - - - - - - - - _NSMainMenu - - - Controller - - - 15 - 2 - {{858, 755}, {787, 260}} - 603979776 - Window - NSWindow - - {1.79769e+308, 1.79769e+308} - - - 256 - - YES - - - 268 - {{20, 7}, {645, 79}} - - YES - 3 - 1 - - YES - - -2080244224 - 0 - program crashes during launch because of missing dylib - - - 5 - 1211912703 - 0 - - NSRadioButton - - - - 200 - 25 - - - 67239424 - 0 - program crashes after launch - - - 6 - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAwYAAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAMGGFw -cGwCAAAAbW50clJHQiBYWVogB9YABAADABMALAASYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA -AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAMSbmRpbgAA -BOwAAAY+ZGVzYwAACywAAABkZHNjbQAAC5AAAAAubW1vZAAAC8AAAAAoY3BydAAAC+gAAAAtWFlaIAAA -AAAAAF1KAAA0kQAACCVYWVogAAAAAAAAdCAAALRgAAAjPVhZWiAAAAAAAAAlbAAAFyoAAKfDWFlaIAAA -AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 -cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD -AQAAAQACBAUGBwkKCw0ODxASExQWFxgaGxweHyAiIyQmJygpKywtLzAxMjM1Njc4OTs8PT5AQUJDREZH -SElKS0xOT1BRUlNUVVZXWFlaW1xdXl9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SF -hoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnZ6foKGio6SlpqanqKmqq6ytra6vsLGysrO0tba3uLi5uru8 -vL2+v8DBwcLDxMXGxsfIycrKy8zNzs7P0NHS0tPU1dbW19jZ2drb3Nzd3t/g4eLi4+Tl5ufo6enq6+zt -7u/w8fHy8/T19vf4+fr7/P3+/v8AAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR8gISIjJCUnKCkq -Ky0uLzAxMzQ1Njc4OTo7PD0/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaWltcXV5fYGFiY2RlZmdo -aWprbG1ub3BxcnN0dXZ3d3h5ent8fH1+f4CBgoKDhIWGh4iIiYqLjI2Oj5CRkpOUlJWWl5iZmpucnZ2e -n6ChoqOkpaamp6ipqqusra6vsLCxsrO0tba3uLm5uru8vb6/wMHCw8TFx8jJysvMzc7P0NDR0tPU1dbX -2Nna29ze3+Dh4uPk5ebn6err7O3u7/Hy8/T19vf5+vv8/f7/AAIDAwQFBgcICQoKCwwNDg8QERITFBUW -FxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODg5Ojs8PT4+P0BBQkNDREVGR0hJSUpLTE1O -Tk9QUVJSU1RVVVZXWFhZWltbXF1eXl9gYWFiY2RkZWZnZ2hpaWprbGxtbm5vcHFxcnNzdHV1dnd4eHl6 -ent8fH1+fn+AgYGCg4SEhYaHiImJiouMjY6Oj5CRkpOTlJWWl5iZmZqbnJ2en6ChoqOkpaanqKmqq6yt -rq+xsrO0tba3uLq7vL2+wMHDxMbHycrMzs/R0tTW19nb3d7g4uTm6Ors7vDy9Pb4+vz+/wAAbmRpbgAA -AAAAAAY2AACXGgAAVjoAAFPKAACJ3gAAJ8IAABaoAABQDQAAVDkAAiuFAAIZmQABeFEAAwEAAAIAAAAA -AAEABgANABcAIwAxAEAAUgBlAHsAkwCrAMUA4gD/AR8BPwFhAYUBqgHQAfgCIAJLAncCpQLSAwIDMwNl -A5gDzgQFBD0EdQSvBOsFKQVnBacF6AYqBm4GtQb8B0UHkgfkCDkIkAjnCT4JmAn0ClAKrQsLC2sLygwq -DIwM8Q1XDcAOKA6SDv4PbA/bEE0QxBE7EbQSMRKwEzITuRREFNAVYBXxFocXHhfAGGIZBBmsGlQa+RuU -HC4czh1yHhQeux9jIA0gvCFoIhkizyOJJEEk+SW6JnknOygFKMspkypiKzIsASzXLawuhy9gMD4xGzH8 -MtszvzSgNYY2cjdcOEw5OTorOxs8CD0EPfU+6z/nQOFB2ELUQ9VE00XcRttH5EjxSgBLCUwdTTFOUE9v -UI9Rt1LdVAVVNlZsV6VY4FohW21ct135X09goGH0Y0tkqGYFZ19oxGova5ptCG54b/BxbnLsdG119Xd/ -eQh6knwqfcV/W4D4gpSEO4Xih4CJKorYjIqOOY/jkZuTWJUOlsyYiZpSnB6d4Z+soX+jWqUvpxOo+6rj -rMuuwLC4sra0rra0uL+60LzfvwDBHcLdxLXGhchYyi7MCs3lz7rRmtOA1WPXR9kq2xPc/97s4M/iveSn -5o3obupT7ELuLPAM8fLz0PW396H5f/tZ/T3//wAAAAEAAwALABYAJQA3AE0AZQCBAJ8AwQDlAQsBNQFh -AZABwQH1AisCZAKfAtwDHANfA6MD6gQ0BH8EzQT1BR0FcAXEBhsGdAbPBy0HXAeMB+4IUgi4CSAJVAmK -CfYKZArVC0cLgQu8DDIMqw0mDaIOIQ6hDyQPqRAvELgQ/RFDEc8SXRLuE4AUFRSrFUMV3RZ5FxcXthhY -GPwZoRpIGvEbnBxJHPgdqB5bHw8fxSB9ITch8iKwJDAk8yW3Jn4nRigQKNwpqSp5K0osHCzxLccuoC95 -MFUxMzISMvMz1TS5NaA2hzdxOFw5STo4Oyg8Gj4DPvs/9EDuQepD6ETpRexG8Uf3SP9LFEwhTTBOQE9S -UGZSklOrVMVV4Vb/WB5ZP1phW4Vcq13SXvthUmJ/Y69k4GYSZ0dofGm0au1tZG6ib+FxInJlc6l073Y2 -d396FXtjfLJ+A39VgKmB/4NWhK+GCYjCiiGLgYzjjkePrJESknuT5Ja8mCuZm5sMnH+d9J9qoOGiWqPV -pVGmz6eOqE6pzqtRrNSuWq/gsWmy8rR+tgu5Kbq6vE294b93wQ7Cp8RBxd3He8kZyrrLisxbzf/Po9FK -0vHUm9ZF1/HZn9tO3Cbc/96x4GTiGePQ5YjnQegf6Pzquex27jbv9/G583z0X/VC9wj40Pqa/GX+Mf// -AAAAAQADAAsAJQA3AE0AZQCBAJ8AwQELATUBYQGQAcEB9QIrAmQCnwLcAxwDXwOjA+oENAR/BM0FHQVw -BcQGGwZ0Bs8HLQeMB+4IUgi4CSAJign2CmQK1QtHC7wMMgyrDSYNog4hDqEPJA+pEC8QuBFDEl0S7hOA -FBUUqxVDFnkXFxe2GFgY/BpIGvEbnBxJHPgdqB8PH8UgfSE3IfIjbyQwJPMltydGKBAo3Cp5K0osHC3H -LqAveTEzMhIy8zS5NaA2hzhcOUk6ODwaPQ4+Az/0QO5C6EPoROlG8Uf3SglLFEwhTkBPUlF7UpJUxVXh -Vv9ZP1phXKtd0mAlYVJjr2TgZhJofGm0au1tZG6ib+FxInJldO92Nnd/eMl6FXyyfgN/VYCpgf+Er4YJ -h2WIwoohi4GOR4+skRKSe5PklVCWvJgrmZubDJx/nfSfaqDholqj1aVRps+oTqnOq1Gs1K2Xrlqv4LFp -svK0frYLt5m5Kbnxurq8Tb3hv3fBDsHawqfEQcUPxd3He8hKyRnKusuKzFvN/87Rz6PQdtFK0vHTxtSb -1kXXG9fx2MjZn9tO3Cbc/93Y3rHfiuBk4hni9ePQ5KzliOZk50HoH+j86drqueuX7HbtVu427xbv9/DX -8bnymvN89F/1QvYl9wj37PjQ+bX6mvt//GX9S/4x//8AAGRlc2MAAAAAAAAACkNvbG9yIExDRAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABIAAAAcAEMAbwBsAG8AcgAgAEwAQwBE -AABtbW9kAAAAAAAABhAAAJxOAAAAAL5zkQAAAAAAAAAAAAAAAAAAAAAAdGV4dAAAAABDb3B5cmlnaHQg -QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA - - - - - - 3 - MCAwAA - - - - 400 - 75 - - - 67239424 - 0 - program crashes in between fork() and exec() (3rd option in first group will happen before crash) - - - 7 - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAv0AAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAL9GFw -cGwCAAAAbW50clJHQiBYWVogB9gAAgAMAAoAFgAIYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAPbWAAEAAAAA0y1hcHBs625VECyhxeSV9P9A73pKGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAANclhZWgAAASAAAAAUZ1hZWgAAATQAAAAUYlhZWgAAAUgAAAAUd3RwdAAAAVwAAAAUY2hhZAAA -AXAAAAAsclRSQwAAAZwAAAAOZ1RSQwAAAawAAAAOYlRSQwAAAbwAAAAOdmNndAAAAcwAAAYSbmRpbgAA -B+AAAAMOZGVzYwAACvAAAACZY3BydAAAC4wAAABAbW1vZAAAC8wAAAAoWFlaIAAAAAAAAJumAABMVQAA -ArBYWVogAAAAAAAANWMAAJ/rAAAZsVhZWiAAAAAAAAAlzQAAE9UAALbFWFlaIAAAAAAAAPPYAAEAAAAB -FghzZjMyAAAAAAABC7cAAAWW///zVwAABykAAP3X///7t////aYAAAPaAADA9mN1cnYAAAAAAAAAAQHN -AABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAADAQAAAgAAAioENAYA -B9AJlAtRDQwOshBOEekTgxUVFqMYMRm9GzwcvR4+H7chLiKnJBoliCb3KGIpyCswLJMt9C9WMLIyDjNn -NL02FTdoOLs6ETtdPKw9+D9DQJBB1kMeRGZFq0bySDRJeEq6S/tNPk59T75Q+lI2U25Uo1XZVwlYOlln -WpZbwFzsXhdfQWBrYZRiv2PoZRNmPWdqaJhpyGr5bC1tZW6hb+BxLXJ+c9d1OHafeA55gnr5fHR98H9t -gOuCY4PYhUqGsIgSiWyKuIwBjTqObY+VkLORyJLUk9eU05XFlrWXlZh2mUuaG5rsm6ucbJ0qndqei588 -n9+ghKEqoceiYqL/o5qkLqTDpVml66Z7pwunnKgpqLWpQqnQqlqq5Ktvq/qsg60MrZauIa6qrzOvvbBH -sNGxXLHnsnKy/7OMtBm0p7U3tci2Wbbrt4C4FrituUa54rqAux27wbxlvQq9rr5Tvvi/ncBAwOXBisIu -wtPDeMQdxMLFaMYPxrXHXMgEyKzJVcn/yqnLVcwBzK7NXc4Mzr3PcNAk0NnRkdJK0wTTw9SC1UTWCtbR -153Ybdk+2hfa8dvM3KfdhN5g3zzgGuD34dbiteOV5HblWeY85yHoCOjw6drqxuu27Kbtm+6R74zwivGM -8pPzn/Sw9cj25/gP+T76e/u//Rr+hP//AAABpANzBRoGsggnCZsLFQx+Dd4PRRCiEf8TYxS0FgoXXRiu -GgQbTRyZHekfMCB8IcIjCSRSJZUm3SgdKWAqpCvjLSYuZC+lMOIyIDNgNJs12TcTOFA5izrEO/49NT5w -P6dA30IWQ01Eg0W4Ru9IIElVSoZLt0zmThVPRFBwUZ5SylP5VSRWUVd+WKtZ2lsIXDhdaV6bX89hBWI8 -Y3dktGX0ZzhohGnVayxsiW3sb1Vww3I0c6p1I3aeeBl5k3sMfIR99X9kgM6CLYOJhNyGJodriKGJ1Ir5 -jBuNL45Aj0WQSJE8kjKTGJP+lNyVspaKl1OYHZjlmaSaZJshm9ecj51EnfSepJ9Vn/+gqqFWofyio6NL -o/CklKU4pdymfacfp8KoYqkDqaWqRarlq4asJ6zHrWiuCq6rr02v77CSsTax27KAsyezzrR3tSG1zLZ5 -tye32LiKuT659rqwu2q8J7zkvaK+YL8ev93AnMFcwhzC3MOdxF7FIMXixqXHaMgryPDJtcp6y0DMB8zO -zZbOX88oz/PQvtGJ0lbTI9Px1MDVkNZi1zTYB9jb2bDah9te3DjdEt3t3sjfpOB/4VviN+MT4/DkzeWq -5ojnZuhG6SXqBuro68rsre2S7nfvXvBH8TDyHPMI8/j06fXc9tL3yvjF+cL6w/vG/ND92v7s//8AAAMJ -BboIZwrCDSsPghG8E/IWHxg5GkgcVB5VIEQiMyQTJeknuimHK00tCy7AMHEyHDO/NV829ziKOhs7pj0s -PrBALEGmQx9EkkYCR3JI3EpCS6pND05vT89RLVKKU+dVP1aYV+9ZRVqdW/NdSV6hX+thM2JzY61k42YS -Z0FoZ2mOaq5rz2zsbglvI3A9cVRybHOEdJx1tHbOd+d5A3ofez98Yn2Lfrl/8IEqgmyDsoT8hkuHnYjw -ikSLmYzsjj+PjJDWkh2TW5SXlceW85gWmTOaSJtVnFqdWp5Pn0SgKaEQoeuiwqOYpGClKaXtpqmnZqgf -qNKph6o5quWrk6xArOatja41rtevebAcsLyxWbH3spWzL7PJtGO0/LWTtiq2wrdWt+q4f7kUuaW6OLrL -u1277Lx9vQ69nr4tvry/TL/bwGjA98GGwhPCocMvw77ESsTYxWXF9MZ/xwzHmcgkyKXJJ8mpyizKpMsc -y5XMDsyFzPjNa83fzlPOxc81z6fQGNCK0PvRbNHe0lDSw9M206vUINSV1QvVhtYA1nzW+Nd61//YhNkK -2ZnaL9rG213cCty63WveI97d35fgUuEO4crih+NE5ALkw+WD5kXnCufP6JbpYOor6vrry+yd7XbuUe8w -8BXw+/Ht8uDz4PTl9fj3E/hE+X363vxa/gH//wAAbmRpbgAAAAAAAAMGAACogAAAUwAAADRAAACqQAAA -JpcAABLbAABQQAAAVEAAAj99AAI1egACxUsAAwB4AAIAAAADAAsAGQAsAEUAYwCHALEA4QEWAVEBkgHZ -AiYCeQLSAzEDlwQDBHYE7wVvBfUGgwcXB7IIUwj8CawKYgsgC+QMrw2BDloPORAfEQ0SBRMGFBEVJBZA -F2MYjhm/GvYcMh1xHrMf9SE1ImwjnSTJJfAnFig7KWMqjivBLP4uSC+jMRMymzRBNgo3+joWPGY+8EG8 -RNhIQEvvT95UCFhkXOxhlWZYaylv/XTKeYN+GoKOhxGLqJBOlP6Ztp5voyan1Kx0sQG1c7nGvfHB9cX7 -ygbOFNIi1izaMN4p4hTl7emv7Vbw3vRC93z6iP1g//8AAAAEAA8AIgA9AF8AiQC7APQBNAF8AcwCIgKB -AuYDUwPHBEIExAVOBd4GdgcUB7oIZgkaCdQKlQteDC0NAw3gDsQPrxCiEZwSnxOpFLsV0xbyGBcZQRpw -G6Mc2R4RH0oggyG3IuckEyU8JmQniyiyKd0rDCxBLYAuyTAhMYkzBjSbNkw4HToSPDA+fED8Q7FGmUmx -TPdQaFQAV7tbll+KY5RnrmvTb/p0H3g6fEOAMoQXiASL+I/yk/KX+JwBoA2kHKgrrDuwS7RYuGK8aMBo -xGvId8yI0J/UuNjS3OvhAOUQ6RftE/EC9OH4rfxi//8AAAABAAYADQAXACUANQBIAF8AeQCWALcA3AEE -ATABYQGVAc4CDAJOApUC4QMyA4gD5QRGBK4FHAWPBgkGigcQB54IMQjMCW0KFArDC3cMMgzzDbsOiA9a -EDIRFhIIEwgUFRUvFlYXhxjDGgkbVhyqHgMfYCC8IhIjYSSrJfMnOSiBKc0rHyx7LeQvXTDrMpE0VTY7 -OEg6gjzuP5NCckWCSMJMMk/QU5xXk1u1X/9kcGkGbb5ylneLfJqByoeDjcyUf5t4oo2plLBetru8eMFr -xirK7c+v1GnZFd2r4iXme+ql7pryUvXD+OT7qv4M//8AAGRlc2MAAAAAAAAAFUhQIExQMzA2NSBDYWxp -YnJhdGVkAAAAAAAAAAAVAEgAUAAgAEwAUAAzADAANgA1ACAAQwBhAGwAaQBiAHIAYQB0AGUAZAAAAAAV -SFAgTFAzMDY1IENhbGlicmF0ZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIEluYy4sIDIwMDgAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAABtbW9kAAAAAAAAIvAAACaQAAAAAMJtVwAAAAAAAAAAAAAAAAAAAAAAA - - - - - - - - - 200 - 25 - - - {645, 25} - {4, 2} - 1151868928 - NSActionCell - - -2080244224 - 0 - program crashes after launch - - 5 - 1211912703 - 0 - - - - 200 - 25 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 3 - MQA - - - - - - 268 - {{20, 170}, {565, 70}} - - YES - 3 - 1 - - YES - - -2080244224 - 0 - Leave breakpad alone before fork - - - 1211912703 - 0 - - - - 200 - 25 - - - 67239424 - 0 - Uninitialize Breakpad before fork - - - 1 - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAwYAAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAMGGFw -cGwCAAAAbW50clJHQiBYWVogB9YABAADABMALAASYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA -AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAMSbmRpbgAA -BOwAAAY+ZGVzYwAACywAAABkZHNjbQAAC5AAAAAubW1vZAAAC8AAAAAoY3BydAAAC+gAAAAtWFlaIAAA -AAAAAF1KAAA0kQAACCVYWVogAAAAAAAAdCAAALRgAAAjPVhZWiAAAAAAAAAlbAAAFyoAAKfDWFlaIAAA -AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 -cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD -AQAAAQACBAUGBwkKCw0ODxASExQWFxgaGxweHyAiIyQmJygpKywtLzAxMjM1Njc4OTs8PT5AQUJDREZH -SElKS0xOT1BRUlNUVVZXWFlaW1xdXl9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SF -hoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnZ6foKGio6SlpqanqKmqq6ytra6vsLGysrO0tba3uLi5uru8 -vL2+v8DBwcLDxMXGxsfIycrKy8zNzs7P0NHS0tPU1dbW19jZ2drb3Nzd3t/g4eLi4+Tl5ufo6enq6+zt -7u/w8fHy8/T19vf4+fr7/P3+/v8AAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR8gISIjJCUnKCkq -Ky0uLzAxMzQ1Njc4OTo7PD0/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaWltcXV5fYGFiY2RlZmdo -aWprbG1ub3BxcnN0dXZ3d3h5ent8fH1+f4CBgoKDhIWGh4iIiYqLjI2Oj5CRkpOUlJWWl5iZmpucnZ2e -n6ChoqOkpaamp6ipqqusra6vsLCxsrO0tba3uLm5uru8vb6/wMHCw8TFx8jJysvMzc7P0NDR0tPU1dbX -2Nna29ze3+Dh4uPk5ebn6err7O3u7/Hy8/T19vf5+vv8/f7/AAIDAwQFBgcICQoKCwwNDg8QERITFBUW -FxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODg5Ojs8PT4+P0BBQkNDREVGR0hJSUpLTE1O -Tk9QUVJSU1RVVVZXWFhZWltbXF1eXl9gYWFiY2RkZWZnZ2hpaWprbGxtbm5vcHFxcnNzdHV1dnd4eHl6 -ent8fH1+fn+AgYGCg4SEhYaHiImJiouMjY6Oj5CRkpOTlJWWl5iZmZqbnJ2en6ChoqOkpaanqKmqq6yt -rq+xsrO0tba3uLq7vL2+wMHDxMbHycrMzs/R0tTW19nb3d7g4uTm6Ors7vDy9Pb4+vz+/wAAbmRpbgAA -AAAAAAY2AACXGgAAVjoAAFPKAACJ3gAAJ8IAABaoAABQDQAAVDkAAiuFAAIZmQABeFEAAwEAAAIAAAAA -AAEABgANABcAIwAxAEAAUgBlAHsAkwCrAMUA4gD/AR8BPwFhAYUBqgHQAfgCIAJLAncCpQLSAwIDMwNl -A5gDzgQFBD0EdQSvBOsFKQVnBacF6AYqBm4GtQb8B0UHkgfkCDkIkAjnCT4JmAn0ClAKrQsLC2sLygwq -DIwM8Q1XDcAOKA6SDv4PbA/bEE0QxBE7EbQSMRKwEzITuRREFNAVYBXxFocXHhfAGGIZBBmsGlQa+RuU -HC4czh1yHhQeux9jIA0gvCFoIhkizyOJJEEk+SW6JnknOygFKMspkypiKzIsASzXLawuhy9gMD4xGzH8 -MtszvzSgNYY2cjdcOEw5OTorOxs8CD0EPfU+6z/nQOFB2ELUQ9VE00XcRttH5EjxSgBLCUwdTTFOUE9v -UI9Rt1LdVAVVNlZsV6VY4FohW21ct135X09goGH0Y0tkqGYFZ19oxGova5ptCG54b/BxbnLsdG119Xd/ -eQh6knwqfcV/W4D4gpSEO4Xih4CJKorYjIqOOY/jkZuTWJUOlsyYiZpSnB6d4Z+soX+jWqUvpxOo+6rj -rMuuwLC4sra0rra0uL+60LzfvwDBHcLdxLXGhchYyi7MCs3lz7rRmtOA1WPXR9kq2xPc/97s4M/iveSn -5o3obupT7ELuLPAM8fLz0PW396H5f/tZ/T3//wAAAAEAAwALABYAJQA3AE0AZQCBAJ8AwQDlAQsBNQFh -AZABwQH1AisCZAKfAtwDHANfA6MD6gQ0BH8EzQT1BR0FcAXEBhsGdAbPBy0HXAeMB+4IUgi4CSAJVAmK -CfYKZArVC0cLgQu8DDIMqw0mDaIOIQ6hDyQPqRAvELgQ/RFDEc8SXRLuE4AUFRSrFUMV3RZ5FxcXthhY -GPwZoRpIGvEbnBxJHPgdqB5bHw8fxSB9ITch8iKwJDAk8yW3Jn4nRigQKNwpqSp5K0osHCzxLccuoC95 -MFUxMzISMvMz1TS5NaA2hzdxOFw5STo4Oyg8Gj4DPvs/9EDuQepD6ETpRexG8Uf3SP9LFEwhTTBOQE9S -UGZSklOrVMVV4Vb/WB5ZP1phW4Vcq13SXvthUmJ/Y69k4GYSZ0dofGm0au1tZG6ib+FxInJlc6l073Y2 -d396FXtjfLJ+A39VgKmB/4NWhK+GCYjCiiGLgYzjjkePrJESknuT5Ja8mCuZm5sMnH+d9J9qoOGiWqPV -pVGmz6eOqE6pzqtRrNSuWq/gsWmy8rR+tgu5Kbq6vE294b93wQ7Cp8RBxd3He8kZyrrLisxbzf/Po9FK -0vHUm9ZF1/HZn9tO3Cbc/96x4GTiGePQ5YjnQegf6Pzquex27jbv9/G583z0X/VC9wj40Pqa/GX+Mf// -AAAAAQADAAsAJQA3AE0AZQCBAJ8AwQELATUBYQGQAcEB9QIrAmQCnwLcAxwDXwOjA+oENAR/BM0FHQVw -BcQGGwZ0Bs8HLQeMB+4IUgi4CSAJign2CmQK1QtHC7wMMgyrDSYNog4hDqEPJA+pEC8QuBFDEl0S7hOA -FBUUqxVDFnkXFxe2GFgY/BpIGvEbnBxJHPgdqB8PH8UgfSE3IfIjbyQwJPMltydGKBAo3Cp5K0osHC3H -LqAveTEzMhIy8zS5NaA2hzhcOUk6ODwaPQ4+Az/0QO5C6EPoROlG8Uf3SglLFEwhTkBPUlF7UpJUxVXh -Vv9ZP1phXKtd0mAlYVJjr2TgZhJofGm0au1tZG6ib+FxInJldO92Nnd/eMl6FXyyfgN/VYCpgf+Er4YJ -h2WIwoohi4GOR4+skRKSe5PklVCWvJgrmZubDJx/nfSfaqDholqj1aVRps+oTqnOq1Gs1K2Xrlqv4LFp -svK0frYLt5m5Kbnxurq8Tb3hv3fBDsHawqfEQcUPxd3He8hKyRnKusuKzFvN/87Rz6PQdtFK0vHTxtSb -1kXXG9fx2MjZn9tO3Cbc/93Y3rHfiuBk4hni9ePQ5KzliOZk50HoH+j86drqueuX7HbtVu427xbv9/DX -8bnymvN89F/1QvYl9wj37PjQ+bX6mvt//GX9S/4x//8AAGRlc2MAAAAAAAAACkNvbG9yIExDRAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABIAAAAcAEMAbwBsAG8AcgAgAEwAQwBE -AABtbW9kAAAAAAAABhAAAJxOAAAAAL5zkQAAAAAAAAAAAAAAAAAAAAAAdGV4dAAAAABDb3B5cmlnaHQg -QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA - - - - - - - - 400 - 75 - - - 67239424 - 0 - Call task_set_exception_port with null exception port in child process before exec - - - 2 - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAv0AAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAL9GFw -cGwCAAAAbW50clJHQiBYWVogB9gAAgAMAAoAFgAIYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAPbWAAEAAAAA0y1hcHBs625VECyhxeSV9P9A73pKGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAANclhZWgAAASAAAAAUZ1hZWgAAATQAAAAUYlhZWgAAAUgAAAAUd3RwdAAAAVwAAAAUY2hhZAAA -AXAAAAAsclRSQwAAAZwAAAAOZ1RSQwAAAawAAAAOYlRSQwAAAbwAAAAOdmNndAAAAcwAAAYSbmRpbgAA -B+AAAAMOZGVzYwAACvAAAACZY3BydAAAC4wAAABAbW1vZAAAC8wAAAAoWFlaIAAAAAAAAJumAABMVQAA -ArBYWVogAAAAAAAANWMAAJ/rAAAZsVhZWiAAAAAAAAAlzQAAE9UAALbFWFlaIAAAAAAAAPPYAAEAAAAB -FghzZjMyAAAAAAABC7cAAAWW///zVwAABykAAP3X///7t////aYAAAPaAADA9mN1cnYAAAAAAAAAAQHN -AABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAADAQAAAgAAAioENAYA -B9AJlAtRDQwOshBOEekTgxUVFqMYMRm9GzwcvR4+H7chLiKnJBoliCb3KGIpyCswLJMt9C9WMLIyDjNn -NL02FTdoOLs6ETtdPKw9+D9DQJBB1kMeRGZFq0bySDRJeEq6S/tNPk59T75Q+lI2U25Uo1XZVwlYOlln -WpZbwFzsXhdfQWBrYZRiv2PoZRNmPWdqaJhpyGr5bC1tZW6hb+BxLXJ+c9d1OHafeA55gnr5fHR98H9t -gOuCY4PYhUqGsIgSiWyKuIwBjTqObY+VkLORyJLUk9eU05XFlrWXlZh2mUuaG5rsm6ucbJ0qndqei588 -n9+ghKEqoceiYqL/o5qkLqTDpVml66Z7pwunnKgpqLWpQqnQqlqq5Ktvq/qsg60MrZauIa6qrzOvvbBH -sNGxXLHnsnKy/7OMtBm0p7U3tci2Wbbrt4C4FrituUa54rqAux27wbxlvQq9rr5Tvvi/ncBAwOXBisIu -wtPDeMQdxMLFaMYPxrXHXMgEyKzJVcn/yqnLVcwBzK7NXc4Mzr3PcNAk0NnRkdJK0wTTw9SC1UTWCtbR -153Ybdk+2hfa8dvM3KfdhN5g3zzgGuD34dbiteOV5HblWeY85yHoCOjw6drqxuu27Kbtm+6R74zwivGM -8pPzn/Sw9cj25/gP+T76e/u//Rr+hP//AAABpANzBRoGsggnCZsLFQx+Dd4PRRCiEf8TYxS0FgoXXRiu -GgQbTRyZHekfMCB8IcIjCSRSJZUm3SgdKWAqpCvjLSYuZC+lMOIyIDNgNJs12TcTOFA5izrEO/49NT5w -P6dA30IWQ01Eg0W4Ru9IIElVSoZLt0zmThVPRFBwUZ5SylP5VSRWUVd+WKtZ2lsIXDhdaV6bX89hBWI8 -Y3dktGX0ZzhohGnVayxsiW3sb1Vww3I0c6p1I3aeeBl5k3sMfIR99X9kgM6CLYOJhNyGJodriKGJ1Ir5 -jBuNL45Aj0WQSJE8kjKTGJP+lNyVspaKl1OYHZjlmaSaZJshm9ecj51EnfSepJ9Vn/+gqqFWofyio6NL -o/CklKU4pdymfacfp8KoYqkDqaWqRarlq4asJ6zHrWiuCq6rr02v77CSsTax27KAsyezzrR3tSG1zLZ5 -tye32LiKuT659rqwu2q8J7zkvaK+YL8ev93AnMFcwhzC3MOdxF7FIMXixqXHaMgryPDJtcp6y0DMB8zO -zZbOX88oz/PQvtGJ0lbTI9Px1MDVkNZi1zTYB9jb2bDah9te3DjdEt3t3sjfpOB/4VviN+MT4/DkzeWq -5ojnZuhG6SXqBuro68rsre2S7nfvXvBH8TDyHPMI8/j06fXc9tL3yvjF+cL6w/vG/ND92v7s//8AAAMJ -BboIZwrCDSsPghG8E/IWHxg5GkgcVB5VIEQiMyQTJeknuimHK00tCy7AMHEyHDO/NV829ziKOhs7pj0s -PrBALEGmQx9EkkYCR3JI3EpCS6pND05vT89RLVKKU+dVP1aYV+9ZRVqdW/NdSV6hX+thM2JzY61k42YS -Z0FoZ2mOaq5rz2zsbglvI3A9cVRybHOEdJx1tHbOd+d5A3ofez98Yn2Lfrl/8IEqgmyDsoT8hkuHnYjw -ikSLmYzsjj+PjJDWkh2TW5SXlceW85gWmTOaSJtVnFqdWp5Pn0SgKaEQoeuiwqOYpGClKaXtpqmnZqgf -qNKph6o5quWrk6xArOatja41rtevebAcsLyxWbH3spWzL7PJtGO0/LWTtiq2wrdWt+q4f7kUuaW6OLrL -u1277Lx9vQ69nr4tvry/TL/bwGjA98GGwhPCocMvw77ESsTYxWXF9MZ/xwzHmcgkyKXJJ8mpyizKpMsc -y5XMDsyFzPjNa83fzlPOxc81z6fQGNCK0PvRbNHe0lDSw9M206vUINSV1QvVhtYA1nzW+Nd61//YhNkK -2ZnaL9rG213cCty63WveI97d35fgUuEO4crih+NE5ALkw+WD5kXnCufP6JbpYOor6vrry+yd7XbuUe8w -8BXw+/Ht8uDz4PTl9fj3E/hE+X363vxa/gH//wAAbmRpbgAAAAAAAAMGAACogAAAUwAAADRAAACqQAAA -JpcAABLbAABQQAAAVEAAAj99AAI1egACxUsAAwB4AAIAAAADAAsAGQAsAEUAYwCHALEA4QEWAVEBkgHZ -AiYCeQLSAzEDlwQDBHYE7wVvBfUGgwcXB7IIUwj8CawKYgsgC+QMrw2BDloPORAfEQ0SBRMGFBEVJBZA -F2MYjhm/GvYcMh1xHrMf9SE1ImwjnSTJJfAnFig7KWMqjivBLP4uSC+jMRMymzRBNgo3+joWPGY+8EG8 -RNhIQEvvT95UCFhkXOxhlWZYaylv/XTKeYN+GoKOhxGLqJBOlP6Ztp5voyan1Kx0sQG1c7nGvfHB9cX7 -ygbOFNIi1izaMN4p4hTl7emv7Vbw3vRC93z6iP1g//8AAAAEAA8AIgA9AF8AiQC7APQBNAF8AcwCIgKB -AuYDUwPHBEIExAVOBd4GdgcUB7oIZgkaCdQKlQteDC0NAw3gDsQPrxCiEZwSnxOpFLsV0xbyGBcZQRpw -G6Mc2R4RH0oggyG3IuckEyU8JmQniyiyKd0rDCxBLYAuyTAhMYkzBjSbNkw4HToSPDA+fED8Q7FGmUmx -TPdQaFQAV7tbll+KY5RnrmvTb/p0H3g6fEOAMoQXiASL+I/yk/KX+JwBoA2kHKgrrDuwS7RYuGK8aMBo -xGvId8yI0J/UuNjS3OvhAOUQ6RftE/EC9OH4rfxi//8AAAABAAYADQAXACUANQBIAF8AeQCWALcA3AEE -ATABYQGVAc4CDAJOApUC4QMyA4gD5QRGBK4FHAWPBgkGigcQB54IMQjMCW0KFArDC3cMMgzzDbsOiA9a -EDIRFhIIEwgUFRUvFlYXhxjDGgkbVhyqHgMfYCC8IhIjYSSrJfMnOSiBKc0rHyx7LeQvXTDrMpE0VTY7 -OEg6gjzuP5NCckWCSMJMMk/QU5xXk1u1X/9kcGkGbb5ylneLfJqByoeDjcyUf5t4oo2plLBetru8eMFr -xirK7c+v1GnZFd2r4iXme+ql7pryUvXD+OT7qv4M//8AAGRlc2MAAAAAAAAAFUhQIExQMzA2NSBDYWxp -YnJhdGVkAAAAAAAAAAAVAEgAUAAgAEwAUAAzADAANgA1ACAAQwBhAGwAaQBiAHIAYQB0AGUAZAAAAAAV -SFAgTFAzMDY1IENhbGlicmF0ZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIEluYy4sIDIwMDgAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAABtbW9kAAAAAAAAIvAAACaQAAAAAMJtVwAAAAAAAAAAAAAAAAAAAAAAA - - - - - - - - 400 - 75 - - - {565, 22} - {4, 2} - 1151868928 - NSActionCell - - 67239424 - 0 - Radio - - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFugEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - - - - - - - - 400 - 75 - - - - - - - - - 268 - {{20, 104}, {565, 38}} - - YES - 2 - 1 - - YES - - -2080244224 - 0 - fork() - - - 3 - 1211912703 - 0 - - - - 200 - 25 - - - 67239424 - 0 - vfork() - - - 4 - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAwYAAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAMGGFw -cGwCAAAAbW50clJHQiBYWVogB9YABAADABMALAASYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA -AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAMSbmRpbgAA -BOwAAAY+ZGVzYwAACywAAABkZHNjbQAAC5AAAAAubW1vZAAAC8AAAAAoY3BydAAAC+gAAAAtWFlaIAAA -AAAAAF1KAAA0kQAACCVYWVogAAAAAAAAdCAAALRgAAAjPVhZWiAAAAAAAAAlbAAAFyoAAKfDWFlaIAAA -AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 -cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD -AQAAAQACBAUGBwkKCw0ODxASExQWFxgaGxweHyAiIyQmJygpKywtLzAxMjM1Njc4OTs8PT5AQUJDREZH -SElKS0xOT1BRUlNUVVZXWFlaW1xdXl9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SF -hoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnZ6foKGio6SlpqanqKmqq6ytra6vsLGysrO0tba3uLi5uru8 -vL2+v8DBwcLDxMXGxsfIycrKy8zNzs7P0NHS0tPU1dbW19jZ2drb3Nzd3t/g4eLi4+Tl5ufo6enq6+zt -7u/w8fHy8/T19vf4+fr7/P3+/v8AAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR8gISIjJCUnKCkq -Ky0uLzAxMzQ1Njc4OTo7PD0/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaWltcXV5fYGFiY2RlZmdo -aWprbG1ub3BxcnN0dXZ3d3h5ent8fH1+f4CBgoKDhIWGh4iIiYqLjI2Oj5CRkpOUlJWWl5iZmpucnZ2e -n6ChoqOkpaamp6ipqqusra6vsLCxsrO0tba3uLm5uru8vb6/wMHCw8TFx8jJysvMzc7P0NDR0tPU1dbX -2Nna29ze3+Dh4uPk5ebn6err7O3u7/Hy8/T19vf5+vv8/f7/AAIDAwQFBgcICQoKCwwNDg8QERITFBUW -FxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODg5Ojs8PT4+P0BBQkNDREVGR0hJSUpLTE1O -Tk9QUVJSU1RVVVZXWFhZWltbXF1eXl9gYWFiY2RkZWZnZ2hpaWprbGxtbm5vcHFxcnNzdHV1dnd4eHl6 -ent8fH1+fn+AgYGCg4SEhYaHiImJiouMjY6Oj5CRkpOTlJWWl5iZmZqbnJ2en6ChoqOkpaanqKmqq6yt -rq+xsrO0tba3uLq7vL2+wMHDxMbHycrMzs/R0tTW19nb3d7g4uTm6Ors7vDy9Pb4+vz+/wAAbmRpbgAA -AAAAAAY2AACXGgAAVjoAAFPKAACJ3gAAJ8IAABaoAABQDQAAVDkAAiuFAAIZmQABeFEAAwEAAAIAAAAA -AAEABgANABcAIwAxAEAAUgBlAHsAkwCrAMUA4gD/AR8BPwFhAYUBqgHQAfgCIAJLAncCpQLSAwIDMwNl -A5gDzgQFBD0EdQSvBOsFKQVnBacF6AYqBm4GtQb8B0UHkgfkCDkIkAjnCT4JmAn0ClAKrQsLC2sLygwq -DIwM8Q1XDcAOKA6SDv4PbA/bEE0QxBE7EbQSMRKwEzITuRREFNAVYBXxFocXHhfAGGIZBBmsGlQa+RuU -HC4czh1yHhQeux9jIA0gvCFoIhkizyOJJEEk+SW6JnknOygFKMspkypiKzIsASzXLawuhy9gMD4xGzH8 -MtszvzSgNYY2cjdcOEw5OTorOxs8CD0EPfU+6z/nQOFB2ELUQ9VE00XcRttH5EjxSgBLCUwdTTFOUE9v -UI9Rt1LdVAVVNlZsV6VY4FohW21ct135X09goGH0Y0tkqGYFZ19oxGova5ptCG54b/BxbnLsdG119Xd/ -eQh6knwqfcV/W4D4gpSEO4Xih4CJKorYjIqOOY/jkZuTWJUOlsyYiZpSnB6d4Z+soX+jWqUvpxOo+6rj -rMuuwLC4sra0rra0uL+60LzfvwDBHcLdxLXGhchYyi7MCs3lz7rRmtOA1WPXR9kq2xPc/97s4M/iveSn -5o3obupT7ELuLPAM8fLz0PW396H5f/tZ/T3//wAAAAEAAwALABYAJQA3AE0AZQCBAJ8AwQDlAQsBNQFh -AZABwQH1AisCZAKfAtwDHANfA6MD6gQ0BH8EzQT1BR0FcAXEBhsGdAbPBy0HXAeMB+4IUgi4CSAJVAmK -CfYKZArVC0cLgQu8DDIMqw0mDaIOIQ6hDyQPqRAvELgQ/RFDEc8SXRLuE4AUFRSrFUMV3RZ5FxcXthhY -GPwZoRpIGvEbnBxJHPgdqB5bHw8fxSB9ITch8iKwJDAk8yW3Jn4nRigQKNwpqSp5K0osHCzxLccuoC95 -MFUxMzISMvMz1TS5NaA2hzdxOFw5STo4Oyg8Gj4DPvs/9EDuQepD6ETpRexG8Uf3SP9LFEwhTTBOQE9S -UGZSklOrVMVV4Vb/WB5ZP1phW4Vcq13SXvthUmJ/Y69k4GYSZ0dofGm0au1tZG6ib+FxInJlc6l073Y2 -d396FXtjfLJ+A39VgKmB/4NWhK+GCYjCiiGLgYzjjkePrJESknuT5Ja8mCuZm5sMnH+d9J9qoOGiWqPV -pVGmz6eOqE6pzqtRrNSuWq/gsWmy8rR+tgu5Kbq6vE294b93wQ7Cp8RBxd3He8kZyrrLisxbzf/Po9FK -0vHUm9ZF1/HZn9tO3Cbc/96x4GTiGePQ5YjnQegf6Pzquex27jbv9/G583z0X/VC9wj40Pqa/GX+Mf// -AAAAAQADAAsAJQA3AE0AZQCBAJ8AwQELATUBYQGQAcEB9QIrAmQCnwLcAxwDXwOjA+oENAR/BM0FHQVw -BcQGGwZ0Bs8HLQeMB+4IUgi4CSAJign2CmQK1QtHC7wMMgyrDSYNog4hDqEPJA+pEC8QuBFDEl0S7hOA -FBUUqxVDFnkXFxe2GFgY/BpIGvEbnBxJHPgdqB8PH8UgfSE3IfIjbyQwJPMltydGKBAo3Cp5K0osHC3H -LqAveTEzMhIy8zS5NaA2hzhcOUk6ODwaPQ4+Az/0QO5C6EPoROlG8Uf3SglLFEwhTkBPUlF7UpJUxVXh -Vv9ZP1phXKtd0mAlYVJjr2TgZhJofGm0au1tZG6ib+FxInJldO92Nnd/eMl6FXyyfgN/VYCpgf+Er4YJ -h2WIwoohi4GOR4+skRKSe5PklVCWvJgrmZubDJx/nfSfaqDholqj1aVRps+oTqnOq1Gs1K2Xrlqv4LFp -svK0frYLt5m5Kbnxurq8Tb3hv3fBDsHawqfEQcUPxd3He8hKyRnKusuKzFvN/87Rz6PQdtFK0vHTxtSb -1kXXG9fx2MjZn9tO3Cbc/93Y3rHfiuBk4hni9ePQ5KzliOZk50HoH+j86drqueuX7HbtVu427xbv9/DX -8bnymvN89F/1QvYl9wj37PjQ+bX6mvt//GX9S/4x//8AAGRlc2MAAAAAAAAACkNvbG9yIExDRAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABIAAAAcAEMAbwBsAG8AcgAgAEwAQwBE -AABtbW9kAAAAAAAABhAAAJxOAAAAAL5zkQAAAAAAAAAAAAAAAAAAAAAAdGV4dAAAAABDb3B5cmlnaHQg -QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA - - - - - - - - 400 - 75 - - - {565, 18} - {4, 2} - 1151868928 - NSActionCell - - 67239424 - 0 - Radio - - 1211912703 - 0 - - 549453824 - {18, 18} - - YES - - YES - - - - TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw -IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ -29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 -dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA -AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG -AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ -0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ -7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ -5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ -3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD -AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns -AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ -6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ -/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ -///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl -YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA -AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD -AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu -AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQEAAAMAAAABABIAAAEB -AAMAAAABABIAAAECAAMAAAAEAAAFugEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - - - - - - - - 400 - 75 - - - - - - - - - 268 - {{591, 59}, {178, 161}} - - YES - - 67239424 - 134217728 - Go! - - LucidaGrande - 10 - 16 - - - -2033434369 - 130 - - - 400 - 75 - - - - {787, 260} - - - {{0, 0}, {1440, 878}} - {1.79769e+308, 1.79769e+308} - - - - - YES - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - showHelp: - - - - 122 - - - - clearRecentDocuments: - - - - 127 - - - - terminate: - - - - 139 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - hideOtherApplications: - - - - 146 - - - - hide: - - - - 152 - - - - unhideAllApplications: - - - - 153 - - - - cut: - - - - 175 - - - - paste: - - - - 176 - - - - redo: - - - - 178 - - - - selectAll: - - - - 179 - - - - undo: - - - - 180 - - - - copy: - - - - 181 - - - - showGuessPanel: - - - - 188 - - - - checkSpelling: - - - - 190 - - - - toggleContinuousSpellChecking: - - - - 192 - - - - performClose: - - - - 193 - - - - delete: - - - - 195 - - - - performZoom: - - - - 198 - - - - performFindPanelAction: - - - - 199 - - - - performFindPanelAction: - - - - 200 - - - - performFindPanelAction: - - - - 201 - - - - performFindPanelAction: - - - - 202 - - - - centerSelectionInVisibleArea: - - - - 203 - - - - pasteAsPlainText: - - - - 205 - - - - crash: - - - - 208 - - - - window_ - - - - 209 - - - - crash: - - - - 211 - - - - crash: - - - - 213 - - - - forkTestOptions_ - - - - 241 - - - - forkTestOptions: - - - - 242 - - - - forkTestOptions: - - - - 243 - - - - forkTestOptions: - - - - 244 - - - - forkTestGo: - - - - 250 - - - - forkTestOptions: - - - - 261 - - - - forkTestOptions: - - - - 262 - - - - showForkTestWindow: - - - - 283 - - - - generateReportWithoutCrash: - - - - 327 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 21 - - - YES - - - - Window - - - 2 - - - YES - - - - - - - - - - 206 - - - YES - - - - - - 210 - - - YES - - - - - - 212 - - - YES - - - - - - 218 - - - YES - - - - - - 325 - - - YES - - - - - - 29 - - - YES - - - - - - - - MainMenu - - - 19 - - - YES - - - - - - 24 - - - YES - - - - - - - - - 5 - - - - - 23 - - - - - 92 - - - - - 197 - - - - - 56 - - - YES - - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 129 - - - - - 131 - - - YES - - - - - - 130 - - - - - 134 - - - - - 136 - - - - - 143 - - - - - 144 - - - - - 145 - - - - - 149 - - - - - 150 - - - - - 196 - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - - - - - - - - - 72 - - - - - 73 - - - - - 74 - - - - - 75 - - - - - 77 - - - - - 78 - - - - - 79 - - - - - 80 - - - - - 82 - - - - - 112 - - - - - 124 - - - YES - - - - - - 125 - - - YES - - - - - - 126 - - - - - 103 - - - YES - - - - - - 106 - - - YES - - - - - - 111 - - - - - 163 - - - YES - - - - - - 169 - - - YES - - - - - - - - - - - - - - - - - 156 - - - - - 157 - - - - - 158 - - - - - 160 - - - - - 164 - - - - - 168 - - - YES - - - - - - 159 - - - YES - - - - - - - - - - 154 - - - - - 155 - - - - - 161 - - - - - 162 - - - - - 167 - - - - - 171 - - - - - 172 - - - - - 173 - - - - - 174 - - - - - 184 - - - YES - - - - - - 185 - - - YES - - - - - - - - 187 - - - - - 189 - - - - - 191 - - - - - 204 - - - - - 207 - - - Controller - - - 220 - - - YES - - - - Window (Window) - - - 221 - - - YES - - - - - - - - - 226 - - - YES - - - - - - - - - 227 - - - - - 228 - - - - - 272 - - - - - 232 - - - YES - - - - - - - - - 233 - - - - - 234 - - - - - 236 - - - - - 237 - - - YES - - - - - - - - 238 - - - - - 239 - - - - - 248 - - - YES - - - - - - 329 - - - - - 330 - - - - - 331 - - - - - 332 - - - - - 333 - - - - - 334 - - - - - 335 - - - - - 336 - - - - - 337 - - - - - - - YES - - YES - -3.IBPluginDependency - -3.ImportedFromIB2 - 103.IBPluginDependency - 103.ImportedFromIB2 - 106.IBPluginDependency - 106.ImportedFromIB2 - 111.IBPluginDependency - 111.ImportedFromIB2 - 112.IBPluginDependency - 112.ImportedFromIB2 - 124.IBPluginDependency - 124.ImportedFromIB2 - 125.IBPluginDependency - 125.ImportedFromIB2 - 126.IBPluginDependency - 126.ImportedFromIB2 - 129.IBPluginDependency - 129.ImportedFromIB2 - 130.IBPluginDependency - 130.ImportedFromIB2 - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 143.IBPluginDependency - 143.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 154.IBPluginDependency - 154.ImportedFromIB2 - 155.IBPluginDependency - 155.ImportedFromIB2 - 156.IBPluginDependency - 156.ImportedFromIB2 - 157.IBPluginDependency - 157.ImportedFromIB2 - 158.IBPluginDependency - 158.ImportedFromIB2 - 159.IBPluginDependency - 159.ImportedFromIB2 - 160.IBPluginDependency - 160.ImportedFromIB2 - 161.IBPluginDependency - 161.ImportedFromIB2 - 162.IBPluginDependency - 162.ImportedFromIB2 - 163.IBPluginDependency - 163.ImportedFromIB2 - 164.IBPluginDependency - 164.ImportedFromIB2 - 167.IBPluginDependency - 167.ImportedFromIB2 - 168.IBPluginDependency - 168.ImportedFromIB2 - 169.IBPluginDependency - 169.ImportedFromIB2 - 171.IBPluginDependency - 171.ImportedFromIB2 - 172.IBPluginDependency - 172.ImportedFromIB2 - 173.IBPluginDependency - 173.ImportedFromIB2 - 174.IBPluginDependency - 174.ImportedFromIB2 - 184.IBPluginDependency - 184.ImportedFromIB2 - 185.IBPluginDependency - 185.ImportedFromIB2 - 187.IBPluginDependency - 187.ImportedFromIB2 - 189.IBPluginDependency - 189.ImportedFromIB2 - 19.IBPluginDependency - 19.ImportedFromIB2 - 191.IBPluginDependency - 191.ImportedFromIB2 - 196.IBPluginDependency - 196.ImportedFromIB2 - 197.IBPluginDependency - 197.ImportedFromIB2 - 2.IBPluginDependency - 2.ImportedFromIB2 - 204.IBPluginDependency - 204.ImportedFromIB2 - 206.IBPluginDependency - 206.ImportedFromIB2 - 207.ImportedFromIB2 - 21.IBEditorWindowLastContentRect - 21.IBPluginDependency - 21.IBWindowTemplateEditedContentRect - 21.ImportedFromIB2 - 21.windowTemplate.hasMinSize - 21.windowTemplate.minSize - 210.IBPluginDependency - 210.ImportedFromIB2 - 212.IBPluginDependency - 212.ImportedFromIB2 - 218.IBPluginDependency - 218.ImportedFromIB2 - 220.IBEditorWindowLastContentRect - 220.IBPluginDependency - 220.IBWindowTemplateEditedContentRect - 220.ImportedFromIB2 - 221.IBPluginDependency - 221.ImportedFromIB2 - 226.IBPluginDependency - 226.ImportedFromIB2 - 227.IBPluginDependency - 227.ImportedFromIB2 - 228.IBPluginDependency - 228.ImportedFromIB2 - 23.IBPluginDependency - 23.ImportedFromIB2 - 232.IBPluginDependency - 232.ImportedFromIB2 - 233.IBPluginDependency - 233.ImportedFromIB2 - 234.IBPluginDependency - 234.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 - 237.IBPluginDependency - 237.ImportedFromIB2 - 238.IBPluginDependency - 238.ImportedFromIB2 - 239.IBPluginDependency - 239.ImportedFromIB2 - 24.IBPluginDependency - 24.ImportedFromIB2 - 248.IBPluginDependency - 248.ImportedFromIB2 - 272.IBPluginDependency - 272.ImportedFromIB2 - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 325.IBPluginDependency - 325.ImportedFromIB2 - 329.IBPluginDependency - 330.IBPluginDependency - 331.IBPluginDependency - 332.IBPluginDependency - 333.IBPluginDependency - 334.IBPluginDependency - 335.IBPluginDependency - 336.IBPluginDependency - 337.IBPluginDependency - 5.IBPluginDependency - 5.ImportedFromIB2 - 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBPluginDependency - 57.ImportedFromIB2 - 58.IBPluginDependency - 58.ImportedFromIB2 - 72.IBPluginDependency - 72.ImportedFromIB2 - 73.IBPluginDependency - 73.ImportedFromIB2 - 74.IBPluginDependency - 74.ImportedFromIB2 - 75.IBPluginDependency - 75.ImportedFromIB2 - 77.IBPluginDependency - 77.ImportedFromIB2 - 78.IBPluginDependency - 78.ImportedFromIB2 - 79.IBPluginDependency - 79.ImportedFromIB2 - 80.IBPluginDependency - 80.ImportedFromIB2 - 81.IBPluginDependency - 81.ImportedFromIB2 - 82.IBPluginDependency - 82.ImportedFromIB2 - 83.IBPluginDependency - 83.ImportedFromIB2 - 92.IBPluginDependency - 92.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - {{510, 1250}, {320, 188}} - com.apple.InterfaceBuilder.CocoaPlugin - {{510, 1250}, {320, 188}} - - - {213, 107} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{-55, 1287}, {787, 260}} - com.apple.InterfaceBuilder.CocoaPlugin - {{-55, 1287}, {787, 260}} - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{0, 1114}, {362, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 337 - - - - YES - - Controller - NSObject - - YES - - YES - crash: - forkTestGo: - forkTestOptions: - generateReportWithoutCrash: - showForkTestWindow: - - - YES - id - id - id - id - id - - - - YES - - YES - crash: - forkTestGo: - forkTestOptions: - generateReportWithoutCrash: - showForkTestWindow: - - - YES - - crash: - id - - - forkTestGo: - id - - - forkTestOptions: - id - - - generateReportWithoutCrash: - id - - - showForkTestWindow: - id - - - - - YES - - YES - forkTestOptions_ - window_ - - - YES - NSWindow - NSWindow - - - - YES - - YES - forkTestOptions_ - window_ - - - YES - - forkTestOptions_ - NSWindow - - - window_ - NSWindow - - - - - IBProjectSource - testapp/Controller.h - - - - Controller - NSObject - - IBUserSource - - - - - FirstResponder - NSObject - - IBUserSource - - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSBrowser - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSBrowser.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSDocument - NSObject - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - id - id - id - id - id - id - - - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - - printDocument: - id - - - revertDocumentToSaved: - id - - - runPageLayout: - id - - - saveDocument: - id - - - saveDocumentAs: - id - - - saveDocumentTo: - id - - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocument.h - - - - NSDocument - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentScripting.h - - - - NSDocumentController - NSObject - - YES - - YES - clearRecentDocuments: - newDocument: - openDocument: - saveAllDocuments: - - - YES - id - id - id - id - - - - YES - - YES - clearRecentDocuments: - newDocument: - openDocument: - saveAllDocuments: - - - YES - - clearRecentDocuments: - id - - - newDocument: - id - - - openDocument: - id - - - saveAllDocuments: - id - - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMatrix - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSMatrix.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMovieView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMovieView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSTableView - NSControl - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../../Breakpad.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - - - YES - {9, 8} - {7, 2} - - - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Info.plist b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Info.plist deleted file mode 100644 index 6094ec6ce..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Info.plist +++ /dev/null @@ -1,55 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - bomb - CFBundleIdentifier - com.Google.BreakpadTest - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - BreakpadProductDisplay - Breakpad Tester - BreakpadProduct - Breakpad_Tester - BreakpadVersion - 1.2.3.4 - BreakpadReportInterval - 10 - BreakpadSkipConfirm - NO - BreakpadSendAndExit - YES - BreakpadRequestEmail - YES - BreakpadRequestComments - YES - BreakpadVendor - Foo Bar Corp, Incorporated, LTD, LLC - BreakpadServerParameters - - Param1 - Value1 - Param2 - Value2 - - LSUIElement - 1 - - diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.h b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.h deleted file mode 100644 index 0a6d736d1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import - -@interface TestClass : NSObject { -} - -- (void)wait; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.mm deleted file mode 100644 index 6e6a8833d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.mm +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#import "TestClass.h" - -struct AStruct { - int x; - float y; - double z; -}; - -class InternalTestClass { - public: - InternalTestClass(int a) : a_(a) {} - ~InternalTestClass() {} - - void snooze(float a); - void snooze(int a); - int snooze(int a, float b); - - protected: - int a_; - AStruct s_; - - static void InternalFunction(AStruct &s); - static float kStaticFloatValue; -}; - -void InternalTestClass::snooze(float a) { - InternalFunction(s_); - sleep(a_ * a); -} - -void InternalTestClass::snooze(int a) { - InternalFunction(s_); - sleep(a_ * a); -} - -int InternalTestClass::snooze(int a, float b) { - InternalFunction(s_); - sleep(a_ * a * b); - - return 33; -} - -void InternalTestClass::InternalFunction(AStruct &s) { - s.x = InternalTestClass::kStaticFloatValue; -} - -float InternalTestClass::kStaticFloatValue = 42; - -static float PlainOldFunction() { - return 3.14145f; -} - -@implementation TestClass - -- (void)wait { - InternalTestClass t(10); - float z = PlainOldFunction(); - - while (1) { - t.snooze(z); - } -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/bomb.icns b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/bomb.icns deleted file mode 100644 index c360dbf61..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/bomb.icns and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashInMain b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashInMain deleted file mode 100755 index 03bb31727..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashInMain and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashduringload b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashduringload deleted file mode 100755 index 5ca9debb7..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/crashduringload and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/main.m b/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/main.m deleted file mode 100644 index 1ed19bf96..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/main.m +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import - -int main(int argc, char *argv[]) { - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/BreakpadFramework_Test.mm b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/BreakpadFramework_Test.mm deleted file mode 100644 index 2ea103c69..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/BreakpadFramework_Test.mm +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// BreakpadFramework_Test.mm -// Test case file for Breakpad.h/mm. -// - -#import "GTMSenTestCase.h" -#import "Breakpad.h" - -#include - -@interface BreakpadFramework_Test : GTMTestCase { - @private - int last_exception_code_; - int last_exception_type_; - mach_port_t last_exception_thread_; - // We're not using Obj-C BOOL because we need to interop with - // Breakpad's callback. - bool shouldHandleException_; -} - -// This method is used by a callback used by test cases to determine -// whether to return true or false to Breakpad when handling an -// exception. -- (bool)shouldHandleException; -// This method returns a minimal dictionary that has what -// Breakpad needs to initialize. -- (NSMutableDictionary *)breakpadInitializationDictionary; -// This method is used by the exception handling callback -// to communicate to test cases the properites of the last -// exception. -- (void)setLastExceptionType:(int)type andCode:(int)code - andThread:(mach_port_t)thread; -@end - -// Callback for Breakpad exceptions -bool myBreakpadCallback(int exception_type, - int exception_code, - mach_port_t crashing_thread, - void *context); - -bool myBreakpadCallback(int exception_type, - int exception_code, - mach_port_t crashing_thread, - void *context) { - BreakpadFramework_Test *testCaseClass = - (BreakpadFramework_Test *)context; - [testCaseClass setLastExceptionType:exception_type - andCode:exception_code - andThread:crashing_thread]; - bool shouldHandleException = - [testCaseClass shouldHandleException]; - NSLog(@"Callback returning %d", shouldHandleException); - return shouldHandleException; -} -const int kNoLastExceptionCode = -1; -const int kNoLastExceptionType = -1; -const mach_port_t kNoLastExceptionThread = MACH_PORT_NULL; - -@implementation BreakpadFramework_Test -- (void) initializeExceptionStateVariables { - last_exception_code_ = kNoLastExceptionCode; - last_exception_type_ = kNoLastExceptionType; - last_exception_thread_ = kNoLastExceptionThread; -} - -- (NSMutableDictionary *)breakpadInitializationDictionary { - NSMutableDictionary *breakpadParams = - [NSMutableDictionary dictionaryWithCapacity:3]; - - [breakpadParams setObject:@"UnitTests" forKey:@BREAKPAD_PRODUCT]; - [breakpadParams setObject:@"1.0" forKey:@BREAKPAD_VERSION]; - [breakpadParams setObject:@"http://staging" forKey:@BREAKPAD_URL]; - return breakpadParams; -} - -- (bool)shouldHandleException { - return shouldHandleException_; -} - -- (void)setLastExceptionType:(int)type - andCode:(int)code - andThread:(mach_port_t)thread { - last_exception_type_ = type; - last_exception_code_ = code; - last_exception_thread_ = thread; -} - -// Test that the parameters mark required actually enable Breakpad to -// be initialized. -- (void)testBreakpadInstantiationWithRequiredParameters { - BreakpadRef b = BreakpadCreate([self breakpadInitializationDictionary]); - STAssertNotNULL(b, @"BreakpadCreate failed with required parameters"); - BreakpadRelease(b); -} - -// Test that Breakpad fails to initialize cleanly when required -// parameters are not present. -- (void)testBreakpadInstantiationWithoutRequiredParameters { - NSMutableDictionary *breakpadDictionary = - [self breakpadInitializationDictionary]; - - // Skip setting version, so that BreakpadCreate fails. - [breakpadDictionary removeObjectForKey:@BREAKPAD_VERSION]; - BreakpadRef b = BreakpadCreate(breakpadDictionary); - STAssertNULL(b, @"BreakpadCreate did not fail when missing a required" - " parameter!"); - - breakpadDictionary = [self breakpadInitializationDictionary]; - // Now test with no product - [breakpadDictionary removeObjectForKey:@BREAKPAD_PRODUCT]; - b = BreakpadCreate(breakpadDictionary); - STAssertNULL(b, @"BreakpadCreate did not fail when missing a required" - " parameter!"); - - breakpadDictionary = [self breakpadInitializationDictionary]; - // Now test with no URL - [breakpadDictionary removeObjectForKey:@BREAKPAD_URL]; - b = BreakpadCreate(breakpadDictionary); - STAssertNULL(b, @"BreakpadCreate did not fail when missing a required" - " parameter!"); - BreakpadRelease(b); -} - -// Test to ensure that when we call BreakpadAddUploadParameter, -// it's added to the dictionary correctly(this test depends on -// some internal details of Breakpad, namely, the special prefix -// that it uses to figure out which key/value pairs to upload). -- (void)testAddingBreakpadServerVariable { - NSMutableDictionary *breakpadDictionary = - [self breakpadInitializationDictionary]; - - BreakpadRef b = BreakpadCreate(breakpadDictionary); - STAssertNotNULL(b, @"BreakpadCreate failed with valid dictionary!"); - - BreakpadAddUploadParameter(b, - @"key", - @"value"); - - // Test that it did not add the key/value directly, e.g. without - // prepending the key with the prefix. - STAssertNil(BreakpadKeyValue(b, @"key"), - @"AddUploadParameter added key directly to dictionary" - " instead of prepending it!"); - - NSString *prependedKeyname = - [@BREAKPAD_SERVER_PARAMETER_PREFIX stringByAppendingString:@"key"]; - - STAssertEqualStrings(BreakpadKeyValue(b, prependedKeyname), - @"value", - @"Calling BreakpadAddUploadParameter did not prepend " - "key name"); - BreakpadRelease(b); -} - -// Test that when we do on-demand minidump generation, -// the exception code/type/thread are set properly. -- (void)testFilterCallbackReturnsFalse { - NSMutableDictionary *breakpadDictionary = - [self breakpadInitializationDictionary]; - - BreakpadRef b = BreakpadCreate(breakpadDictionary); - STAssertNotNULL(b, @"BreakpadCreate failed with valid dictionary!"); - BreakpadSetFilterCallback(b, &myBreakpadCallback, self); - - // This causes the callback to return false, meaning - // Breakpad won't take the exception - shouldHandleException_ = false; - - [self initializeExceptionStateVariables]; - STAssertEquals(last_exception_type_, kNoLastExceptionType, - @"Last exception type not initialized correctly."); - STAssertEquals(last_exception_code_, kNoLastExceptionCode, - @"Last exception code not initialized correctly."); - STAssertEquals(last_exception_thread_, kNoLastExceptionThread, - @"Last exception thread is not initialized correctly."); - - // Cause Breakpad's exception handler to be invoked. - BreakpadGenerateAndSendReport(b); - - STAssertEquals(last_exception_type_, 0, - @"Last exception type is not 0 for on demand"); - STAssertEquals(last_exception_code_, 0, - @"Last exception code is not 0 for on demand"); - STAssertEquals(last_exception_thread_, mach_thread_self(), - @"Last exception thread is not mach_thread_self() " - "for on demand"); -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc deleted file mode 100644 index 0164f4a29..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// crash_generation_server_test.cc -// Unit tests for CrashGenerationServer - -#include -#include -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/mac/crash_generation/client_info.h" -#include "client/mac/crash_generation/crash_generation_client.h" -#include "client/mac/crash_generation/crash_generation_server.h" -#include "client/mac/handler/exception_handler.h" -#include "client/mac/tests/spawn_child_process.h" -#include "common/tests/auto_tempdir.h" -#include "google_breakpad/processor/minidump.h" - -namespace google_breakpad { -// This acts as the log sink for INFO logging from the processor -// logging code. The logging output confuses XCode and makes it think -// there are unit test failures. testlogging.h handles the overriding. -std::ostringstream info_log; -} - -namespace { -using std::string; -using google_breakpad::AutoTempDir; -using google_breakpad::ClientInfo; -using google_breakpad::CrashGenerationClient; -using google_breakpad::CrashGenerationServer; -using google_breakpad::ExceptionHandler; -using google_breakpad::Minidump; -using google_breakpad::MinidumpContext; -using google_breakpad::MinidumpException; -using google_breakpad::MinidumpModule; -using google_breakpad::MinidumpModuleList; -using google_breakpad::MinidumpSystemInfo; -using google_breakpad::MinidumpThread; -using google_breakpad::MinidumpThreadList; -using testing::Test; -using namespace google_breakpad_test; - -class CrashGenerationServerTest : public Test { -public: - // The port name to receive messages on - char mach_port_name[128]; - // Filename of the last dump that was generated - string last_dump_name; - // PID of the child process - pid_t child_pid; - // A temp dir - AutoTempDir temp_dir; - // Counter just to ensure that we don't hit the same port again - static int i; - bool filter_callback_called; - - void SetUp() { - sprintf(mach_port_name, - "com.google.breakpad.ServerTest.%d.%d", getpid(), - CrashGenerationServerTest::i++); - child_pid = (pid_t)-1; - filter_callback_called = false; - } -}; -int CrashGenerationServerTest::i = 0; - -// Test that starting and stopping a server works -TEST_F(CrashGenerationServerTest, testStartStopServer) { - CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - NULL, // dump callback - NULL, // dump context - NULL, // exit callback - NULL, // exit context - false, // generate dumps - ""); // dump path - ASSERT_TRUE(server.Start()); - ASSERT_TRUE(server.Stop()); -} - -// Test that requesting a dump via CrashGenerationClient works -// Test without actually dumping -TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) { - CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - NULL, // dump callback - NULL, // dump context - NULL, // exit callback - NULL, // exit context - false, // don't generate dumps - temp_dir.path()); // dump path - ASSERT_TRUE(server.Start()); - - pid_t pid = fork(); - ASSERT_NE(-1, pid); - if (pid == 0) { - CrashGenerationClient client(mach_port_name); - bool result = client.RequestDump(); - exit(result ? 0 : 1); - } - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_TRUE(WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - EXPECT_TRUE(server.Stop()); - // check that no minidump was written - string pattern = temp_dir.path() + "/*"; - glob_t dirContents; - ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents); - EXPECT_EQ(GLOB_NOMATCH, ret); - if (ret != GLOB_NOMATCH) - globfree(&dirContents); -} - -void dumpCallback(void *context, const ClientInfo &client_info, - const std::string &file_path) { - if (context) { - CrashGenerationServerTest* self = - reinterpret_cast(context); - if (!file_path.empty()) - self->last_dump_name = file_path; - self->child_pid = client_info.pid(); - } -} - -void *RequestDump(void *context) { - CrashGenerationClient client((const char*)context); - bool result = client.RequestDump(); - return (void*)(result ? 0 : 1); -} - -// Test that actually writing a minidump works -TEST_F(CrashGenerationServerTest, testRequestDump) { - CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - dumpCallback, // dump callback - this, // dump context - NULL, // exit callback - NULL, // exit context - true, // generate dumps - temp_dir.path()); // dump path - ASSERT_TRUE(server.Start()); - - pid_t pid = fork(); - ASSERT_NE(-1, pid); - if (pid == 0) { - // Have to spawn off a separate thread to request the dump, - // because MinidumpGenerator assumes the handler thread is not - // the only thread - pthread_t thread; - if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0) - exit(1); - void* result; - pthread_join(thread, &result); - exit(reinterpret_cast(result)); - } - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_TRUE(WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - EXPECT_TRUE(server.Stop()); - // check that minidump was written - ASSERT_FALSE(last_dump_name.empty()); - struct stat st; - EXPECT_EQ(0, stat(last_dump_name.c_str(), &st)); - EXPECT_LT(0, st.st_size); - // check client's PID - ASSERT_EQ(pid, child_pid); -} - -static void Crasher() { - int *a = (int*)0x42; - - fprintf(stdout, "Going to crash...\n"); - fprintf(stdout, "A = %d", *a); -} - -// Test that crashing a child process with an OOP ExceptionHandler installed -// results in a minidump being written by the CrashGenerationServer in -// the parent. -TEST_F(CrashGenerationServerTest, testChildProcessCrash) { - CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - dumpCallback, // dump callback - this, // dump context - NULL, // exit callback - NULL, // exit context - true, // generate dumps - temp_dir.path()); // dump path - ASSERT_TRUE(server.Start()); - - pid_t pid = fork(); - ASSERT_NE(-1, pid); - if (pid == 0) { - // Instantiate an OOP exception handler. - ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name); - Crasher(); - // not reached - exit(0); - } - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_FALSE(WIFEXITED(ret)); - EXPECT_TRUE(server.Stop()); - // check that minidump was written - ASSERT_FALSE(last_dump_name.empty()); - struct stat st; - EXPECT_EQ(0, stat(last_dump_name.c_str(), &st)); - EXPECT_LT(0, st.st_size); - - // Read the minidump, sanity check some data. - Minidump minidump(last_dump_name.c_str()); - ASSERT_TRUE(minidump.Read()); - - MinidumpSystemInfo* system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(system_info); - const MDRawSystemInfo* raw_info = system_info->system_info(); - ASSERT_TRUE(raw_info); - EXPECT_EQ(kNativeArchitecture, raw_info->processor_architecture); - - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list); - ASSERT_EQ((unsigned int)1, thread_list->thread_count()); - - MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(main_thread); - MinidumpContext* context = main_thread->GetContext(); - ASSERT_TRUE(context); - EXPECT_EQ(kNativeContext, context->GetContextCPU()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* main_module = module_list->GetMainModule(); - ASSERT_TRUE(main_module); - EXPECT_EQ(GetExecutablePath(), main_module->code_file()); -} - -#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) && \ - (defined(__x86_64__) || defined(__i386__)) -// Test that crashing a child process of a different architecture -// produces a valid minidump. -TEST_F(CrashGenerationServerTest, testChildProcessCrashCrossArchitecture) { - CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - dumpCallback, // dump callback - this, // dump context - NULL, // exit callback - NULL, // exit context - true, // generate dumps - temp_dir.path()); // dump path - ASSERT_TRUE(server.Start()); - - // Spawn a child process - string helper_path = GetHelperPath(); - const char* argv[] = { - helper_path.c_str(), - "crash", - mach_port_name, - NULL - }; - pid_t pid = spawn_child_process(argv); - ASSERT_NE(-1, pid); - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_FALSE(WIFEXITED(ret)); - EXPECT_TRUE(server.Stop()); - // check that minidump was written - ASSERT_FALSE(last_dump_name.empty()); - struct stat st; - EXPECT_EQ(0, stat(last_dump_name.c_str(), &st)); - EXPECT_LT(0, st.st_size); - -const MDCPUArchitecture kExpectedArchitecture = -#if defined(__x86_64__) - MD_CPU_ARCHITECTURE_X86 -#elif defined(__i386__) - MD_CPU_ARCHITECTURE_AMD64 -#endif - ; -const uint32_t kExpectedContext = -#if defined(__i386__) - MD_CONTEXT_AMD64 -#elif defined(__x86_64__) - MD_CONTEXT_X86 -#endif - ; - - // Read the minidump, sanity check some data. - Minidump minidump(last_dump_name.c_str()); - ASSERT_TRUE(minidump.Read()); - - MinidumpSystemInfo* system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(system_info); - const MDRawSystemInfo* raw_info = system_info->system_info(); - ASSERT_TRUE(raw_info); - EXPECT_EQ(kExpectedArchitecture, raw_info->processor_architecture); - - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list); - ASSERT_EQ((unsigned int)1, thread_list->thread_count()); - - MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(main_thread); - MinidumpContext* context = main_thread->GetContext(); - ASSERT_TRUE(context); - EXPECT_EQ(kExpectedContext, context->GetContextCPU()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* main_module = module_list->GetMainModule(); - ASSERT_TRUE(main_module); - EXPECT_EQ(helper_path, main_module->code_file()); -} -#endif - -bool filter_callback(void* context) { - CrashGenerationServerTest* self = - reinterpret_cast(context); - self->filter_callback_called = true; - // veto dump generation - return false; -} - -// Test that a filter callback can veto minidump writing. -TEST_F(CrashGenerationServerTest, testFilter) { - CrashGenerationServer server(mach_port_name, - filter_callback, // filter callback - this, // filter context - dumpCallback, // dump callback - this, // dump context - NULL, // exit callback - NULL, // exit context - true, // generate dumps - temp_dir.path()); // dump path - ASSERT_TRUE(server.Start()); - - pid_t pid = fork(); - ASSERT_NE(-1, pid); - if (pid == 0) { - // Instantiate an OOP exception handler. - ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name); - Crasher(); - // not reached - exit(0); - } - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_FALSE(WIFEXITED(ret)); - EXPECT_TRUE(server.Stop()); - - // check that no minidump was written - EXPECT_TRUE(last_dump_name.empty()); - EXPECT_TRUE(filter_callback_called); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/exception_handler_test.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/exception_handler_test.cc deleted file mode 100644 index a8cf6968c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/exception_handler_test.cc +++ /dev/null @@ -1,713 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exception_handler_test.cc: Unit tests for google_breakpad::ExceptionHandler - -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "client/mac/handler/exception_handler.h" -#include "common/mac/MachIPC.h" -#include "common/tests/auto_tempdir.h" -#include "google_breakpad/processor/minidump.h" - -namespace google_breakpad { -// This acts as the log sink for INFO logging from the processor -// logging code. The logging output confuses XCode and makes it think -// there are unit test failures. testlogging.h handles the overriding. -std::ostringstream info_log; -} - -namespace { -using std::string; -using google_breakpad::AutoTempDir; -using google_breakpad::ExceptionHandler; -using google_breakpad::MachPortSender; -using google_breakpad::MachReceiveMessage; -using google_breakpad::MachSendMessage; -using google_breakpad::Minidump; -using google_breakpad::MinidumpContext; -using google_breakpad::MinidumpException; -using google_breakpad::MinidumpMemoryList; -using google_breakpad::MinidumpMemoryRegion; -using google_breakpad::ReceivePort; -using testing::Test; - -class ExceptionHandlerTest : public Test { - public: - void InProcessCrash(bool aborting); - AutoTempDir tempDir; - string lastDumpName; -}; - -static void Crasher() { - int *a = (int*)0x42; - - fprintf(stdout, "Going to crash...\n"); - fprintf(stdout, "A = %d", *a); -} - -static void AbortCrasher() { - fprintf(stdout, "Going to crash...\n"); - abort(); -} - -static void SoonToCrash(void(*crasher)()) { - crasher(); -} - -static bool MDCallback(const char *dump_dir, const char *file_name, - void *context, bool success) { - string path(dump_dir); - path.append("/"); - path.append(file_name); - path.append(".dmp"); - - int fd = *reinterpret_cast(context); - (void)write(fd, path.c_str(), path.length() + 1); - close(fd); - exit(0); - // not reached - return true; -} - -void ExceptionHandlerTest::InProcessCrash(bool aborting) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - // Fork off a child process so it can crash. - pid_t pid = fork(); - if (pid == 0) { - // In the child process. - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - // crash - SoonToCrash(aborting ? &AbortCrasher : &Crasher); - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - ASSERT_TRUE(exception); - - const MDRawExceptionStream* raw_exception = exception->exception(); - ASSERT_TRUE(raw_exception); - - if (aborting) { - EXPECT_EQ(MD_EXCEPTION_MAC_SOFTWARE, - raw_exception->exception_record.exception_code); - EXPECT_EQ(MD_EXCEPTION_CODE_MAC_ABORT, - raw_exception->exception_record.exception_flags); - } else { - EXPECT_EQ(MD_EXCEPTION_MAC_BAD_ACCESS, - raw_exception->exception_record.exception_code); -#if defined(__x86_64__) - EXPECT_EQ(MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS, - raw_exception->exception_record.exception_flags); -#elif defined(__i386__) - EXPECT_EQ(MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE, - raw_exception->exception_record.exception_flags); -#endif - } - - const MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - // Ideally would like to sanity check that abort() is on the stack - // but that's hard. - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(memory_list); - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - EXPECT_TRUE(region); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); -} - -TEST_F(ExceptionHandlerTest, InProcess) { - InProcessCrash(false); -} - -TEST_F(ExceptionHandlerTest, InProcessAbort) { - InProcessCrash(true); -} - -static bool DumpNameMDCallback(const char *dump_dir, const char *file_name, - void *context, bool success) { - ExceptionHandlerTest *self = reinterpret_cast(context); - if (dump_dir && file_name) { - self->lastDumpName = dump_dir; - self->lastDumpName += "/"; - self->lastDumpName += file_name; - self->lastDumpName += ".dmp"; - } - return true; -} - -TEST_F(ExceptionHandlerTest, WriteMinidump) { - ExceptionHandler eh(tempDir.path(), NULL, DumpNameMDCallback, this, true, - NULL); - ASSERT_TRUE(eh.WriteMinidump()); - - // Ensure that minidump file exists and is > 0 bytes. - ASSERT_FALSE(lastDumpName.empty()); - struct stat st; - ASSERT_EQ(0, stat(lastDumpName.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // The minidump should not contain an exception stream. - Minidump minidump(lastDumpName); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - EXPECT_FALSE(exception); -} - -TEST_F(ExceptionHandlerTest, WriteMinidumpWithException) { - ExceptionHandler eh(tempDir.path(), NULL, DumpNameMDCallback, this, true, - NULL); - ASSERT_TRUE(eh.WriteMinidump(true)); - - // Ensure that minidump file exists and is > 0 bytes. - ASSERT_FALSE(lastDumpName.empty()); - struct stat st; - ASSERT_EQ(0, stat(lastDumpName.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // The minidump should contain an exception stream. - Minidump minidump(lastDumpName); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - ASSERT_TRUE(exception); - const MDRawExceptionStream* raw_exception = exception->exception(); - ASSERT_TRUE(raw_exception); - - EXPECT_EQ(MD_EXCEPTION_MAC_BREAKPOINT, - raw_exception->exception_record.exception_code); -} - -TEST_F(ExceptionHandlerTest, DumpChildProcess) { - const int kTimeoutMs = 2000; - // Create a mach port to receive the child task on. - char machPortName[128]; - sprintf(machPortName, "ExceptionHandlerTest.%d", getpid()); - ReceivePort parent_recv_port(machPortName); - - // Give the child process a pipe to block on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - // Fork off a child process to dump. - pid_t pid = fork(); - if (pid == 0) { - // In the child process - close(fds[1]); - - // Send parent process the task and thread ports. - MachSendMessage child_message(0); - child_message.AddDescriptor(mach_task_self()); - child_message.AddDescriptor(mach_thread_self()); - - MachPortSender child_sender(machPortName); - if (child_sender.SendMessage(child_message, kTimeoutMs) != KERN_SUCCESS) - exit(1); - - // Wait for the parent process. - uint8_t data; - read(fds[0], &data, 1); - exit(0); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[0]); - - // Read the child's task and thread ports. - MachReceiveMessage child_message; - ASSERT_EQ(KERN_SUCCESS, - parent_recv_port.WaitForMessage(&child_message, kTimeoutMs)); - mach_port_t child_task = child_message.GetTranslatedPort(0); - mach_port_t child_thread = child_message.GetTranslatedPort(1); - ASSERT_NE((mach_port_t)MACH_PORT_NULL, child_task); - ASSERT_NE((mach_port_t)MACH_PORT_NULL, child_thread); - - // Write a minidump of the child process. - bool result = ExceptionHandler::WriteMinidumpForChild(child_task, - child_thread, - tempDir.path(), - DumpNameMDCallback, - this); - ASSERT_EQ(true, result); - - // Ensure that minidump file exists and is > 0 bytes. - ASSERT_FALSE(lastDumpName.empty()); - struct stat st; - ASSERT_EQ(0, stat(lastDumpName.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // Unblock child process - uint8_t data = 1; - (void)write(fds[1], &data, 1); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); -} - -// Test that memory around the instruction pointer is written -// to the dump as a MinidumpMemoryRegion. -TEST_F(ExceptionHandlerTest, InstructionPointerMemory) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = kMemorySize / 2; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - - pid_t pid = fork(); - if (pid == 0) { - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them in the middle - // of the block of memory, because the minidump should contain 128 - // bytes on either side of the instruction pointer. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[1]); - - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_NE((unsigned int)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - EXPECT_TRUE(region); - - EXPECT_EQ(kMemorySize, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kOffset]; - uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes)) == 0); -} - -// Test that the memory region around the instruction pointer is -// bounded correctly on the low end. -TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = 0; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - - pid_t pid = fork(); - if (pid == 0) { - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them at the start - // of the block of memory, to ensure that the memory bounding - // works properly. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[1]); - - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_NE((unsigned int)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - EXPECT_TRUE(region); - - EXPECT_EQ(kMemorySize / 2, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)]; - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes + kOffset, instructions, sizeof(instructions)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes)) == 0); -} - -// Test that the memory region around the instruction pointer is -// bounded correctly on the high end. -TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - // These are defined here so the parent can use them to check the - // data from the minidump afterwards. - // Use 4k here because the OS will hand out a single page even - // if a smaller size is requested, and this test wants to - // test the upper bound of the memory range. - const uint32_t kMemorySize = 4096; // bytes - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - const int kOffset = kMemorySize - sizeof(instructions); - - pid_t pid = fork(); - if (pid == 0) { - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - // Get some executable memory. - char* memory = - reinterpret_cast(mmap(NULL, - kMemorySize, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, - -1, - 0)); - if (!memory) - exit(0); - - // Write some instructions that will crash. Put them at the start - // of the block of memory, to ensure that the memory bounding - // works properly. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - memory_function(); - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[1]); - - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_NE((unsigned int)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - EXPECT_TRUE(region); - - const size_t kPrefixSize = 128; // bytes - EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kPrefixSize]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0); - EXPECT_TRUE(memcmp(bytes + kPrefixSize, - instructions, sizeof(instructions)) == 0); -} - -// Ensure that an extra memory block doesn't get added when the -// instruction pointer is not in mapped memory. -TEST_F(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - pid_t pid = fork(); - if (pid == 0) { - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - // Try calling a NULL pointer. - typedef void (*void_function)(void); - // Volatile markings are needed to keep Clang from generating invalid - // opcodes. See http://crbug.com/498354 for details. - volatile void_function memory_function = - reinterpret_cast(NULL); - memory_function(); - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[1]); - - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is only one memory region - // in the memory list (the thread memory from the single thread). - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_EQ((unsigned int)1, memory_list->region_count()); -} - -static void *Junk(void *) { - sleep(1000000); - return NULL; -} - -// Test that the memory list gets written correctly when multiple -// threads are running. -TEST_F(ExceptionHandlerTest, MemoryListMultipleThreads) { - // Give the child process a pipe to report back on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - pid_t pid = fork(); - if (pid == 0) { - close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); - - // Run an extra thread so >2 memory regions will be written. - pthread_t junk_thread; - if (pthread_create(&junk_thread, NULL, Junk, NULL) == 0) - pthread_detach(junk_thread); - - // Just crash. - Crasher(); - - // not reached - exit(1); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[1]); - - // Wait for the background process to return the minidump file. - close(fds[1]); - char minidump_file[PATH_MAX]; - ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); - ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump, and verify that the memory list can be read. - Minidump minidump(minidump_file); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(memory_list); - // Verify that there are three memory regions: - // one per thread, and one for the instruction pointer memory. - ASSERT_EQ((unsigned int)3, memory_list->region_count()); -} - -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test.cc deleted file mode 100644 index d40c7d986..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test.cc +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_generator_test.cc: Unit tests for google_breakpad::MinidumpGenerator - -#include -#ifndef MAC_OS_X_VERSION_10_6 -#define MAC_OS_X_VERSION_10_6 1060 -#endif -#include -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "client/mac/handler/minidump_generator.h" -#include "client/mac/tests/spawn_child_process.h" -#include "common/mac/MachIPC.h" -#include "common/tests/auto_tempdir.h" -#include "google_breakpad/processor/minidump.h" - -namespace google_breakpad { -// This acts as the log sink for INFO logging from the processor -// logging code. The logging output confuses XCode and makes it think -// there are unit test failures. testlogging.h handles the overriding. -std::ostringstream info_log; -} - -namespace { -using std::string; -using std::vector; -using google_breakpad::AutoTempDir; -using google_breakpad::MinidumpGenerator; -using google_breakpad::MachPortSender; -using google_breakpad::MachReceiveMessage; -using google_breakpad::MachSendMessage; -using google_breakpad::Minidump; -using google_breakpad::MinidumpContext; -using google_breakpad::MinidumpException; -using google_breakpad::MinidumpModule; -using google_breakpad::MinidumpModuleList; -using google_breakpad::MinidumpSystemInfo; -using google_breakpad::MinidumpThread; -using google_breakpad::MinidumpThreadList; -using google_breakpad::ReceivePort; -using testing::Test; -using namespace google_breakpad_test; - -class MinidumpGeneratorTest : public Test { - public: - AutoTempDir tempDir; -}; - -static void *Junk(void* data) { - bool* wait = reinterpret_cast(data); - while (!*wait) { - usleep(10000); - } - return NULL; -} - -TEST_F(MinidumpGeneratorTest, InProcess) { - MinidumpGenerator generator; - string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); - - // Run an extra thread since MinidumpGenerator assumes there - // are 2 or more threads. - pthread_t junk_thread; - bool quit = false; - ASSERT_EQ(0, pthread_create(&junk_thread, NULL, Junk, &quit)); - - ASSERT_TRUE(generator.Write(dump_filename.c_str())); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(dump_filename.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // join the background thread - quit = true; - pthread_join(junk_thread, NULL); - - // Read the minidump, sanity check some data. - Minidump minidump(dump_filename.c_str()); - ASSERT_TRUE(minidump.Read()); - - MinidumpSystemInfo* system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(system_info); - const MDRawSystemInfo* raw_info = system_info->system_info(); - ASSERT_TRUE(raw_info); - EXPECT_EQ(kNativeArchitecture, raw_info->processor_architecture); - - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list); - ASSERT_EQ((unsigned int)1, thread_list->thread_count()); - - MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(main_thread); - MinidumpContext* context = main_thread->GetContext(); - ASSERT_TRUE(context); - EXPECT_EQ(kNativeContext, context->GetContextCPU()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* main_module = module_list->GetMainModule(); - ASSERT_TRUE(main_module); - EXPECT_EQ(GetExecutablePath(), main_module->code_file()); -} - -TEST_F(MinidumpGeneratorTest, OutOfProcess) { - const int kTimeoutMs = 2000; - // Create a mach port to receive the child task on. - char machPortName[128]; - sprintf(machPortName, "MinidumpGeneratorTest.OutOfProcess.%d", getpid()); - ReceivePort parent_recv_port(machPortName); - - // Give the child process a pipe to block on. - int fds[2]; - ASSERT_EQ(0, pipe(fds)); - - // Fork off a child process to dump. - pid_t pid = fork(); - if (pid == 0) { - // In the child process - close(fds[1]); - - // Send parent process the task port. - MachSendMessage child_message(0); - child_message.AddDescriptor(mach_task_self()); - - MachPortSender child_sender(machPortName); - if (child_sender.SendMessage(child_message, kTimeoutMs) != KERN_SUCCESS) { - fprintf(stderr, "Error sending message from child process!\n"); - exit(1); - } - - // Wait for the parent process. - uint8_t data; - read(fds[0], &data, 1); - exit(0); - } - // In the parent process. - ASSERT_NE(-1, pid); - close(fds[0]); - - // Read the child's task port. - MachReceiveMessage child_message; - ASSERT_EQ(KERN_SUCCESS, - parent_recv_port.WaitForMessage(&child_message, kTimeoutMs)); - mach_port_t child_task = child_message.GetTranslatedPort(0); - ASSERT_NE((mach_port_t)MACH_PORT_NULL, child_task); - - // Write a minidump of the child process. - MinidumpGenerator generator(child_task, MACH_PORT_NULL); - string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); - ASSERT_TRUE(generator.Write(dump_filename.c_str())); - - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(dump_filename.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // Unblock child process - uint8_t data = 1; - (void)write(fds[1], &data, 1); - - // Child process should have exited with a zero status. - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - EXPECT_NE(0, WIFEXITED(ret)); - EXPECT_EQ(0, WEXITSTATUS(ret)); - - // Read the minidump, sanity check some data. - Minidump minidump(dump_filename.c_str()); - ASSERT_TRUE(minidump.Read()); - - MinidumpSystemInfo* system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(system_info); - const MDRawSystemInfo* raw_info = system_info->system_info(); - ASSERT_TRUE(raw_info); - EXPECT_EQ(kNativeArchitecture, raw_info->processor_architecture); - - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list); - ASSERT_EQ((unsigned int)1, thread_list->thread_count()); - - MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(main_thread); - MinidumpContext* context = main_thread->GetContext(); - ASSERT_TRUE(context); - EXPECT_EQ(kNativeContext, context->GetContextCPU()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* main_module = module_list->GetMainModule(); - ASSERT_TRUE(main_module); - EXPECT_EQ(GetExecutablePath(), main_module->code_file()); -} - -// This test fails on 10.5, but I don't have easy access to a 10.5 machine, -// so it's simpler to just limit it to 10.6 for now. -#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) && \ - (defined(__x86_64__) || defined(__i386__)) - -TEST_F(MinidumpGeneratorTest, CrossArchitectureDump) { - const int kTimeoutMs = 5000; - // Create a mach port to receive the child task on. - char machPortName[128]; - sprintf(machPortName, - "MinidumpGeneratorTest.CrossArchitectureDump.%d", getpid()); - - ReceivePort parent_recv_port(machPortName); - - // Spawn a child process to dump. - string helper_path = GetHelperPath(); - const char* argv[] = { - helper_path.c_str(), - machPortName, - NULL - }; - pid_t pid = spawn_child_process(argv); - ASSERT_NE(-1, pid); - - // Read the child's task port. - MachReceiveMessage child_message; - ASSERT_EQ(KERN_SUCCESS, - parent_recv_port.WaitForMessage(&child_message, kTimeoutMs)); - mach_port_t child_task = child_message.GetTranslatedPort(0); - ASSERT_NE((mach_port_t)MACH_PORT_NULL, child_task); - - // Write a minidump of the child process. - MinidumpGenerator generator(child_task, MACH_PORT_NULL); - string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); - ASSERT_TRUE(generator.Write(dump_filename.c_str())); - - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(dump_filename.c_str(), &st)); - ASSERT_LT(0, st.st_size); - - // Kill child process. - kill(pid, SIGKILL); - - int ret; - ASSERT_EQ(pid, waitpid(pid, &ret, 0)); - -const MDCPUArchitecture kExpectedArchitecture = -#if defined(__x86_64__) - MD_CPU_ARCHITECTURE_X86 -#elif defined(__i386__) - MD_CPU_ARCHITECTURE_AMD64 -#endif - ; -const uint32_t kExpectedContext = -#if defined(__i386__) - MD_CONTEXT_AMD64 -#elif defined(__x86_64__) - MD_CONTEXT_X86 -#endif - ; - - // Read the minidump, sanity check some data. - Minidump minidump(dump_filename.c_str()); - ASSERT_TRUE(minidump.Read()); - - MinidumpSystemInfo* system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(system_info); - const MDRawSystemInfo* raw_info = system_info->system_info(); - ASSERT_TRUE(raw_info); - EXPECT_EQ(kExpectedArchitecture, raw_info->processor_architecture); - - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list); - ASSERT_EQ((unsigned int)1, thread_list->thread_count()); - - MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(main_thread); - MinidumpContext* context = main_thread->GetContext(); - ASSERT_TRUE(context); - EXPECT_EQ(kExpectedContext, context->GetContextCPU()); - - MinidumpModuleList* module_list = minidump.GetModuleList(); - ASSERT_TRUE(module_list); - const MinidumpModule* main_module = module_list->GetMainModule(); - ASSERT_TRUE(main_module); - EXPECT_EQ(helper_path, main_module->code_file()); -} -#endif // 10.6 && (x86-64 || i386) - -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test_helper.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test_helper.cc deleted file mode 100644 index 4e8ce3cf0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/minidump_generator_test_helper.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_generator_test_helper.cc: A helper program that -// minidump_generator_test.cc can launch to test certain things -// that require a separate executable. - -#include - -#include "client/mac/handler/exception_handler.h" -#include "common/mac/MachIPC.h" - -using google_breakpad::MachPortSender; -using google_breakpad::MachReceiveMessage; -using google_breakpad::MachSendMessage; -using google_breakpad::ReceivePort; - -int main(int argc, char** argv) { - if (argc < 2) - return 1; - - if (strcmp(argv[1], "crash") != 0) { - const int kTimeoutMs = 2000; - // Send parent process the task and thread ports. - MachSendMessage child_message(0); - child_message.AddDescriptor(mach_task_self()); - child_message.AddDescriptor(mach_thread_self()); - - MachPortSender child_sender(argv[1]); - if (child_sender.SendMessage(child_message, kTimeoutMs) != KERN_SUCCESS) { - fprintf(stderr, "Error sending message from child process!\n"); - exit(1); - } - - // Loop forever. - while (true) { - sleep(100); - } - } else if (argc == 3 && strcmp(argv[1], "crash") == 0) { - // Instantiate an OOP exception handler - google_breakpad::ExceptionHandler eh("", NULL, NULL, NULL, true, argv[2]); - // and crash. - int *a = (int*)0x42; - *a = 1; - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/spawn_child_process.h b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/spawn_child_process.h deleted file mode 100644 index e52ff6b65..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/spawn_child_process.h +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utility functions for spawning a helper process using a different -// CPU architecture. - -#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS -#define GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS - -#include -#ifndef MAC_OS_X_VERSION_10_6 -#define MAC_OS_X_VERSION_10_6 1060 -#endif -#include -#include -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 -#include -#endif - -#include -#include - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad_test { - -using std::string; -using std::vector; - -const MDCPUArchitecture kNativeArchitecture = -#if defined(__i386__) - MD_CPU_ARCHITECTURE_X86 -#elif defined(__x86_64__) - MD_CPU_ARCHITECTURE_AMD64 -#elif defined(__ppc__) || defined(__ppc64__) - MD_CPU_ARCHITECTURE_PPC -#else -#error "This file has not been ported to this CPU architecture." -#endif - ; - -const uint32_t kNativeContext = -#if defined(__i386__) - MD_CONTEXT_X86 -#elif defined(__x86_64__) - MD_CONTEXT_AMD64 -#elif defined(__ppc__) || defined(__ppc64__) - MD_CONTEXT_PPC -#else -#error "This file has not been ported to this CPU architecture." -#endif - ; - -string GetExecutablePath() { - char self_path[PATH_MAX]; - uint32_t size = sizeof(self_path); - if (_NSGetExecutablePath(self_path, &size) != 0) - return ""; - return self_path; -} - -string GetHelperPath() { - string helper_path(GetExecutablePath()); - size_t pos = helper_path.rfind('/'); - if (pos == string::npos) - return ""; - - helper_path.erase(pos + 1); - helper_path += "minidump_generator_test_helper"; - return helper_path; -} - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 - -pid_t spawn_child_process(const char** argv) { - posix_spawnattr_t spawnattr; - if (posix_spawnattr_init(&spawnattr) != 0) - return (pid_t)-1; - - cpu_type_t pref_cpu_types[2] = { -#if defined(__x86_64__) - CPU_TYPE_X86, -#elif defined(__i386__) - CPU_TYPE_X86_64, -#endif - CPU_TYPE_ANY - }; - - // Set spawn attributes. - size_t attr_count = sizeof(pref_cpu_types) / sizeof(pref_cpu_types[0]); - size_t attr_ocount = 0; - if (posix_spawnattr_setbinpref_np(&spawnattr, - attr_count, - pref_cpu_types, - &attr_ocount) != 0 || - attr_ocount != attr_count) { - posix_spawnattr_destroy(&spawnattr); - return (pid_t)-1; - } - - // Create an argv array. - vector argv_v; - while (*argv) { - argv_v.push_back(strdup(*argv)); - argv++; - } - argv_v.push_back(NULL); - pid_t new_pid = 0; - int result = posix_spawnp(&new_pid, argv_v[0], NULL, &spawnattr, - &argv_v[0], *_NSGetEnviron()); - posix_spawnattr_destroy(&spawnattr); - - for (unsigned i = 0; i < argv_v.size(); i++) { - free(argv_v[i]); - } - - return result == 0 ? new_pid : -1; -} -#endif - -} // namespace google_breakpad_test - -#endif // GOOGLE_BREAKPAD_CLIENT_MAC_TESTS_SPAWN_CHILD_PROCESS diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/testlogging.h b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/testlogging.h deleted file mode 100644 index c6b6be699..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/testlogging.h +++ /dev/null @@ -1,9 +0,0 @@ -// This file exists to override the processor logging for unit tests, -// since it confuses XCode into thinking unit tests have failed. -#include - -namespace google_breakpad { -extern std::ostringstream info_log; -} - -#define BPLOG_INFO_STREAM google_breakpad::info_log diff --git a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer-inl.h b/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer-inl.h deleted file mode 100644 index 0e12e00b6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer-inl.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_file_writer-inl.h: Minidump file writer implementation. -// -// See minidump_file_writer.h for documentation. - -#ifndef CLIENT_MINIDUMP_FILE_WRITER_INL_H__ -#define CLIENT_MINIDUMP_FILE_WRITER_INL_H__ - -#include - -#include "client/minidump_file_writer.h" -#include "google_breakpad/common/minidump_size.h" - -namespace google_breakpad { - -template -inline bool TypedMDRVA::Allocate() { - allocation_state_ = SINGLE_OBJECT; - return UntypedMDRVA::Allocate(minidump_size::size()); -} - -template -inline bool TypedMDRVA::Allocate(size_t additional) { - allocation_state_ = SINGLE_OBJECT; - return UntypedMDRVA::Allocate(minidump_size::size() + additional); -} - -template -inline bool TypedMDRVA::AllocateArray(size_t count) { - assert(count); - allocation_state_ = ARRAY; - return UntypedMDRVA::Allocate(minidump_size::size() * count); -} - -template -inline bool TypedMDRVA::AllocateObjectAndArray(size_t count, - size_t length) { - assert(count && length); - allocation_state_ = SINGLE_OBJECT_WITH_ARRAY; - return UntypedMDRVA::Allocate(minidump_size::size() + count * length); -} - -template -inline bool TypedMDRVA::CopyIndex(unsigned int index, MDType *item) { - assert(allocation_state_ == ARRAY); - return writer_->Copy( - static_cast(position_ + index * minidump_size::size()), - item, minidump_size::size()); -} - -template -inline bool TypedMDRVA::CopyIndexAfterObject(unsigned int index, - const void *src, - size_t length) { - assert(allocation_state_ == SINGLE_OBJECT_WITH_ARRAY); - return writer_->Copy( - static_cast(position_ + minidump_size::size() - + index * length), - src, length); -} - -template -inline bool TypedMDRVA::Flush() { - return writer_->Copy(position_, &data_, minidump_size::size()); -} - -} // namespace google_breakpad - -#endif // CLIENT_MINIDUMP_FILE_WRITER_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.cc b/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.cc deleted file mode 100644 index a1957f324..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.cc +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_file_writer.cc: Minidump file writer implementation. -// -// See minidump_file_writer.h for documentation. - -#include -#include -#include -#include -#include - -#include "client/minidump_file_writer-inl.h" -#include "common/linux/linux_libc_support.h" -#include "common/string_conversion.h" -#if defined(__linux__) && __linux__ -#include "third_party/lss/linux_syscall_support.h" -#endif - -#if defined(__ANDROID__) -#include - -namespace { - -bool g_need_ftruncate_workaround = false; -bool g_checked_need_ftruncate_workaround = false; - -void CheckNeedsFTruncateWorkAround(int file) { - if (g_checked_need_ftruncate_workaround) { - return; - } - g_checked_need_ftruncate_workaround = true; - - // Attempt an idempotent truncate that chops off nothing and see if we - // run into any sort of errors. - off_t offset = sys_lseek(file, 0, SEEK_END); - if (offset == -1) { - // lseek failed. Don't apply work around. It's unlikely that we can write - // to a minidump with either method. - return; - } - - int result = ftruncate(file, offset); - if (result == -1 && errno == EACCES) { - // It very likely that we are running into the kernel bug in M devices. - // We are going to deploy the workaround for writing minidump files - // without uses of ftruncate(). This workaround should be fine even - // for kernels without the bug. - // See http://crbug.com/542840 for more details. - g_need_ftruncate_workaround = true; - } -} - -bool NeedsFTruncateWorkAround() { - return g_need_ftruncate_workaround; -} - -} // namespace -#endif // defined(__ANDROID__) - -namespace google_breakpad { - -const MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast(-1); - -MinidumpFileWriter::MinidumpFileWriter() - : file_(-1), - close_file_when_destroyed_(true), - position_(0), - size_(0) { -} - -MinidumpFileWriter::~MinidumpFileWriter() { - if (close_file_when_destroyed_) - Close(); -} - -bool MinidumpFileWriter::Open(const char *path) { - assert(file_ == -1); -#if defined(__linux__) && __linux__ - file_ = sys_open(path, O_WRONLY | O_CREAT | O_EXCL, 0600); -#else - file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600); -#endif - - return file_ != -1; -} - -void MinidumpFileWriter::SetFile(const int file) { - assert(file_ == -1); - file_ = file; - close_file_when_destroyed_ = false; -#if defined(__ANDROID__) - CheckNeedsFTruncateWorkAround(file); -#endif -} - -bool MinidumpFileWriter::Close() { - bool result = true; - - if (file_ != -1) { -#if defined(__ANDROID__) - if (!NeedsFTruncateWorkAround() && ftruncate(file_, position_)) { - return false; - } -#else - if (ftruncate(file_, position_)) { - return false; - } -#endif -#if defined(__linux__) && __linux__ - result = (sys_close(file_) == 0); -#else - result = (close(file_) == 0); -#endif - file_ = -1; - } - - return result; -} - -bool MinidumpFileWriter::CopyStringToMDString(const wchar_t *str, - unsigned int length, - TypedMDRVA *mdstring) { - bool result = true; - if (sizeof(wchar_t) == sizeof(uint16_t)) { - // Shortcut if wchar_t is the same size as MDString's buffer - result = mdstring->Copy(str, mdstring->get()->length); - } else { - uint16_t out[2]; - int out_idx = 0; - - // Copy the string character by character - while (length && result) { - UTF32ToUTF16Char(*str, out); - if (!out[0]) - return false; - - // Process one character at a time - --length; - ++str; - - // Append the one or two UTF-16 characters. The first one will be non- - // zero, but the second one may be zero, depending on the conversion from - // UTF-32. - int out_count = out[1] ? 2 : 1; - size_t out_size = sizeof(uint16_t) * out_count; - result = mdstring->CopyIndexAfterObject(out_idx, out, out_size); - out_idx += out_count; - } - } - return result; -} - -bool MinidumpFileWriter::CopyStringToMDString(const char *str, - unsigned int length, - TypedMDRVA *mdstring) { - bool result = true; - uint16_t out[2]; - int out_idx = 0; - - // Copy the string character by character - while (length && result) { - int conversion_count = UTF8ToUTF16Char(str, length, out); - if (!conversion_count) - return false; - - // Move the pointer along based on the nubmer of converted characters - length -= conversion_count; - str += conversion_count; - - // Append the one or two UTF-16 characters - int out_count = out[1] ? 2 : 1; - size_t out_size = sizeof(uint16_t) * out_count; - result = mdstring->CopyIndexAfterObject(out_idx, out, out_size); - out_idx += out_count; - } - return result; -} - -template -bool MinidumpFileWriter::WriteStringCore(const CharType *str, - unsigned int length, - MDLocationDescriptor *location) { - assert(str); - assert(location); - // Calculate the mdstring length by either limiting to |length| as passed in - // or by finding the location of the NULL character. - unsigned int mdstring_length = 0; - if (!length) - length = INT_MAX; - for (; mdstring_length < length && str[mdstring_length]; ++mdstring_length) - ; - - // Allocate the string buffer - TypedMDRVA mdstring(this); - if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(uint16_t))) - return false; - - // Set length excluding the NULL and copy the string - mdstring.get()->length = - static_cast(mdstring_length * sizeof(uint16_t)); - bool result = CopyStringToMDString(str, mdstring_length, &mdstring); - - // NULL terminate - if (result) { - uint16_t ch = 0; - result = mdstring.CopyIndexAfterObject(mdstring_length, &ch, sizeof(ch)); - - if (result) - *location = mdstring.location(); - } - - return result; -} - -bool MinidumpFileWriter::WriteString(const wchar_t *str, unsigned int length, - MDLocationDescriptor *location) { - return WriteStringCore(str, length, location); -} - -bool MinidumpFileWriter::WriteString(const char *str, unsigned int length, - MDLocationDescriptor *location) { - return WriteStringCore(str, length, location); -} - -bool MinidumpFileWriter::WriteMemory(const void *src, size_t size, - MDMemoryDescriptor *output) { - assert(src); - assert(output); - UntypedMDRVA mem(this); - - if (!mem.Allocate(size)) - return false; - if (!mem.Copy(src, mem.size())) - return false; - - output->start_of_memory_range = reinterpret_cast(src); - output->memory = mem.location(); - - return true; -} - -MDRVA MinidumpFileWriter::Allocate(size_t size) { - assert(size); - assert(file_ != -1); -#if defined(__ANDROID__) - if (NeedsFTruncateWorkAround()) { - // If ftruncate() is not available. We simply increase the size beyond the - // current file size. sys_write() will expand the file when data is written - // to it. Because we did not over allocate to fit memory pages, we also - // do not need to ftruncate() the file once we are done. - size_ += size; - - // We don't need to seek since the file is unchanged. - MDRVA current_position = position_; - position_ += static_cast(size); - return current_position; - } -#endif - size_t aligned_size = (size + 7) & ~7; // 64-bit alignment - - if (position_ + aligned_size > size_) { - size_t growth = aligned_size; - size_t minimal_growth = getpagesize(); - - // Ensure that the file grows by at least the size of a memory page - if (growth < minimal_growth) - growth = minimal_growth; - - size_t new_size = size_ + growth; - if (ftruncate(file_, new_size) != 0) - return kInvalidMDRVA; - - size_ = new_size; - } - - MDRVA current_position = position_; - position_ += static_cast(aligned_size); - - return current_position; -} - -bool MinidumpFileWriter::Copy(MDRVA position, const void *src, ssize_t size) { - assert(src); - assert(size); - assert(file_ != -1); - - // Ensure that the data will fit in the allocated space - if (static_cast(size + position) > size_) - return false; - - // Seek and write the data -#if defined(__linux__) && __linux__ - if (sys_lseek(file_, position, SEEK_SET) == static_cast(position)) { - if (sys_write(file_, src, size) == size) { - return true; - } - } -#else - if (lseek(file_, position, SEEK_SET) == static_cast(position)) { - if (write(file_, src, size) == size) { - return true; - } - } -#endif - return false; -} - -bool UntypedMDRVA::Allocate(size_t size) { - assert(size_ == 0); - size_ = size; - position_ = writer_->Allocate(size_); - return position_ != MinidumpFileWriter::kInvalidMDRVA; -} - -bool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) { - assert(src); - assert(size); - assert(pos + size <= position_ + size_); - return writer_->Copy(pos, src, size); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.h b/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.h deleted file mode 100644 index ce32b6d08..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer.h +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_file_writer.h: Implements file-based minidump generation. It's -// intended to be used with the Google Breakpad open source crash handling -// project. - -#ifndef CLIENT_MINIDUMP_FILE_WRITER_H__ -#define CLIENT_MINIDUMP_FILE_WRITER_H__ - -#include - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -class UntypedMDRVA; -template class TypedMDRVA; - -// The user of this class can Open() a file and add minidump streams, data, and -// strings using the definitions in minidump_format.h. Since this class is -// expected to be used in a situation where the current process may be -// damaged, it will not allocate heap memory. -// Sample usage: -// MinidumpFileWriter writer; -// writer.Open("/tmp/minidump.dmp"); -// TypedMDRVA header(&writer_); -// header.Allocate(); -// header->get()->signature = MD_HEADER_SIGNATURE; -// : -// writer.Close(); -// -// An alternative is to use SetFile and provide a file descriptor: -// MinidumpFileWriter writer; -// writer.SetFile(minidump_fd); -// TypedMDRVA header(&writer_); -// header.Allocate(); -// header->get()->signature = MD_HEADER_SIGNATURE; -// : -// writer.Close(); - -class MinidumpFileWriter { -public: - // Invalid MDRVA (Minidump Relative Virtual Address) - // returned on failed allocation - static const MDRVA kInvalidMDRVA; - - MinidumpFileWriter(); - ~MinidumpFileWriter(); - - // Open |path| as the destination of the minidump data. If |path| already - // exists, then Open() will fail. - // Return true on success, or false on failure. - bool Open(const char *path); - - // Sets the file descriptor |file| as the destination of the minidump data. - // Can be used as an alternative to Open() when a file descriptor is - // available. - // Note that |fd| is not closed when the instance of MinidumpFileWriter is - // destroyed. - void SetFile(const int file); - - // Close the current file (that was either created when Open was called, or - // specified with SetFile). - // Return true on success, or false on failure. - bool Close(); - - // Copy the contents of |str| to a MDString and write it to the file. - // |str| is expected to be either UTF-16 or UTF-32 depending on the size - // of wchar_t. - // Maximum |length| of characters to copy from |str|, or specify 0 to use the - // entire NULL terminated string. Copying will stop at the first NULL. - // |location| the allocated location - // Return true on success, or false on failure - bool WriteString(const wchar_t *str, unsigned int length, - MDLocationDescriptor *location); - - // Same as above, except with |str| as a UTF-8 string - bool WriteString(const char *str, unsigned int length, - MDLocationDescriptor *location); - - // Write |size| bytes starting at |src| into the current position. - // Return true on success and set |output| to position, or false on failure - bool WriteMemory(const void *src, size_t size, MDMemoryDescriptor *output); - - // Copies |size| bytes from |src| to |position| - // Return true on success, or false on failure - bool Copy(MDRVA position, const void *src, ssize_t size); - - // Return the current position for writing to the minidump - inline MDRVA position() const { return position_; } - - private: - friend class UntypedMDRVA; - - // Allocates an area of |size| bytes. - // Returns the position of the allocation, or kInvalidMDRVA if it was - // unable to allocate the bytes. - MDRVA Allocate(size_t size); - - // The file descriptor for the output file. - int file_; - - // Whether |file_| should be closed when the instance is destroyed. - bool close_file_when_destroyed_; - - // Current position in buffer - MDRVA position_; - - // Current allocated size - size_t size_; - - // Copy |length| characters from |str| to |mdstring|. These are distinct - // because the underlying MDString is a UTF-16 based string. The wchar_t - // variant may need to create a MDString that has more characters than the - // source |str|, whereas the UTF-8 variant may coalesce characters to form - // a single UTF-16 character. - bool CopyStringToMDString(const wchar_t *str, unsigned int length, - TypedMDRVA *mdstring); - bool CopyStringToMDString(const char *str, unsigned int length, - TypedMDRVA *mdstring); - - // The common templated code for writing a string - template - bool WriteStringCore(const CharType *str, unsigned int length, - MDLocationDescriptor *location); -}; - -// Represents an untyped allocated chunk -class UntypedMDRVA { - public: - explicit UntypedMDRVA(MinidumpFileWriter *writer) - : writer_(writer), - position_(writer->position()), - size_(0) {} - - // Allocates |size| bytes. Must not call more than once. - // Return true on success, or false on failure - bool Allocate(size_t size); - - // Returns the current position or kInvalidMDRVA if allocation failed - inline MDRVA position() const { return position_; } - - // Number of bytes allocated - inline size_t size() const { return size_; } - - // Return size and position - inline MDLocationDescriptor location() const { - MDLocationDescriptor location = { static_cast(size_), - position_ }; - return location; - } - - // Copy |size| bytes starting at |src| into the minidump at |position| - // Return true on success, or false on failure - bool Copy(MDRVA position, const void *src, size_t size); - - // Copy |size| bytes from |src| to the current position - inline bool Copy(const void *src, size_t size) { - return Copy(position_, src, size); - } - - protected: - // Writer we associate with - MinidumpFileWriter *writer_; - - // Position of the start of the data - MDRVA position_; - - // Allocated size - size_t size_; -}; - -// Represents a Minidump object chunk. Additional memory can be allocated at -// the end of the object as a: -// - single allocation -// - Array of MDType objects -// - A MDType object followed by an array -template -class TypedMDRVA : public UntypedMDRVA { - public: - // Constructs an unallocated MDRVA - explicit TypedMDRVA(MinidumpFileWriter *writer) - : UntypedMDRVA(writer), - data_(), - allocation_state_(UNALLOCATED) {} - - inline ~TypedMDRVA() { - // Ensure that the data_ object is written out - if (allocation_state_ != ARRAY) - Flush(); - } - - // Address of object data_ of MDType. This is not declared const as the - // typical usage will be to access the underlying |data_| object as to - // alter its contents. - MDType *get() { return &data_; } - - // Allocates minidump_size::size() bytes. - // Must not call more than once. - // Return true on success, or false on failure - bool Allocate(); - - // Allocates minidump_size::size() + |additional| bytes. - // Must not call more than once. - // Return true on success, or false on failure - bool Allocate(size_t additional); - - // Allocate an array of |count| elements of MDType. - // Must not call more than once. - // Return true on success, or false on failure - bool AllocateArray(size_t count); - - // Allocate an array of |count| elements of |size| after object of MDType - // Must not call more than once. - // Return true on success, or false on failure - bool AllocateObjectAndArray(size_t count, size_t size); - - // Copy |item| to |index| - // Must have been allocated using AllocateArray(). - // Return true on success, or false on failure - bool CopyIndex(unsigned int index, MDType *item); - - // Copy |size| bytes starting at |str| to |index| - // Must have been allocated using AllocateObjectAndArray(). - // Return true on success, or false on failure - bool CopyIndexAfterObject(unsigned int index, const void *src, size_t size); - - // Write data_ - bool Flush(); - - private: - enum AllocationState { - UNALLOCATED = 0, - SINGLE_OBJECT, - ARRAY, - SINGLE_OBJECT_WITH_ARRAY - }; - - MDType data_; - AllocationState allocation_state_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_MINIDUMP_FILE_WRITER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer_unittest.cc b/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer_unittest.cc deleted file mode 100644 index 60c364e68..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer_unittest.cc +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: waylonis@google.com (Dan Waylonis) - -/* - g++ -I../ ../common/convert_UTF.c \ - ../common/string_conversion.cc \ - minidump_file_writer.cc \ - minidump_file_writer_unittest.cc \ - -o minidump_file_writer_unittest - */ - -#include -#include - -#include "minidump_file_writer-inl.h" - -using google_breakpad::MinidumpFileWriter; - -#define ASSERT_TRUE(cond) \ -if (!(cond)) { \ - fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \ - return false; \ -} - -#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2)) -#define ASSERT_NE(e1, e2) ASSERT_TRUE((e1) != (e2)) - -struct StringStructure { - unsigned long integer_value; - MDLocationDescriptor first_string; - MDLocationDescriptor second_string; -}; - -struct ArrayStructure { - unsigned char char_value; - unsigned short short_value; - unsigned long long_value; -}; - -typedef struct { - unsigned long count; - ArrayStructure array[0]; -} ObjectAndArrayStructure; - -static bool WriteFile(const char *path) { - MinidumpFileWriter writer; - if (writer.Open(path)) { - // Test a single structure - google_breakpad::TypedMDRVA strings(&writer); - ASSERT_TRUE(strings.Allocate()); - strings.get()->integer_value = 0xBEEF; - const char *first = "First String"; - ASSERT_TRUE(writer.WriteString(first, 0, &strings.get()->first_string)); - const wchar_t *second = L"Second String"; - ASSERT_TRUE(writer.WriteString(second, 0, &strings.get()->second_string)); - - // Test an array structure - google_breakpad::TypedMDRVA array(&writer); - unsigned int count = 10; - ASSERT_TRUE(array.AllocateArray(count)); - for (unsigned char i = 0; i < count; ++i) { - ArrayStructure local; - local.char_value = i; - local.short_value = i + 1; - local.long_value = i + 2; - ASSERT_TRUE(array.CopyIndex(i, &local)); - } - - // Test an object followed by an array - google_breakpad::TypedMDRVA obj_array(&writer); - ASSERT_TRUE(obj_array.AllocateObjectAndArray(count, - sizeof(ArrayStructure))); - obj_array.get()->count = count; - for (unsigned char i = 0; i < count; ++i) { - ArrayStructure local; - local.char_value = i; - local.short_value = i + 1; - local.long_value = i + 2; - ASSERT_TRUE(obj_array.CopyIndexAfterObject(i, &local, sizeof(local))); - } - } - - return writer.Close(); -} - -static bool CompareFile(const char *path) { - unsigned long expected[] = { -#if defined(__BIG_ENDIAN__) - 0x0000beef, 0x0000001e, 0x00000018, 0x00000020, 0x00000038, 0x00000000, - 0x00000018, 0x00460069, 0x00720073, 0x00740020, 0x00530074, 0x00720069, - 0x006e0067, 0x00000000, 0x0000001a, 0x00530065, 0x0063006f, 0x006e0064, - 0x00200053, 0x00740072, 0x0069006e, 0x00670000, 0x00000001, 0x00000002, - 0x01000002, 0x00000003, 0x02000003, 0x00000004, 0x03000004, 0x00000005, - 0x04000005, 0x00000006, 0x05000006, 0x00000007, 0x06000007, 0x00000008, - 0x07000008, 0x00000009, 0x08000009, 0x0000000a, 0x0900000a, 0x0000000b, - 0x0000000a, 0x00000001, 0x00000002, 0x01000002, 0x00000003, 0x02000003, - 0x00000004, 0x03000004, 0x00000005, 0x04000005, 0x00000006, 0x05000006, - 0x00000007, 0x06000007, 0x00000008, 0x07000008, 0x00000009, 0x08000009, - 0x0000000a, 0x0900000a, 0x0000000b, 0x00000000 -#else - 0x0000beef, 0x0000001e, 0x00000018, 0x00000020, - 0x00000038, 0x00000000, 0x00000018, 0x00690046, - 0x00730072, 0x00200074, 0x00740053, 0x00690072, - 0x0067006e, 0x00000000, 0x0000001a, 0x00650053, - 0x006f0063, 0x0064006e, 0x00530020, 0x00720074, - 0x006e0069, 0x00000067, 0x00011e00, 0x00000002, - 0x00021e01, 0x00000003, 0x00031e02, 0x00000004, - 0x00041e03, 0x00000005, 0x00051e04, 0x00000006, - 0x00061e05, 0x00000007, 0x00071e06, 0x00000008, - 0x00081e07, 0x00000009, 0x00091e08, 0x0000000a, - 0x000a1e09, 0x0000000b, 0x0000000a, 0x00011c00, - 0x00000002, 0x00021c01, 0x00000003, 0x00031c02, - 0x00000004, 0x00041c03, 0x00000005, 0x00051c04, - 0x00000006, 0x00061c05, 0x00000007, 0x00071c06, - 0x00000008, 0x00081c07, 0x00000009, 0x00091c08, - 0x0000000a, 0x000a1c09, 0x0000000b, 0x00000000, -#endif - }; - size_t expected_byte_count = sizeof(expected); - int fd = open(path, O_RDONLY, 0600); - void *buffer = malloc(expected_byte_count); - ASSERT_NE(fd, -1); - ASSERT_TRUE(buffer); - ASSERT_EQ(read(fd, buffer, expected_byte_count), - static_cast(expected_byte_count)); - - char *b1, *b2; - b1 = reinterpret_cast(buffer); - b2 = reinterpret_cast(expected); - while (*b1 == *b2) { - b1++; - b2++; - } - - printf("%p\n", reinterpret_cast(b1 - (char*)buffer)); - - ASSERT_EQ(memcmp(buffer, expected, expected_byte_count), 0); - return true; -} - -static bool RunTests() { - const char *path = "/tmp/minidump_file_writer_unittest.dmp"; - ASSERT_TRUE(WriteFile(path)); - ASSERT_TRUE(CompareFile(path)); - unlink(path); - return true; -} - -extern "C" int main(int argc, const char *argv[]) { - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/moz.build b/toolkit/crashreporter/google-breakpad/src/client/moz.build deleted file mode 100644 index 49a1797be..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SOURCES += [ - 'minidump_file_writer.cc', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '..', -] - -if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-shadow'] diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile deleted file mode 100644 index beeb9448f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Author: Alfred Peng - -CC=cc -CXX=CC - -CPPFLAGS=-g -I../../.. -DNDEBUG -features=extensions -D_REENTRANT -LDFLAGS=-lpthread -lssl -lgnutls-openssl -lelf - -OBJ_DIR=. -BIN_DIR=. - -THREAD_SRC=solaris_lwp.cc -SHARE_SRC=../../minidump_file_writer.cc\ - ../../../common/md5.cc\ - ../../../common/string_conversion.cc\ - ../../../common/solaris/file_id.cc\ - minidump_generator.cc -HANDLER_SRC=exception_handler.cc\ - ../../../common/solaris/guid_creator.cc -SHARE_C_SRC=../../../common/convert_UTF.c - -MINIDUMP_TEST_SRC=minidump_test.cc -EXCEPTION_TEST_SRC=exception_handler_test.cc - -THREAD_OBJ=$(patsubst %.cc,$(OBJ_DIR)/%.o,$(THREAD_SRC)) -SHARE_OBJ=$(patsubst %.cc,$(OBJ_DIR)/%.o,$(SHARE_SRC)) -HANDLER_OBJ=$(patsubst %.cc,$(OBJ_DIR)/%.o,$(HANDLER_SRC)) -SHARE_C_OBJ=$(patsubst %.c,$(OBJ_DIR)/%.o,$(SHARE_C_SRC)) -MINIDUMP_TEST_OBJ=$(patsubst %.cc,$(OBJ_DIR)/%.o, $(MINIDUMP_TEST_SRC))\ - $(THREAD_OBJ) $(SHARE_OBJ) $(SHARE_C_OBJ) $(HANDLER_OBJ) -EXCEPTION_TEST_OBJ=$(patsubst %.cc,$(OBJ_DIR)/%.o, $(EXCEPTION_TEST_SRC))\ - $(THREAD_OBJ) $(SHARE_OBJ) $(SHARE_C_OBJ) $(HANDLER_OBJ) - -BIN=$(BIN_DIR)/minidump_test\ - $(BIN_DIR)/exception_handler_test - -.PHONY:all clean - -all:$(BIN) - -$(BIN_DIR)/minidump_test:$(MINIDUMP_TEST_OBJ) - $(CXX) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ - -$(BIN_DIR)/exception_handler_test:$(EXCEPTION_TEST_OBJ) - $(CXX) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ - -clean: - rm -f $(BIN) *.o *.out *.dmp core ../../minidump_file_writer.o\ - ../../../common/*.o ../../../common/solaris/*.o diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.cc b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.cc deleted file mode 100644 index 7fc8d2557..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include -#include -#include - -#include -#include -#include - -#include "client/solaris/handler/exception_handler.h" -#include "common/solaris/guid_creator.h" -#include "common/solaris/message_output.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Signals that we are interested. -static const int kSigTable[] = { - SIGSEGV, - SIGABRT, - SIGFPE, - SIGILL, - SIGBUS -}; - -std::vector *ExceptionHandler::handler_stack_ = NULL; -int ExceptionHandler::handler_stack_index_ = 0; -pthread_mutex_t ExceptionHandler::handler_stack_mutex_ = - PTHREAD_MUTEX_INITIALIZER; - -ExceptionHandler::ExceptionHandler(const string &dump_path, - FilterCallback filter, - MinidumpCallback callback, - void *callback_context, - bool install_handler) - : filter_(filter), - callback_(callback), - callback_context_(callback_context), - dump_path_(), - installed_handler_(install_handler) { - set_dump_path(dump_path); - - if (install_handler) { - SetupHandler(); - } - - if (install_handler) { - pthread_mutex_lock(&handler_stack_mutex_); - - if (handler_stack_ == NULL) - handler_stack_ = new std::vector; - handler_stack_->push_back(this); - pthread_mutex_unlock(&handler_stack_mutex_); - } -} - -ExceptionHandler::~ExceptionHandler() { - TeardownAllHandlers(); - pthread_mutex_lock(&handler_stack_mutex_); - if (handler_stack_->back() == this) { - handler_stack_->pop_back(); - } else { - print_message1(2, "warning: removing Breakpad handler out of order\n"); - for (std::vector::iterator iterator = - handler_stack_->begin(); - iterator != handler_stack_->end(); - ++iterator) { - if (*iterator == this) { - handler_stack_->erase(iterator); - } - } - } - - if (handler_stack_->empty()) { - // When destroying the last ExceptionHandler that installed a handler, - // clean up the handler stack. - delete handler_stack_; - handler_stack_ = NULL; - } - pthread_mutex_unlock(&handler_stack_mutex_); -} - -bool ExceptionHandler::WriteMinidump() { - return InternalWriteMinidump(0, 0, NULL); -} - -// static -bool ExceptionHandler::WriteMinidump(const string &dump_path, - MinidumpCallback callback, - void *callback_context) { - ExceptionHandler handler(dump_path, NULL, callback, - callback_context, false); - return handler.InternalWriteMinidump(0, 0, NULL); -} - -void ExceptionHandler::SetupHandler() { - // Signal on a different stack to avoid using the stack - // of the crashing lwp. - struct sigaltstack sig_stack; - sig_stack.ss_sp = malloc(MINSIGSTKSZ); - if (sig_stack.ss_sp == NULL) - return; - sig_stack.ss_size = MINSIGSTKSZ; - sig_stack.ss_flags = 0; - - if (sigaltstack(&sig_stack, NULL) < 0) - return; - for (size_t i = 0; i < sizeof(kSigTable) / sizeof(kSigTable[0]); ++i) - SetupHandler(kSigTable[i]); -} - -void ExceptionHandler::SetupHandler(int signo) { - struct sigaction act, old_act; - act.sa_handler = HandleException; - act.sa_flags = SA_ONSTACK; - if (sigaction(signo, &act, &old_act) < 0) - return; - old_handlers_[signo] = old_act.sa_handler; -} - -void ExceptionHandler::TeardownHandler(int signo) { - if (old_handlers_.find(signo) != old_handlers_.end()) { - struct sigaction act; - act.sa_handler = old_handlers_[signo]; - act.sa_flags = 0; - sigaction(signo, &act, 0); - } -} - -void ExceptionHandler::TeardownAllHandlers() { - for (size_t i = 0; i < sizeof(kSigTable) / sizeof(kSigTable[0]); ++i) { - TeardownHandler(kSigTable[i]); - } -} - -// static -void ExceptionHandler::HandleException(int signo) { -//void ExceptionHandler::HandleException(int signo, siginfo_t *sip, ucontext_t *sig_ctx) { - // The context information about the signal is put on the stack of - // the signal handler frame as value parameter. For some reasons, the - // prototype of the handler doesn't declare this information as parameter, we - // will do it by hand. The stack layout for a signal handler frame is here: - // http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libproc/common/Pstack.c#81 - // - // However, if we are being called by another signal handler passing the - // signal up the chain, then we may not have this random extra parameter, - // so we may have to walk the stack to find it. We do the actual work - // on another thread, where it's a little safer, but we want the ebp - // from this frame to find it. - uintptr_t current_ebp = (uintptr_t)_getfp(); - - pthread_mutex_lock(&handler_stack_mutex_); - ExceptionHandler *current_handler = - handler_stack_->at(handler_stack_->size() - ++handler_stack_index_); - pthread_mutex_unlock(&handler_stack_mutex_); - - // Restore original handler. - current_handler->TeardownHandler(signo); - - ucontext_t *sig_ctx = NULL; - if (current_handler->InternalWriteMinidump(signo, current_ebp, &sig_ctx)) { -// if (current_handler->InternalWriteMinidump(signo, &sig_ctx)) { - // Fully handled this exception, safe to exit. - exit(EXIT_FAILURE); - } else { - // Exception not fully handled, will call the next handler in stack to - // process it. - typedef void (*SignalHandler)(int signo); - SignalHandler old_handler = - reinterpret_cast(current_handler->old_handlers_[signo]); - if (old_handler != NULL) - old_handler(signo); - } - - pthread_mutex_lock(&handler_stack_mutex_); - current_handler->SetupHandler(signo); - --handler_stack_index_; - // All the handlers in stack have been invoked to handle the exception, - // normally the process should be terminated and should not reach here. - // In case we got here, ask the OS to handle it to avoid endless loop, - // normally the OS will generate a core and termiate the process. This - // may be desired to debug the program. - if (handler_stack_index_ == 0) - signal(signo, SIG_DFL); - pthread_mutex_unlock(&handler_stack_mutex_); -} - -bool ExceptionHandler::InternalWriteMinidump(int signo, - uintptr_t sighandler_ebp, - ucontext_t **sig_ctx) { - if (filter_ && !filter_(callback_context_)) - return false; - - bool success = false; - GUID guid; - char guid_str[kGUIDStringLength + 1]; - if (CreateGUID(&guid) && GUIDToString(&guid, guid_str, sizeof(guid_str))) { - char minidump_path[PATH_MAX]; - snprintf(minidump_path, sizeof(minidump_path), "%s/%s.dmp", - dump_path_c_, guid_str); - - // Block all the signals we want to process when writing minidump. - // We don't want it to be interrupted. - sigset_t sig_blocked, sig_old; - bool blocked = true; - sigfillset(&sig_blocked); - for (size_t i = 0; i < sizeof(kSigTable) / sizeof(kSigTable[0]); ++i) - sigdelset(&sig_blocked, kSigTable[i]); - if (sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old) != 0) { - blocked = false; - print_message1(2, "HandleException: failed to block signals.\n"); - } - - success = minidump_generator_.WriteMinidumpToFile( - minidump_path, signo, sighandler_ebp, sig_ctx); - - // Unblock the signals. - if (blocked) - sigprocmask(SIG_SETMASK, &sig_old, &sig_old); - - if (callback_) - success = callback_(dump_path_c_, guid_str, callback_context_, success); - } - return success; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.h b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.h deleted file mode 100644 index 4d72485fe..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.h +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: Alfred Peng - -#ifndef CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__ -#define CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__ - -#include -#include -#include - -#include "client/solaris/handler/minidump_generator.h" - -namespace google_breakpad { - -using std::string; - -// -// ExceptionHandler -// -// ExceptionHandler can write a minidump file when an exception occurs, -// or when WriteMinidump() is called explicitly by your program. -// -// To have the exception handler write minidumps when an uncaught exception -// (crash) occurs, you should create an instance early in the execution -// of your program, and keep it around for the entire time you want to -// have crash handling active (typically, until shutdown). -// (NOTE): There should be only one this kind of exception handler -// object per process. -// -// If you want to write minidumps without installing the exception handler, -// you can create an ExceptionHandler with install_handler set to false, -// then call WriteMinidump. You can also use this technique if you want to -// use different minidump callbacks for different call sites. -// -// In either case, a callback function is called when a minidump is written, -// which receives the unqiue id of the minidump. The caller can use this -// id to collect and write additional application state, and to launch an -// external crash-reporting application. -// -// Caller should try to make the callbacks as crash-friendly as possible, -// it should avoid use heap memory allocation as much as possible. -// -class ExceptionHandler { - public: - // A callback function to run before Breakpad performs any substantial - // processing of an exception. A FilterCallback is called before writing - // a minidump. context is the parameter supplied by the user as - // callback_context when the handler was created. - // - // If a FilterCallback returns true, Breakpad will continue processing, - // attempting to write a minidump. If a FilterCallback returns false, - // Breakpad will immediately report the exception as unhandled without - // writing a minidump, allowing another handler the opportunity to handle it. - typedef bool (*FilterCallback)(void *context); - - // A callback function to run after the minidump has been written. - // minidump_id is a unique id for the dump, so the minidump - // file is /.dmp. context is the parameter supplied - // by the user as callback_context when the handler was created. succeeded - // indicates whether a minidump file was successfully written. - // - // If an exception occurred and the callback returns true, Breakpad will - // treat the exception as fully-handled, suppressing any other handlers from - // being notified of the exception. If the callback returns false, Breakpad - // will treat the exception as unhandled, and allow another handler to handle - // it. If there are no other handlers, Breakpad will report the exception to - // the system as unhandled, allowing a debugger or native crash dialog the - // opportunity to handle the exception. Most callback implementations - // should normally return the value of |succeeded|, or when they wish to - // not report an exception of handled, false. Callbacks will rarely want to - // return true directly (unless |succeeded| is true). - typedef bool (*MinidumpCallback)(const char *dump_path, - const char *minidump_id, - void *context, - bool succeeded); - - // Creates a new ExceptionHandler instance to handle writing minidumps. - // Before writing a minidump, the optional filter callback will be called. - // Its return value determines whether or not Breakpad should write a - // minidump. Minidump files will be written to dump_path, and the optional - // callback is called after writing the dump file, as described above. - // If install_handler is true, then a minidump will be written whenever - // an unhandled exception occurs. If it is false, minidumps will only - // be written when WriteMinidump is called. - ExceptionHandler(const string &dump_path, - FilterCallback filter, MinidumpCallback callback, - void *callback_context, - bool install_handler); - ~ExceptionHandler(); - - // Get and Set the minidump path. - string dump_path() const { return dump_path_; } - void set_dump_path(const string &dump_path) { - dump_path_ = dump_path; - dump_path_c_ = dump_path_.c_str(); - } - - // Writes a minidump immediately. This can be used to capture the - // execution state independently of a crash. Returns true on success. - bool WriteMinidump(); - - // Convenience form of WriteMinidump which does not require an - // ExceptionHandler instance. - static bool WriteMinidump(const string &dump_path, - MinidumpCallback callback, - void *callback_context); - - private: - // Setup crash handler. - void SetupHandler(); - // Setup signal handler for a signal. - void SetupHandler(int signo); - // Teardown the handler for a signal. - void TeardownHandler(int signo); - // Teardown all handlers. - void TeardownAllHandlers(); - - // Runs the main loop for the exception handler thread. - static void* ExceptionHandlerThreadMain(void *lpParameter); - - // Signal handler. - static void HandleException(int signo); - - // Write all the information to the dump file. - // If called from a signal handler, sighandler_ebp is the ebp of - // that signal handler's frame, and sig_ctx is an out parameter - // that will be set to point at the ucontext_t that was placed - // on the stack by the kernel. You can pass zero and NULL - // for the second and third parameters if you are not calling - // this from a signal handler. - bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp, - ucontext_t **sig_ctx); - - private: - // The callbacks before and after writing the dump file. - FilterCallback filter_; - MinidumpCallback callback_; - void *callback_context_; - - // The directory in which a minidump will be written, set by the dump_path - // argument to the constructor, or set_dump_path. - string dump_path_; - // C style dump path. Keep this when setting dump path, since calling - // c_str() of std::string when crashing may not be safe. - const char *dump_path_c_; - - // True if the ExceptionHandler installed an unhandled exception filter - // when created (with an install_handler parameter set to true). - bool installed_handler_; - - // Keep the previous handlers for the signal. - typedef void (*sighandler_t)(int); - std::map old_handlers_; - - // The global exception handler stack. This is need becuase there may exist - // multiple ExceptionHandler instances in a process. Each will have itself - // registered in this stack. - static std::vector *handler_stack_; - // The index of the handler that should handle the next exception. - static int handler_stack_index_; - static pthread_mutex_t handler_stack_mutex_; - - // The minidump generator. - MinidumpGenerator minidump_generator_; - - // disallow copy ctor and operator= - explicit ExceptionHandler(const ExceptionHandler &); - void operator=(const ExceptionHandler &); -}; - -} // namespace google_breakpad - -#endif // CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler_test.cc b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler_test.cc deleted file mode 100644 index 6bb8e18d9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler_test.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include - -#include -#include -#include -#include - -#include "client/solaris/handler/exception_handler.h" -#include "client/solaris/handler/solaris_lwp.h" - -using namespace google_breakpad; - -// Thread use this to see if it should stop working. -static bool should_exit = false; - -static int foo2(int arg) { - // Stack variable, used for debugging stack dumps. - int c = 0xcccccccc; - fprintf(stderr, "Thread trying to crash: %x\n", getpid()); - c = *reinterpret_cast(0x5); - return c; -} - -static int foo(int arg) { - // Stack variable, used for debugging stack dumps. - int b = 0xbbbbbbbb; - b = foo2(b); - return b; -} - -static void *thread_crash(void *) { - // Stack variable, used for debugging stack dumps. - int a = 0xaaaaaaaa; - sleep(3); - a = foo(a); - printf("%x\n", a); - return NULL; -} - -static void *thread_main(void *) { - while (!should_exit) - sleep(1); - return NULL; -} - -static void CreateCrashThread() { - pthread_t h; - pthread_create(&h, NULL, thread_crash, NULL); - pthread_detach(h); -} - -// Create working threads. -static void CreateThread(int num) { - pthread_t h; - for (int i = 0; i < num; ++i) { - pthread_create(&h, NULL, thread_main, NULL); - pthread_detach(h); - } -} - -// Callback when minidump written. -static bool MinidumpCallback(const char *dump_path, - const char *minidump_id, - void *context, - bool succeeded) { - int index = reinterpret_cast(context); - if (index == 0) { - should_exit = true; - return true; - } - // Don't process it. - return false; -} - -int main(int argc, char *argv[]) { - int handler_index = 1; - ExceptionHandler handler_ignore(".", NULL, MinidumpCallback, - (void*)handler_index, true); - CreateCrashThread(); - CreateThread(10); - - while (true) - sleep(20); - should_exit = true; - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.cc b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.cc deleted file mode 100644 index 7485025fe..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.cc +++ /dev/null @@ -1,786 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "client/solaris/handler/minidump_generator.h" -#include "client/minidump_file_writer-inl.h" -#include "common/solaris/file_id.h" - -namespace { - -using namespace google_breakpad; - -// Argument for the writer function. -struct WriterArgument { - MinidumpFileWriter *minidump_writer; - - // Pid of the lwp who called WriteMinidumpToFile - int requester_pid; - - // The stack bottom of the lwp which caused the dump. - // Mainly used to find the lwp id of the crashed lwp since signal - // handler may not be called in the lwp who caused it. - uintptr_t crashed_stack_bottom; - - // Id of the crashing lwp. - int crashed_lwpid; - - // Signal number when crash happened. Can be 0 if this is a requested dump. - int signo; - - // The ebp of the signal handler frame on x86. Can be 0 if this is a - // requested dump. - uintptr_t sighandler_ebp; - - // User context when crash happens. Can be NULL if this is a requested dump. - // This is actually an out parameter, but it will be filled in at the start - // of the writer LWP. - ucontext_t *sig_ctx; - - // Used to get information about the lwps. - SolarisLwp *lwp_lister; -}; - -// Holding context information for the callback of finding the crashing lwp. -struct FindCrashLwpContext { - const SolarisLwp *lwp_lister; - uintptr_t crashing_stack_bottom; - int crashing_lwpid; - - FindCrashLwpContext() : - lwp_lister(NULL), - crashing_stack_bottom(0UL), - crashing_lwpid(-1) { - } -}; - -// Callback for list lwps. -// It will compare the stack bottom of the provided lwp with the stack -// bottom of the crashed lwp, it they are eqaul, this lwp is the one -// who crashed. -bool IsLwpCrashedCallback(lwpstatus_t *lsp, void *context) { - FindCrashLwpContext *crashing_context = - static_cast(context); - const SolarisLwp *lwp_lister = crashing_context->lwp_lister; - const prgregset_t *gregs = &(lsp->pr_reg); -#if TARGET_CPU_SPARC - uintptr_t last_ebp = (*gregs)[R_FP]; -#elif TARGET_CPU_X86 - uintptr_t last_ebp = (*gregs)[EBP]; -#endif - uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_ebp); - if (stack_bottom > last_ebp && - stack_bottom == crashing_context->crashing_stack_bottom) { - // Got it. Stop iteration. - crashing_context->crashing_lwpid = lsp->pr_lwpid; - return false; - } - - return true; -} - -// Find the crashing lwpid. -// This is done based on stack bottom comparing. -int FindCrashingLwp(uintptr_t crashing_stack_bottom, - int requester_pid, - const SolarisLwp *lwp_lister) { - FindCrashLwpContext context; - context.lwp_lister = lwp_lister; - context.crashing_stack_bottom = crashing_stack_bottom; - CallbackParam callback_param(IsLwpCrashedCallback, - &context); - lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param); - return context.crashing_lwpid; -} - -bool WriteLwpStack(const SolarisLwp *lwp_lister, - uintptr_t last_esp, - UntypedMDRVA *memory, - MDMemoryDescriptor *loc) { - uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_esp); - if (stack_bottom >= last_esp) { - int size = stack_bottom - last_esp; - if (size > 0) { - if (!memory->Allocate(size)) - return false; - memory->Copy(reinterpret_cast(last_esp), size); - loc->start_of_memory_range = last_esp; - loc->memory = memory->location(); - } - return true; - } - return false; -} - -#if TARGET_CPU_SPARC -bool WriteContext(MDRawContextSPARC *context, ucontext_t *sig_ctx) { - assert(sig_ctx != NULL); - int* regs = sig_ctx->uc_mcontext.gregs; - context->context_flags = MD_CONTEXT_SPARC_FULL; - - context->ccr = (unsigned int)(regs[0]); - context->pc = (unsigned int)(regs[REG_PC]); - context->npc = (unsigned int)(regs[REG_nPC]); - context->y = (unsigned int)(regs[REG_Y]); - context->asi = (unsigned int)(regs[19]); - context->fprs = (unsigned int)(regs[20]); - - for ( int i = 0 ; i < 32; ++i ) { - context->g_r[i] = 0; - } - - for ( int i = 1 ; i < 16; ++i ) { - context->g_r[i] = (uintptr_t)(sig_ctx->uc_mcontext.gregs[i + 3]); - } - context->g_r[30] = (uintptr_t)(((struct frame *)context->g_r[14])->fr_savfp); - - return true; -} - -bool WriteContext(MDRawContextSPARC *context, prgregset_t regs, - prfpregset_t *fp_regs) { - if (!context || !regs) - return false; - - context->context_flags = MD_CONTEXT_SPARC_FULL; - - context->ccr = (uintptr_t)(regs[32]); - context->pc = (uintptr_t)(regs[R_PC]); - context->npc = (uintptr_t)(regs[R_nPC]); - context->y = (uintptr_t)(regs[R_Y]); - context->asi = (uintptr_t)(regs[36]); - context->fprs = (uintptr_t)(regs[37]); - for ( int i = 0 ; i < 32 ; ++i ){ - context->g_r[i] = (uintptr_t)(regs[i]); - } - - return true; -} -#elif TARGET_CPU_X86 -bool WriteContext(MDRawContextX86 *context, prgregset_t regs, - prfpregset_t *fp_regs) { - if (!context || !regs) - return false; - - context->context_flags = MD_CONTEXT_X86_FULL; - - context->cs = regs[CS]; - context->ds = regs[DS]; - context->es = regs[ES]; - context->fs = regs[FS]; - context->gs = regs[GS]; - context->ss = regs[SS]; - context->edi = regs[EDI]; - context->esi = regs[ESI]; - context->ebx = regs[EBX]; - context->edx = regs[EDX]; - context->ecx = regs[ECX]; - context->eax = regs[EAX]; - context->ebp = regs[EBP]; - context->eip = regs[EIP]; - context->esp = regs[UESP]; - context->eflags = regs[EFL]; - - return true; -} -#endif /* TARGET_CPU_XXX */ - -// Write information about a crashed Lwp. -// When a lwp crash, kernel will write something on the stack for processing -// signal. This makes the current stack not reliable, and our stack walker -// won't figure out the whole call stack for this. So we write the stack at the -// time of the crash into the minidump file, not the current stack. -bool WriteCrashedLwpStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - const lwpstatus_t *lsp, - MDRawThread *lwp) { - assert(writer_args->sig_ctx != NULL); - - lwp->thread_id = lsp->pr_lwpid; - -#if TARGET_CPU_SPARC - UntypedMDRVA memory(minidump_writer); - if (!WriteLwpStack(writer_args->lwp_lister, - writer_args->sig_ctx->uc_mcontext.gregs[REG_O6], - &memory, - &lwp->stack)) - return false; - - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - lwp->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextSPARC)); - return WriteContext(context.get(), writer_args->sig_ctx); -#elif TARGET_CPU_X86 - UntypedMDRVA memory(minidump_writer); - if (!WriteLwpStack(writer_args->lwp_lister, - writer_args->sig_ctx->uc_mcontext.gregs[UESP], - &memory, - &lwp->stack)) - return false; - - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - lwp->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextX86)); - return WriteContext(context.get(), - (int *)&writer_args->sig_ctx->uc_mcontext.gregs, - &writer_args->sig_ctx->uc_mcontext.fpregs); -#endif -} - -bool WriteLwpStream(MinidumpFileWriter *minidump_writer, - const SolarisLwp *lwp_lister, - const lwpstatus_t *lsp, MDRawThread *lwp) { - prfpregset_t fp_regs = lsp->pr_fpreg; - const prgregset_t *gregs = &(lsp->pr_reg); - UntypedMDRVA memory(minidump_writer); -#if TARGET_CPU_SPARC - if (!WriteLwpStack(lwp_lister, - (*gregs)[R_SP], - &memory, - &lwp->stack)) - return false; - - // Write context - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - // should be the thread_id - lwp->thread_id = lsp->pr_lwpid; - lwp->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextSPARC)); -#elif TARGET_CPU_X86 - if (!WriteLwpStack(lwp_lister, - (*gregs)[UESP], - &memory, - &lwp->stack)) - return false; - - // Write context - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - // should be the thread_id - lwp->thread_id = lsp->pr_lwpid; - lwp->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextX86)); -#endif /* TARGET_CPU_XXX */ - return WriteContext(context.get(), (int *)gregs, &fp_regs); -} - -bool WriteCPUInformation(MDRawSystemInfo *sys_info) { - struct utsname uts; - char *major, *minor, *build; - - sys_info->number_of_processors = sysconf(_SC_NPROCESSORS_CONF); - sys_info->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN; - if (uname(&uts) != -1) { - // Match "i86pc" as X86 architecture. - if (strcmp(uts.machine, "i86pc") == 0) - sys_info->processor_architecture = MD_CPU_ARCHITECTURE_X86; - else if (strcmp(uts.machine, "sun4u") == 0) - sys_info->processor_architecture = MD_CPU_ARCHITECTURE_SPARC; - } - - major = uts.release; - minor = strchr(major, '.'); - *minor = '\0'; - ++minor; - sys_info->major_version = atoi(major); - sys_info->minor_version = atoi(minor); - - build = strchr(uts.version, '_'); - ++build; - sys_info->build_number = atoi(build); - - return true; -} - -bool WriteOSInformation(MinidumpFileWriter *minidump_writer, - MDRawSystemInfo *sys_info) { - sys_info->platform_id = MD_OS_SOLARIS; - - struct utsname uts; - if (uname(&uts) != -1) { - char os_version[512]; - size_t space_left = sizeof(os_version); - memset(os_version, 0, space_left); - const char *os_info_table[] = { - uts.sysname, - uts.release, - uts.version, - uts.machine, - "OpenSolaris", - NULL - }; - for (const char **cur_os_info = os_info_table; - *cur_os_info != NULL; - ++cur_os_info) { - if (cur_os_info != os_info_table && space_left > 1) { - strcat(os_version, " "); - --space_left; - } - if (space_left > strlen(*cur_os_info)) { - strcat(os_version, *cur_os_info); - space_left -= strlen(*cur_os_info); - } else { - break; - } - } - - MDLocationDescriptor location; - if (!minidump_writer->WriteString(os_version, 0, &location)) - return false; - sys_info->csd_version_rva = location.rva; - } - return true; -} - -// Callback context for get writting lwp information. -struct LwpInfoCallbackCtx { - MinidumpFileWriter *minidump_writer; - const WriterArgument *writer_args; - TypedMDRVA *list; - int lwp_index; -}; - -bool LwpInformationCallback(lwpstatus_t *lsp, void *context) { - bool success = true; - LwpInfoCallbackCtx *callback_context = - static_cast(context); - - // The current lwp is the one to handle the crash. Ignore it. - if (lsp->pr_lwpid != pthread_self()) { - LwpInfoCallbackCtx *callback_context = - static_cast(context); - MDRawThread lwp; - memset(&lwp, 0, sizeof(MDRawThread)); - - if (lsp->pr_lwpid != callback_context->writer_args->crashed_lwpid || - callback_context->writer_args->sig_ctx == NULL) { - success = WriteLwpStream(callback_context->minidump_writer, - callback_context->writer_args->lwp_lister, - lsp, &lwp); - } else { - success = WriteCrashedLwpStream(callback_context->minidump_writer, - callback_context->writer_args, - lsp, &lwp); - } - if (success) { - callback_context->list->CopyIndexAfterObject( - callback_context->lwp_index++, - &lwp, sizeof(MDRawThread)); - } - } - - return success; -} - -bool WriteLwpListStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - // Get the lwp information. - const SolarisLwp *lwp_lister = writer_args->lwp_lister; - int lwp_count = lwp_lister->GetLwpCount(); - if (lwp_count < 0) - return false; - TypedMDRVA list(minidump_writer); - if (!list.AllocateObjectAndArray(lwp_count - 1, sizeof(MDRawThread))) - return false; - dir->stream_type = MD_THREAD_LIST_STREAM; - dir->location = list.location(); - list.get()->number_of_threads = lwp_count - 1; - - LwpInfoCallbackCtx context; - context.minidump_writer = minidump_writer; - context.writer_args = writer_args; - context.list = &list; - context.lwp_index = 0; - CallbackParam callback_param(LwpInformationCallback, - &context); - int written = - lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param); - return written == lwp_count; -} - -bool WriteCVRecord(MinidumpFileWriter *minidump_writer, - MDRawModule *module, - const char *module_path, - char *realname) { - TypedMDRVA cv(minidump_writer); - - char path[PATH_MAX]; - const char *module_name = module_path ? module_path : ""; - snprintf(path, sizeof(path), "/proc/self/object/%s", module_name); - - size_t module_name_length = strlen(realname); - if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t))) - return false; - if (!cv.CopyIndexAfterObject(0, realname, module_name_length)) - return false; - - module->cv_record = cv.location(); - MDCVInfoPDB70 *cv_ptr = cv.get(); - memset(cv_ptr, 0, sizeof(MDCVInfoPDB70)); - cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE; - cv_ptr->age = 0; - - // Get the module identifier - FileID file_id(path); - unsigned char identifier[16]; - - if (file_id.ElfFileIdentifier(identifier)) { - cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 | - (uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 | - (uint32_t)identifier[3]; - cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5]; - cv_ptr->signature.data3 = (uint32_t)identifier[6] << 8 | identifier[7]; - cv_ptr->signature.data4[0] = identifier[8]; - cv_ptr->signature.data4[1] = identifier[9]; - cv_ptr->signature.data4[2] = identifier[10]; - cv_ptr->signature.data4[3] = identifier[11]; - cv_ptr->signature.data4[4] = identifier[12]; - cv_ptr->signature.data4[5] = identifier[13]; - cv_ptr->signature.data4[6] = identifier[14]; - cv_ptr->signature.data4[7] = identifier[15]; - } - return true; -} - -struct ModuleInfoCallbackCtx { - MinidumpFileWriter *minidump_writer; - const WriterArgument *writer_args; - TypedMDRVA *list; - int module_index; -}; - -bool ModuleInfoCallback(const ModuleInfo &module_info, void *context) { - ModuleInfoCallbackCtx *callback_context = - static_cast(context); - // Skip those modules without name, or those that are not modules. - if (strlen(module_info.name) == 0) - return true; - - MDRawModule module; - memset(&module, 0, sizeof(module)); - MDLocationDescriptor loc; - char path[PATH_MAX]; - char buf[PATH_MAX]; - char *realname; - int count; - - snprintf(path, sizeof (path), "/proc/self/path/%s", module_info.name); - if ((count = readlink(path, buf, PATH_MAX)) < 0) - return false; - buf[count] = '\0'; - - if ((realname = strrchr(buf, '/')) == NULL) - return false; - realname++; - - if (!callback_context->minidump_writer->WriteString(realname, 0, &loc)) - return false; - - module.base_of_image = (uint64_t)module_info.start_addr; - module.size_of_image = module_info.size; - module.module_name_rva = loc.rva; - - if (!WriteCVRecord(callback_context->minidump_writer, &module, - module_info.name, realname)) - return false; - - callback_context->list->CopyIndexAfterObject( - callback_context->module_index++, &module, MD_MODULE_SIZE); - return true; -} - -bool WriteModuleListStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - TypedMDRVA list(minidump_writer); - int module_count = writer_args->lwp_lister->GetModuleCount(); - - if (module_count <= 0 || - !list.AllocateObjectAndArray(module_count, MD_MODULE_SIZE)) { - return false; - } - - dir->stream_type = MD_MODULE_LIST_STREAM; - dir->location = list.location(); - list.get()->number_of_modules = module_count; - ModuleInfoCallbackCtx context; - context.minidump_writer = minidump_writer; - context.writer_args = writer_args; - context.list = &list; - context.module_index = 0; - CallbackParam callback(ModuleInfoCallback, &context); - return writer_args->lwp_lister->ListModules(&callback) == module_count; -} - -bool WriteSystemInfoStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - TypedMDRVA sys_info(minidump_writer); - - if (!sys_info.Allocate()) - return false; - - dir->stream_type = MD_SYSTEM_INFO_STREAM; - dir->location = sys_info.location(); - - return WriteCPUInformation(sys_info.get()) && - WriteOSInformation(minidump_writer, sys_info.get()); -} - -bool WriteExceptionStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - // This happenes when this is not a crash, but a requested dump. - if (writer_args->sig_ctx == NULL) - return false; - - TypedMDRVA exception(minidump_writer); - if (!exception.Allocate()) - return false; - - dir->stream_type = MD_EXCEPTION_STREAM; - dir->location = exception.location(); - exception.get()->thread_id = writer_args->crashed_lwpid; - exception.get()->exception_record.exception_code = writer_args->signo; - exception.get()->exception_record.exception_flags = 0; - -#if TARGET_CPU_SPARC - if (writer_args->sig_ctx != NULL) { - exception.get()->exception_record.exception_address = - writer_args->sig_ctx->uc_mcontext.gregs[REG_PC]; - } else { - return true; - } - - // Write context of the exception. - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - exception.get()->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextSPARC)); - return WriteContext(context.get(), writer_args->sig_ctx); -#elif TARGET_CPU_X86 - if (writer_args->sig_ctx != NULL) { - exception.get()->exception_record.exception_address = - writer_args->sig_ctx->uc_mcontext.gregs[EIP]; - } else { - return true; - } - - // Write context of the exception. - TypedMDRVA context(minidump_writer); - if (!context.Allocate()) - return false; - exception.get()->thread_context = context.location(); - memset(context.get(), 0, sizeof(MDRawContextX86)); - return WriteContext(context.get(), - (int *)&writer_args->sig_ctx->uc_mcontext.gregs, - NULL); -#endif -} - -bool WriteMiscInfoStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - TypedMDRVA info(minidump_writer); - - if (!info.Allocate()) - return false; - - dir->stream_type = MD_MISC_INFO_STREAM; - dir->location = info.location(); - info.get()->size_of_info = sizeof(MDRawMiscInfo); - info.get()->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID; - info.get()->process_id = writer_args->requester_pid; - - return true; -} - -bool WriteBreakpadInfoStream(MinidumpFileWriter *minidump_writer, - const WriterArgument *writer_args, - MDRawDirectory *dir) { - TypedMDRVA info(minidump_writer); - - if (!info.Allocate()) - return false; - - dir->stream_type = MD_BREAKPAD_INFO_STREAM; - dir->location = info.location(); - - info.get()->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; - info.get()->dump_thread_id = getpid(); - info.get()->requesting_thread_id = writer_args->requester_pid; - return true; -} - -class AutoLwpResumer { - public: - AutoLwpResumer(SolarisLwp *lwp) : lwp_(lwp) {} - ~AutoLwpResumer() { lwp_->ControlAllLwps(false); } - private: - SolarisLwp *lwp_; -}; - -// Prototype of writer functions. -typedef bool (*WriteStreamFN)(MinidumpFileWriter *, - const WriterArgument *, - MDRawDirectory *); - -// Function table to writer a full minidump. -const WriteStreamFN writers[] = { - WriteLwpListStream, - WriteModuleListStream, - WriteSystemInfoStream, - WriteExceptionStream, - WriteMiscInfoStream, - WriteBreakpadInfoStream, -}; - -// Will call each writer function in the writers table. -//void* MinidumpGenerator::Write(void *argument) { -void* Write(void *argument) { - WriterArgument *writer_args = static_cast(argument); - - if (!writer_args->lwp_lister->ControlAllLwps(true)) - return NULL; - - AutoLwpResumer lwpResumer(writer_args->lwp_lister); - - if (writer_args->sighandler_ebp != 0 && - writer_args->lwp_lister->FindSigContext(writer_args->sighandler_ebp, - &writer_args->sig_ctx)) { - writer_args->crashed_stack_bottom = - writer_args->lwp_lister->GetLwpStackBottom( -#if TARGET_CPU_SPARC - writer_args->sig_ctx->uc_mcontext.gregs[REG_O6] -#elif TARGET_CPU_X86 - writer_args->sig_ctx->uc_mcontext.gregs[UESP] -#endif - ); - - int crashed_lwpid = FindCrashingLwp(writer_args->crashed_stack_bottom, - writer_args->requester_pid, - writer_args->lwp_lister); - if (crashed_lwpid > 0) - writer_args->crashed_lwpid = crashed_lwpid; - } - - MinidumpFileWriter *minidump_writer = writer_args->minidump_writer; - TypedMDRVA header(minidump_writer); - TypedMDRVA dir(minidump_writer); - if (!header.Allocate()) - return 0; - - int writer_count = sizeof(writers) / sizeof(writers[0]); - // Need directory space for all writers. - if (!dir.AllocateArray(writer_count)) - return 0; - header.get()->signature = MD_HEADER_SIGNATURE; - header.get()->version = MD_HEADER_VERSION; - header.get()->time_date_stamp = time(NULL); - header.get()->stream_count = writer_count; - header.get()->stream_directory_rva = dir.position(); - - int dir_index = 0; - MDRawDirectory local_dir; - for (int i = 0; i < writer_count; ++i) { - if ((*writers[i])(minidump_writer, writer_args, &local_dir)) - dir.CopyIndex(dir_index++, &local_dir); - } - - return 0; -} - -} // namespace - -namespace google_breakpad { - -MinidumpGenerator::MinidumpGenerator() { -} - -MinidumpGenerator::~MinidumpGenerator() { -} - -// Write minidump into file. -// It runs in a different thread from the crashing thread. -bool MinidumpGenerator::WriteMinidumpToFile(const char *file_pathname, - int signo, - uintptr_t sighandler_ebp, - ucontext_t **sig_ctx) const { - // The exception handler thread. - pthread_t handler_thread; - - assert(file_pathname != NULL); - - if (file_pathname == NULL) - return false; - - MinidumpFileWriter minidump_writer; - if (minidump_writer.Open(file_pathname)) { - WriterArgument argument; - memset(&argument, 0, sizeof(argument)); - SolarisLwp lwp_lister(getpid()); - argument.lwp_lister = &lwp_lister; - argument.minidump_writer = &minidump_writer; - argument.requester_pid = getpid(); - argument.crashed_lwpid = pthread_self(); - argument.signo = signo; - argument.sighandler_ebp = sighandler_ebp; - argument.sig_ctx = NULL; - - pthread_create(&handler_thread, NULL, Write, (void *)&argument); - pthread_join(handler_thread, NULL); - return true; - } - - return false; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.h b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.h deleted file mode 100644 index 882f9e1de..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_generator.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#ifndef CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__ -#define CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__ - -#include - -#include "client/minidump_file_writer.h" -#include "client/solaris/handler/solaris_lwp.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// -// MinidumpGenerator -// -// A minidump generator should be created before any exception happen. -// -class MinidumpGenerator { - // Callback run for writing lwp information in the process. - friend bool LwpInformationCallback(lwpstatus_t *lsp, void *context); - - // Callback run for writing module information in the process. - friend bool ModuleInfoCallback(const ModuleInfo &module_info, void *context); - - public: - MinidumpGenerator(); - - ~MinidumpGenerator(); - - // Write minidump. - bool WriteMinidumpToFile(const char *file_pathname, - int signo, - uintptr_t sighandler_ebp, - ucontext_t **sig_ctx) const; -}; - -} // namespace google_breakpad - -#endif // CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_test.cc b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_test.cc deleted file mode 100644 index 33302d86a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/minidump_test.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include - -#include "client/minidump_file_writer.h" -#include "client/solaris/handler/minidump_generator.h" - -using std::string; -using google_breakpad::MinidumpGenerator; - -static bool doneWritingReport = false; - -static void *Reporter(void *) { - char buffer[PATH_MAX]; - MinidumpGenerator md; - - // Write it to the desktop - snprintf(buffer, sizeof(buffer), "./minidump_test.out"); - fprintf(stdout, "Writing %s\n", buffer); - - md.WriteMinidumpToFile(buffer, 0, 0, NULL); - doneWritingReport = true; - - return NULL; -} - -static void SleepyFunction() { - while (!doneWritingReport) { - usleep(100); - } -} - -int main(int argc, char * const argv[]) { - pthread_t reporter_thread; - - if (pthread_create(&reporter_thread, NULL, Reporter, NULL) == 0) { - pthread_detach(reporter_thread); - } else { - perror("pthread_create"); - } - - SleepyFunction(); - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/moz.build b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/moz.build deleted file mode 100644 index 3442ac0f8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SOURCES += [ - 'exception_handler.cc', - 'minidump_generator.cc', - 'solaris_lwp.cc', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../../..', -] - diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.cc b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.cc deleted file mode 100644 index 0148997ad..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.cc +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "client/solaris/handler/solaris_lwp.h" -#include "common/solaris/message_output.h" - -using namespace google_breakpad; - -// This unamed namespace contains helper function. -namespace { - -uintptr_t stack_base_address = 0; -static const int HEADER_MAX = 2000; -static const int MAP_MAX = 1000; - -// Context information for the callbacks when validating address by listing -// modules. -struct AddressValidatingContext { - uintptr_t address; - bool is_mapped; - - AddressValidatingContext() : address(0UL), is_mapped(false) { - } -}; - -// Convert from string to int. -static bool LocalAtoi(char *s, int *r) { - assert(s != NULL); - assert(r != NULL); - char *endptr = NULL; - int ret = strtol(s, &endptr, 10); - if (endptr == s) - return false; - *r = ret; - return true; -} - -// Callback invoked for each mapped module. -// It uses the module's adderss range to validate the address. -static bool AddressNotInModuleCallback(const ModuleInfo &module_info, - void *context) { - AddressValidatingContext *addr = - reinterpret_cast(context); - if (addr->is_mapped = ((module_info.start_addr > 0) && - (addr->address >= module_info.start_addr) && - (addr->address <= module_info.start_addr + - module_info.size))) { - stack_base_address = module_info.start_addr + module_info.size; - } - - return !addr->is_mapped; -} - -static int IterateLwpAll(int pid, - CallbackParam *callback_param) { - char lwp_path[40]; - DIR *dir; - int count = 0; - - snprintf(lwp_path, sizeof (lwp_path), "/proc/%d/lwp", (int)pid); - if ((dir = opendir(lwp_path)) == NULL) - return -1; - - struct dirent *entry = NULL; - while ((entry = readdir(dir)) != NULL) { - if ((strcmp(entry->d_name, ".") != 0) && - (strcmp(entry->d_name, "..") != 0)) { - int lwpid = 0; - int last_pid = 0; - if (LocalAtoi(entry->d_name, &lwpid) && last_pid != lwpid) { - last_pid = lwpid; - ++count; - if (callback_param && - !(callback_param->call_back)(lwpid, callback_param->context)) { - break; - } - } - } - } - - closedir(dir); - return count; -} - -#if defined(__i386) && !defined(NO_FRAME_POINTER) -void *GetNextFrame(void **last_ebp) { - void *sp = *last_ebp; - if ((unsigned long)sp == (unsigned long)last_ebp) - return NULL; - if ((unsigned long)sp & (sizeof(void *) - 1)) - return NULL; - if ((unsigned long)sp - (unsigned long)last_ebp > 100000) - return NULL; - return sp; -} -#elif defined(__sparc) -void *GetNextFrame(void *last_ebp) { - return reinterpret_cast(last_ebp)->fr_savfp; -} -#else -void *GetNextFrame(void **last_ebp) { - return reinterpret_cast(last_ebp); -} -#endif - - -class AutoCloser { - public: - AutoCloser(int fd) : fd_(fd) {} - ~AutoCloser() { if (fd_) close(fd_); } - private: - int fd_; -}; - -// Control the execution of the lwp. -// Suspend/Resume lwp based on the value of context. -static bool ControlLwp(int lwpid, void *context) { - // The current thread is the one to handle the crash. Ignore it. - if (lwpid != pthread_self()) { - int ctlfd; - char procname[PATH_MAX]; - bool suspend = *(bool *)context; - - // Open the /proc/$pid/lwp/$lwpid/lwpctl files - snprintf(procname, sizeof (procname), "/proc/self/lwp/%d/lwpctl", lwpid); - - if ((ctlfd = open(procname, O_WRONLY|O_EXCL)) < 0) { - print_message2(2, "failed to open %s in ControlLwp\n", procname); - return false; - } - - AutoCloser autocloser(ctlfd); - - long ctl[2]; - ctl[0] = suspend ? PCSTOP : PCRUN; - ctl[1] = 0; - if (write(ctlfd, ctl, sizeof (ctl)) != sizeof (ctl)) { - print_message2(2, "failed in lwp %d\n", lwpid); - return false; - } - } - - return true; -} - -/* - * Utility function to read the contents of a file that contains a - * prheader_t at the start (/proc/$pid/lstatus or /proc/$pid/lpsinfo). - * Return true on success. - */ -static bool read_lfile(int pid, const char *lname, prheader_t *lhp) { - char lpath[PATH_MAX]; - struct stat statb; - int fd; - size_t size; - - snprintf(lpath, sizeof (lpath), "/proc/%d/%s", pid, lname); - if ((fd = open(lpath, O_RDONLY)) < 0) { - print_message2(2, "failed to open %s in read_lfile\n", lpath); - return false; - } - - AutoCloser autocloser(fd); - - if (fstat(fd, &statb) != 0) - return false; - - size = statb.st_size; - if ((size / sizeof (prheader_t)) + 32 > HEADER_MAX) { - print_message1(2, "map size overflow\n"); - return false; - } - - if (pread(fd, lhp, size, 0) <= sizeof (prheader_t)) - return false; - - return true; -} - -} // namespace - -namespace google_breakpad { - -SolarisLwp::SolarisLwp(int pid) : pid_(pid) { -} - -SolarisLwp::~SolarisLwp() { -} - -int SolarisLwp::ControlAllLwps(bool suspend) { - CallbackParam callback_param(ControlLwp, &suspend); - return IterateLwpAll(pid_, &callback_param); -} - -int SolarisLwp::GetLwpCount() const { - return IterateLwpAll(pid_, NULL); -} - -int SolarisLwp::Lwp_iter_all(int pid, - CallbackParam *callback_param) const { - lwpstatus_t *Lsp; - lwpstatus_t *sp; - prheader_t lphp[HEADER_MAX]; - prheader_t lhp[HEADER_MAX]; - prheader_t *Lphp = lphp; - prheader_t *Lhp = lhp; - lwpsinfo_t *Lpsp; - long nstat; - long ninfo; - int rv = 0; - - /* - * The /proc/pid/lstatus file has the array of lwpstatus_t's and the - * /proc/pid/lpsinfo file has the array of lwpsinfo_t's. - */ - if (read_lfile(pid, "lstatus", Lhp) == NULL) - return -1; - if (read_lfile(pid, "lpsinfo", Lphp) == NULL) { - return -1; - } - - Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1); - Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1); - - for (ninfo = Lphp->pr_nent; ninfo != 0; --ninfo) { - if (Lpsp->pr_sname != 'Z') { - sp = Lsp; - Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize); - } else { - sp = NULL; - } - if (callback_param && - !(callback_param->call_back)(sp, callback_param->context)) - break; - ++rv; - Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize); - } - - return rv; -} - -uintptr_t SolarisLwp::GetLwpStackBottom(uintptr_t current_esp) const { - AddressValidatingContext addr; - addr.address = current_esp; - CallbackParam callback_param(AddressNotInModuleCallback, - &addr); - ListModules(&callback_param); - return stack_base_address; -} - -int SolarisLwp::GetModuleCount() const { - return ListModules(NULL); -} - -int SolarisLwp::ListModules( - CallbackParam *callback_param) const { - const char *maps_path = "/proc/self/map"; - struct stat status; - int fd = 0, num; - prmap_t map_array[MAP_MAX]; - prmap_t *maps = map_array; - size_t size; - - if ((fd = open(maps_path, O_RDONLY)) == -1) { - print_message2(2, "failed to open %s in ListModules\n", maps_path); - return -1; - } - - AutoCloser autocloser(fd); - - if (fstat(fd, &status)) - return -1; - - /* - * Determine number of mappings, this value must be - * larger than the actual module count - */ - size = status.st_size; - if ((num = (int)(size / sizeof (prmap_t))) > MAP_MAX) { - print_message1(2, "map size overflow\n"); - return -1; - } - - if (read(fd, (void *)maps, size) < 0) { - print_message2(2, "failed to read %d\n", fd); - return -1; - } - - prmap_t *_maps; - int _num; - int module_count = 0; - - /* - * Scan each mapping - note it is assummed that the mappings are - * presented in order. We fill holes between mappings. On intel - * the last mapping is usually the data segment of ld.so.1, after - * this comes a red zone into which non-fixed mapping won't get - * place. Thus we can simply bail from the loop after seeing the - * last mapping. - */ - for (_num = 0, _maps = maps; _num < num; ++_num, ++_maps) { - ModuleInfo module; - char *name = _maps->pr_mapname; - - memset(&module, 0, sizeof (module)); - module.start_addr = _maps->pr_vaddr; - module.size = _maps->pr_size; - if (strlen(name) > 0) { - int objectfd = 0; - char path[PATH_MAX]; - char buf[SELFMAG]; - - snprintf(path, sizeof (path), "/proc/self/object/%s", name); - if ((objectfd = open(path, O_RDONLY)) < 0) { - print_message1(2, "can't open module file\n"); - continue; - } - - AutoCloser autocloser(objectfd); - - if (read(objectfd, buf, SELFMAG) != SELFMAG) { - print_message1(2, "can't read module file\n"); - continue; - } - if (buf[0] != ELFMAG0 || buf[1] != ELFMAG1 || - buf[2] != ELFMAG2 || buf[3] != ELFMAG3) { - continue; - } - - strncpy(module.name, name, sizeof (module.name) - 1); - ++module_count; - } - if (callback_param && - (!callback_param->call_back(module, callback_param->context))) { - break; - } - } - - return module_count; -} - -// Check if the address is a valid virtual address. -// If the address is in any of the mapped modules, we take it as valid. -// Otherwise it is invalid. -bool SolarisLwp::IsAddressMapped(uintptr_t address) const { - AddressValidatingContext addr; - addr.address = address; - CallbackParam callback_param(AddressNotInModuleCallback, - &addr); - ListModules(&callback_param); - return addr.is_mapped; -} - -// We're looking for a ucontext_t as the second parameter -// to a signal handler function call. Luckily, the ucontext_t -// has an ebp(fp on SPARC) member which should match the ebp(fp) -// pointed to by the ebp(fp) of the signal handler frame. -// The Solaris stack looks like this: -// http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libproc/common/Pstack.c#81 -bool SolarisLwp::FindSigContext(uintptr_t sighandler_ebp, - ucontext_t **sig_ctx) { - uintptr_t previous_ebp; - uintptr_t sig_ebp; - const int MAX_STACK_DEPTH = 50; - int depth_counter = 0; - - do { -#if TARGET_CPU_SPARC - previous_ebp = reinterpret_cast(GetNextFrame( - reinterpret_cast(sighandler_ebp))); - *sig_ctx = reinterpret_cast(sighandler_ebp + sizeof (struct frame)); - uintptr_t sig_esp = (*sig_ctx)->uc_mcontext.gregs[REG_O6]; - if (sig_esp < previous_ebp && sig_esp > sighandler_ebp) - sig_ebp = (uintptr_t)(((struct frame *)sig_esp)->fr_savfp); - -#elif TARGET_CPU_X86 - previous_ebp = reinterpret_cast(GetNextFrame( - reinterpret_cast(sighandler_ebp))); - *sig_ctx = reinterpret_cast(sighandler_ebp + sizeof (struct frame) + - 3 * sizeof(uintptr_t)); - sig_ebp = (*sig_ctx)->uc_mcontext.gregs[EBP]; -#endif - sighandler_ebp = previous_ebp; - depth_counter++; - } while(previous_ebp != sig_ebp && sighandler_ebp != 0 && - IsAddressMapped(sighandler_ebp) && depth_counter < MAX_STACK_DEPTH); - - return previous_ebp == sig_ebp && previous_ebp != 0; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.h b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.h deleted file mode 100644 index 0914cfcd8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/solaris_lwp.h +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#ifndef CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ -#define CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ - -#if defined(sparc) || defined(__sparc) -#define TARGET_CPU_SPARC 1 -#elif defined(i386) || defined(__i386) -#define TARGET_CPU_X86 1 -#else -#error "cannot determine cpu type" -#endif - -#include -#include -#include -#include - -#ifndef _KERNEL -#define _KERNEL -#define MUST_UNDEF_KERNEL -#endif // _KERNEL -#include -#ifdef MUST_UNDEF_KERNEL -#undef _KERNEL -#undef MUST_UNDEF_KERNEL -#endif // MUST_UNDEF_KERNEL - -namespace google_breakpad { - -// Max module path name length. -static const int kMaxModuleNameLength = 256; - -// Holding infomaton about a module in the process. -struct ModuleInfo { - char name[kMaxModuleNameLength]; - uintptr_t start_addr; - int size; -}; - -// A callback to run when getting a lwp in the process. -// Return true will go on to the next lwp while return false will stop the -// iteration. -typedef bool (*LwpCallback)(lwpstatus_t* lsp, void *context); - -// A callback to run when a new module is found in the process. -// Return true will go on to the next module while return false will stop the -// iteration. -typedef bool (*ModuleCallback)(const ModuleInfo &module_info, void *context); - -// A callback to run when getting a lwpid in the process. -// Return true will go on to the next lwp while return false will stop the -// iteration. -typedef bool (*LwpidCallback)(int lwpid, void *context); - -// Holding the callback information. -template -struct CallbackParam { - // Callback function address. - CallbackFunc call_back; - // Callback context; - void *context; - - CallbackParam() : call_back(NULL), context(NULL) { - } - - CallbackParam(CallbackFunc func, void *func_context) : - call_back(func), context(func_context) { - } -}; - -/////////////////////////////////////////////////////////////////////////////// - -// -// SolarisLwp -// -// Provides handy support for operation on Solaris lwps. -// It uses proc file system to get lwp information. -// -// TODO(Alfred): Currently it only supports x86. Add SPARC support. -// -class SolarisLwp { - public: - // Create a SolarisLwp instance to list all the lwps in a process. - explicit SolarisLwp(int pid); - ~SolarisLwp(); - - int getpid() const { return this->pid_; } - - // Control all the lwps in the process. - // Return the number of suspended/resumed lwps in the process. - // Return -1 means failed to control lwps. - int ControlAllLwps(bool suspend); - - // Get the count of lwps in the process. - // Return -1 means error. - int GetLwpCount() const; - - // Iterate the lwps of process. - // Whenever there is a lwp found, the callback will be invoked to process - // the information. - // Return the callback return value or -1 on error. - int Lwp_iter_all(int pid, CallbackParam *callback_param) const; - - // Get the module count of the current process. - int GetModuleCount() const; - - // Get the mapped modules in the address space. - // Whenever a module is found, the callback will be invoked to process the - // information. - // Return how may modules are found. - int ListModules(CallbackParam *callback_param) const; - - // Get the bottom of the stack from esp. - uintptr_t GetLwpStackBottom(uintptr_t current_esp) const; - - // Finds a signal context on the stack given the ebp of our signal handler. - bool FindSigContext(uintptr_t sighandler_ebp, ucontext_t **sig_ctx); - - private: - // Check if the address is a valid virtual address. - bool IsAddressMapped(uintptr_t address) const; - - private: - // The pid of the process we are listing lwps. - int pid_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/breakpad_client.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/breakpad_client.gyp deleted file mode 100644 index 647975342..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/breakpad_client.gyp +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'build_all', - 'type': 'none', - 'dependencies': [ - './crash_generation/crash_generation.gyp:*', - './handler/exception_handler.gyp:*', - './sender/crash_report_sender.gyp:*', - './unittests/client_tests.gyp:*', - './unittests/testing.gyp:*', - './tests/crash_generation_app/crash_generation_app.gyp:*', - ] - }, - { - 'target_name': 'common', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)', - ] - }, - 'sources': [ - '<(DEPTH)/common/windows/guid_string.cc', - '<(DEPTH)/common/windows/guid_string.h', - '<(DEPTH)/common/windows/http_upload.cc', - '<(DEPTH)/common/windows/http_upload.h', - '<(DEPTH)/common/windows/string_utils.cc', - ] - } - ] -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/common/auto_critical_section.h b/toolkit/crashreporter/google-breakpad/src/client/windows/common/auto_critical_section.h deleted file mode 100644 index 3fd4b9b7e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/common/auto_critical_section.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__ -#define CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__ - -#include - -namespace google_breakpad { - -// Automatically enters the critical section in the constructor and leaves -// the critical section in the destructor. -class AutoCriticalSection { - public: - // Creates a new instance with the given critical section object - // and enters the critical section immediately. - explicit AutoCriticalSection(CRITICAL_SECTION* cs) : cs_(cs), taken_(false) { - assert(cs_); - Acquire(); - } - - // Destructor: leaves the critical section. - ~AutoCriticalSection() { - if (taken_) { - Release(); - } - } - - // Enters the critical section. Recursive Acquire() calls are not allowed. - void Acquire() { - assert(!taken_); - EnterCriticalSection(cs_); - taken_ = true; - } - - // Leaves the critical section. The caller should not call Release() unless - // the critical seciton has been entered already. - void Release() { - assert(taken_); - taken_ = false; - LeaveCriticalSection(cs_); - } - - private: - // Disable copy ctor and operator=. - AutoCriticalSection(const AutoCriticalSection&); - AutoCriticalSection& operator=(const AutoCriticalSection&); - - CRITICAL_SECTION* cs_; - bool taken_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/common/ipc_protocol.h b/toolkit/crashreporter/google-breakpad/src/client/windows/common/ipc_protocol.h deleted file mode 100644 index c74868198..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/common/ipc_protocol.h +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__ -#define CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__ - -#include -#include -#include -#include -#include "common/windows/string_utils-inl.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Name/value pair for custom client information. -struct CustomInfoEntry { - // Maximum length for name and value for client custom info. - static const int kNameMaxLength = 64; - static const int kValueMaxLength = 64; - - CustomInfoEntry() { - // Putting name and value in initializer list makes VC++ show warning 4351. - set_name(NULL); - set_value(NULL); - } - - CustomInfoEntry(const wchar_t* name_arg, const wchar_t* value_arg) { - set_name(name_arg); - set_value(value_arg); - } - - void set_name(const wchar_t* name_arg) { - if (!name_arg) { - name[0] = L'\0'; - return; - } - WindowsStringUtils::safe_wcscpy(name, kNameMaxLength, name_arg); - } - - void set_value(const wchar_t* value_arg) { - if (!value_arg) { - value[0] = L'\0'; - return; - } - - WindowsStringUtils::safe_wcscpy(value, kValueMaxLength, value_arg); - } - - void set(const wchar_t* name_arg, const wchar_t* value_arg) { - set_name(name_arg); - set_value(value_arg); - } - - wchar_t name[kNameMaxLength]; - wchar_t value[kValueMaxLength]; -}; - -// Constants for the protocol between client and the server. - -// Tags sent with each message indicating the purpose of -// the message. -enum MessageTag { - MESSAGE_TAG_NONE = 0, - MESSAGE_TAG_REGISTRATION_REQUEST = 1, - MESSAGE_TAG_REGISTRATION_RESPONSE = 2, - MESSAGE_TAG_REGISTRATION_ACK = 3, - MESSAGE_TAG_UPLOAD_REQUEST = 4 -}; - -struct CustomClientInfo { - const CustomInfoEntry* entries; - size_t count; -}; - -// Message structure for IPC between crash client and crash server. -struct ProtocolMessage { - ProtocolMessage() - : tag(MESSAGE_TAG_NONE), - id(0), - dump_type(MiniDumpNormal), - thread_id(0), - exception_pointers(NULL), - assert_info(NULL), - custom_client_info(), - dump_request_handle(NULL), - dump_generated_handle(NULL), - server_alive_handle(NULL) { - } - - // Creates an instance with the given parameters. - ProtocolMessage(MessageTag arg_tag, - DWORD arg_id, - MINIDUMP_TYPE arg_dump_type, - DWORD* arg_thread_id, - EXCEPTION_POINTERS** arg_exception_pointers, - MDRawAssertionInfo* arg_assert_info, - const CustomClientInfo& custom_info, - HANDLE arg_dump_request_handle, - HANDLE arg_dump_generated_handle, - HANDLE arg_server_alive) - : tag(arg_tag), - id(arg_id), - dump_type(arg_dump_type), - thread_id(arg_thread_id), - exception_pointers(arg_exception_pointers), - assert_info(arg_assert_info), - custom_client_info(custom_info), - dump_request_handle(arg_dump_request_handle), - dump_generated_handle(arg_dump_generated_handle), - server_alive_handle(arg_server_alive) { - } - - // Tag in the message. - MessageTag tag; - - // The id for this message. This may be either a process id or a crash id - // depending on the type of message. - DWORD id; - - // Dump type requested. - MINIDUMP_TYPE dump_type; - - // Client thread id pointer. - DWORD* thread_id; - - // Exception information. - EXCEPTION_POINTERS** exception_pointers; - - // Assert information in case of an invalid parameter or - // pure call failure. - MDRawAssertionInfo* assert_info; - - // Custom client information. - CustomClientInfo custom_client_info; - - // Handle to signal the crash event. - HANDLE dump_request_handle; - - // Handle to check if server is done generating crash. - HANDLE dump_generated_handle; - - // Handle to a mutex that becomes signaled (WAIT_ABANDONED) - // if server process goes down. - HANDLE server_alive_handle; - - private: - // Disable copy ctor and operator=. - ProtocolMessage(const ProtocolMessage& msg); - ProtocolMessage& operator=(const ProtocolMessage& msg); -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_COMMON_IPC_PROTOCOL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/ReadMe.txt b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/ReadMe.txt deleted file mode 100644 index b54d0e11b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/ReadMe.txt +++ /dev/null @@ -1,58 +0,0 @@ -========================================================================= - State machine transitions for the Crash Generation Server -========================================================================= - -========================================================================= - | - STATE | ACTIONS - | -========================================================================= - ERROR | Clean up resources used to serve clients. - | Always remain in ERROR state. -------------------------------------------------------------------------- - INITIAL | Connect to the pipe asynchronously. - | If connection is successfully queued up asynchronously, - | go into CONNECTING state. - | If connection is done synchronously, go into CONNECTED - | state. - | For any unexpected problems, go into ERROR state. -------------------------------------------------------------------------- - CONNECTING | Get the result of async connection request. - | If I/O is still incomplete, remain in the CONNECTING - | state. - | If connection is complete, go into CONNECTED state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - CONNECTED | Read from the pipe asynchronously. - | If read request is successfully queued up asynchronously, - | go into READING state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - READING | Get the result of async read request. - | If read is done, go into READ_DONE state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - READ_DONE | Register the client, prepare the reply and write the - | reply to the pipe asynchronously. - | If write request is successfully queued up asynchronously, - | go into WRITING state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - WRITING | Get the result of the async write request. - | If write is done, go into WRITE_DONE state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - WRITE_DONE | Read from the pipe asynchronously (for an ACK). - | If read request is successfully queued up asynchonously, - | go into READING_ACK state. - | For any unexpected problems, go into DISCONNECTING state. -------------------------------------------------------------------------- - READING_ACK | Get the result of the async read request. - | If read is done, perform action for successful client - | connection. - | Go into DISCONNECTING state. -------------------------------------------------------------------------- - DISCONNECTING | Disconnect from the pipe, reset the event and go into - | INITIAL state and signal the event again. If anything - | fails, go into ERROR state. -========================================================================= diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.cc deleted file mode 100644 index ed3126381..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.cc +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/crash_generation/client_info.h" -#include "client/windows/common/ipc_protocol.h" - -static const wchar_t kCustomInfoProcessUptimeName[] = L"ptime"; -static const size_t kMaxCustomInfoEntries = 4096; - -namespace google_breakpad { - -ClientInfo::ClientInfo(CrashGenerationServer* crash_server, - DWORD pid, - MINIDUMP_TYPE dump_type, - DWORD* thread_id, - EXCEPTION_POINTERS** ex_info, - MDRawAssertionInfo* assert_info, - const CustomClientInfo& custom_client_info) - : crash_server_(crash_server), - pid_(pid), - dump_type_(dump_type), - ex_info_(ex_info), - assert_info_(assert_info), - custom_client_info_(custom_client_info), - thread_id_(thread_id), - process_handle_(NULL), - dump_requested_handle_(NULL), - dump_generated_handle_(NULL), - dump_request_wait_handle_(NULL), - process_exit_wait_handle_(NULL), - crash_id_(NULL) { - GetSystemTimeAsFileTime(&start_time_); -} - -bool ClientInfo::Initialize() { - process_handle_ = OpenProcess(GENERIC_ALL, FALSE, pid_); - if (!process_handle_) { - return false; - } - - // The crash_id will be the low order word of the process creation time. - FILETIME creation_time, exit_time, kernel_time, user_time; - if (GetProcessTimes(process_handle_, &creation_time, &exit_time, - &kernel_time, &user_time)) { - start_time_ = creation_time; - } - crash_id_ = start_time_.dwLowDateTime; - - dump_requested_handle_ = CreateEvent(NULL, // Security attributes. - TRUE, // Manual reset. - FALSE, // Initial state. - NULL); // Name. - if (!dump_requested_handle_) { - return false; - } - - dump_generated_handle_ = CreateEvent(NULL, // Security attributes. - TRUE, // Manual reset. - FALSE, // Initial state. - NULL); // Name. - return dump_generated_handle_ != NULL; -} - -void ClientInfo::UnregisterDumpRequestWaitAndBlockUntilNoPending() { - if (dump_request_wait_handle_) { - // Wait for callbacks that might already be running to finish. - UnregisterWaitEx(dump_request_wait_handle_, INVALID_HANDLE_VALUE); - dump_request_wait_handle_ = NULL; - } -} - -void ClientInfo::UnregisterProcessExitWait(bool block_until_no_pending) { - if (process_exit_wait_handle_) { - if (block_until_no_pending) { - // Wait for the callback that might already be running to finish. - UnregisterWaitEx(process_exit_wait_handle_, INVALID_HANDLE_VALUE); - } else { - UnregisterWait(process_exit_wait_handle_); - } - process_exit_wait_handle_ = NULL; - } -} - -ClientInfo::~ClientInfo() { - // Waiting for the callback to finish here is safe because ClientInfo's are - // never destroyed from the dump request handling callback. - UnregisterDumpRequestWaitAndBlockUntilNoPending(); - - // This is a little tricky because ClientInfo's may be destroyed by the same - // callback (OnClientEnd) and waiting for it to finish will cause a deadlock. - // Regardless of this complication, wait for any running callbacks to finish - // so that the common case is properly handled. In order to avoid deadlocks, - // the OnClientEnd callback must call UnregisterProcessExitWait(false) - // before deleting the ClientInfo. - UnregisterProcessExitWait(true); - - if (process_handle_) { - CloseHandle(process_handle_); - } - - if (dump_requested_handle_) { - CloseHandle(dump_requested_handle_); - } - - if (dump_generated_handle_) { - CloseHandle(dump_generated_handle_); - } -} - -bool ClientInfo::GetClientExceptionInfo(EXCEPTION_POINTERS** ex_info) const { - SIZE_T bytes_count = 0; - if (!ReadProcessMemory(process_handle_, - ex_info_, - ex_info, - sizeof(*ex_info), - &bytes_count)) { - return false; - } - - return bytes_count == sizeof(*ex_info); -} - -bool ClientInfo::GetClientThreadId(DWORD* thread_id) const { - SIZE_T bytes_count = 0; - if (!ReadProcessMemory(process_handle_, - thread_id_, - thread_id, - sizeof(*thread_id), - &bytes_count)) { - return false; - } - - return bytes_count == sizeof(*thread_id); -} - -void ClientInfo::SetProcessUptime() { - FILETIME now = {0}; - GetSystemTimeAsFileTime(&now); - - ULARGE_INTEGER time_start; - time_start.HighPart = start_time_.dwHighDateTime; - time_start.LowPart = start_time_.dwLowDateTime; - - ULARGE_INTEGER time_now; - time_now.HighPart = now.dwHighDateTime; - time_now.LowPart = now.dwLowDateTime; - - // Calculate the delay and convert it from 100-nanoseconds to milliseconds. - __int64 delay = (time_now.QuadPart - time_start.QuadPart) / 10 / 1000; - - // Convert it to a string. - wchar_t* value = custom_info_entries_.get()[custom_client_info_.count].value; - _i64tow_s(delay, value, CustomInfoEntry::kValueMaxLength, 10); -} - -bool ClientInfo::PopulateCustomInfo() { - if (custom_client_info_.count > kMaxCustomInfoEntries) - return false; - - SIZE_T bytes_count = 0; - SIZE_T read_count = sizeof(CustomInfoEntry) * custom_client_info_.count; - - // If the scoped array for custom info already has an array, it will be - // the same size as what we need. This is because the number of custom info - // entries is always the same. So allocate memory only if scoped array has - // a NULL pointer. - if (!custom_info_entries_.get()) { - // Allocate an extra entry for reporting uptime for the client process. - custom_info_entries_.reset( - new CustomInfoEntry[custom_client_info_.count + 1]); - // Use the last element in the array for uptime. - custom_info_entries_.get()[custom_client_info_.count].set_name( - kCustomInfoProcessUptimeName); - } - - if (!ReadProcessMemory(process_handle_, - custom_client_info_.entries, - custom_info_entries_.get(), - read_count, - &bytes_count)) { - return false; - } - - SetProcessUptime(); - return (bytes_count == read_count); -} - -CustomClientInfo ClientInfo::GetCustomInfo() const { - CustomClientInfo custom_info; - custom_info.entries = custom_info_entries_.get(); - // Add 1 to the count from the client process to account for extra entry for - // process uptime. - custom_info.count = custom_client_info_.count + 1; - return custom_info; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.h b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.h deleted file mode 100644 index 6a8fba31f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/client_info.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_CRASH_GENERATION_CLIENT_INFO_H__ -#define CLIENT_WINDOWS_CRASH_GENERATION_CLIENT_INFO_H__ - -#include -#include -#include "client/windows/common/ipc_protocol.h" -#include "common/scoped_ptr.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -class CrashGenerationServer; - -// Abstraction for a crash client process. -class ClientInfo { - public: - // Creates an instance with the given values. Gets the process - // handle for the given process id and creates necessary event - // objects. - ClientInfo(CrashGenerationServer* crash_server, - DWORD pid, - MINIDUMP_TYPE dump_type, - DWORD* thread_id, - EXCEPTION_POINTERS** ex_info, - MDRawAssertionInfo* assert_info, - const CustomClientInfo& custom_client_info); - - ~ClientInfo(); - - CrashGenerationServer* crash_server() const { return crash_server_; } - DWORD pid() const { return pid_; } - MINIDUMP_TYPE dump_type() const { return dump_type_; } - EXCEPTION_POINTERS** ex_info() const { return ex_info_; } - MDRawAssertionInfo* assert_info() const { return assert_info_; } - DWORD* thread_id() const { return thread_id_; } - HANDLE process_handle() const { return process_handle_; } - HANDLE dump_requested_handle() const { return dump_requested_handle_; } - HANDLE dump_generated_handle() const { return dump_generated_handle_; } - DWORD crash_id() const { return crash_id_; } - const CustomClientInfo& custom_client_info() const { - return custom_client_info_; - } - - void set_dump_request_wait_handle(HANDLE value) { - dump_request_wait_handle_ = value; - } - - void set_process_exit_wait_handle(HANDLE value) { - process_exit_wait_handle_ = value; - } - - // Unregister the dump request wait operation and wait for all callbacks - // that might already be running to complete before returning. - void UnregisterDumpRequestWaitAndBlockUntilNoPending(); - - // Unregister the process exit wait operation. If block_until_no_pending is - // true, wait for all callbacks that might already be running to complete - // before returning. - void UnregisterProcessExitWait(bool block_until_no_pending); - - bool Initialize(); - bool GetClientExceptionInfo(EXCEPTION_POINTERS** ex_info) const; - bool GetClientThreadId(DWORD* thread_id) const; - - // Reads the custom information from the client process address space. - bool PopulateCustomInfo(); - - // Returns the client custom information. - CustomClientInfo GetCustomInfo() const; - - private: - // Calcualtes the uptime for the client process, converts it to a string and - // stores it in the last entry of client custom info. - void SetProcessUptime(); - - // Crash generation server. - CrashGenerationServer* crash_server_; - - // Client process ID. - DWORD pid_; - - // Dump type requested by the client. - MINIDUMP_TYPE dump_type_; - - // Address of an EXCEPTION_POINTERS* variable in the client - // process address space that will point to an instance of - // EXCEPTION_POINTERS containing information about crash. - // - // WARNING: Do not dereference these pointers as they are pointers - // in the address space of another process. - EXCEPTION_POINTERS** ex_info_; - - // Address of an instance of MDRawAssertionInfo in the client - // process address space that will contain information about - // non-exception related crashes like invalid parameter assertion - // failures and pure calls. - // - // WARNING: Do not dereference these pointers as they are pointers - // in the address space of another process. - MDRawAssertionInfo* assert_info_; - - // Custom information about the client. - CustomClientInfo custom_client_info_; - - // Contains the custom client info entries read from the client process - // memory. This will be populated only if the method GetClientCustomInfo - // is called. - scoped_array custom_info_entries_; - - // Address of a variable in the client process address space that - // will contain the thread id of the crashing client thread. - // - // WARNING: Do not dereference these pointers as they are pointers - // in the address space of another process. - DWORD* thread_id_; - - // Client process handle. - HANDLE process_handle_; - - // Dump request event handle. - HANDLE dump_requested_handle_; - - // Dump generated event handle. - HANDLE dump_generated_handle_; - - // Wait handle for dump request event. - HANDLE dump_request_wait_handle_; - - // Wait handle for process exit event. - HANDLE process_exit_wait_handle_; - - // Time when the client process started. It is used to determine the uptime - // for the client process when it signals a crash. - FILETIME start_time_; - - // The crash id which can be used to request an upload. This will be the - // value of the low order dword of the process creation time for the process - // being dumped. - DWORD crash_id_; - - // Disallow copy ctor and operator=. - ClientInfo(const ClientInfo& client_info); - ClientInfo& operator=(const ClientInfo& client_info); -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_CRASH_GENERATION_CLIENT_INFO_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation.gyp deleted file mode 100644 index ba343768a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation.gyp +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'crash_generation_server', - 'type': 'static_library', - 'sources': [ - 'client_info.cc', - 'crash_generation_server.cc', - 'minidump_generator.cc', - 'client_info.h', - 'crash_generation_client.h', - 'crash_generation_server.h', - 'minidump_generator.h', - ], - 'dependencies': [ - '../breakpad_client.gyp:common' - ], - }, - { - 'target_name': 'crash_generation_client', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)', - ], - 'sources': [ - 'crash_generation_client.h', - 'crash_generation_client.cc', - 'crash_generation_server.h', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.cc deleted file mode 100644 index 3ba5d4e4f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.cc +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/crash_generation/crash_generation_client.h" -#include -#include -#include "client/windows/common/ipc_protocol.h" - -namespace google_breakpad { - -const int kPipeBusyWaitTimeoutMs = 2000; - -#ifdef _DEBUG -const DWORD kWaitForServerTimeoutMs = INFINITE; -#else -const DWORD kWaitForServerTimeoutMs = 15000; -#endif - -const int kPipeConnectMaxAttempts = 2; - -const DWORD kPipeDesiredAccess = FILE_READ_DATA | - FILE_WRITE_DATA | - FILE_WRITE_ATTRIBUTES; - -const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION | - SECURITY_SQOS_PRESENT; - -const DWORD kPipeMode = PIPE_READMODE_MESSAGE; - -const size_t kWaitEventCount = 2; - -// This function is orphan for production code. It can be used -// for debugging to help repro some scenarios like the client -// is slow in writing to the pipe after connecting, the client -// is slow in reading from the pipe after writing, etc. The parameter -// overlapped below is not used and it is present to match the signature -// of this function to TransactNamedPipe Win32 API. Uncomment if needed -// for debugging. -/** -static bool TransactNamedPipeDebugHelper(HANDLE pipe, - const void* in_buffer, - DWORD in_size, - void* out_buffer, - DWORD out_size, - DWORD* bytes_count, - LPOVERLAPPED) { - // Uncomment the next sleep to create a gap before writing - // to pipe. - // Sleep(5000); - - if (!WriteFile(pipe, - in_buffer, - in_size, - bytes_count, - NULL)) { - return false; - } - - // Uncomment the next sleep to create a gap between write - // and read. - // Sleep(5000); - - return ReadFile(pipe, out_buffer, out_size, bytes_count, NULL) != FALSE; -} -**/ - -CrashGenerationClient::CrashGenerationClient( - const wchar_t* pipe_name, - MINIDUMP_TYPE dump_type, - const CustomClientInfo* custom_info) - : pipe_name_(pipe_name), - pipe_handle_(NULL), - custom_info_(), - dump_type_(dump_type), - crash_event_(NULL), - crash_generated_(NULL), - server_alive_(NULL), - server_process_id_(0), - thread_id_(0), - exception_pointers_(NULL) { - memset(&assert_info_, 0, sizeof(assert_info_)); - if (custom_info) { - custom_info_ = *custom_info; - } -} - -CrashGenerationClient::CrashGenerationClient( - HANDLE pipe_handle, - MINIDUMP_TYPE dump_type, - const CustomClientInfo* custom_info) - : pipe_name_(), - pipe_handle_(pipe_handle), - custom_info_(), - dump_type_(dump_type), - crash_event_(NULL), - crash_generated_(NULL), - server_alive_(NULL), - server_process_id_(0), - thread_id_(0), - exception_pointers_(NULL) { - memset(&assert_info_, 0, sizeof(assert_info_)); - if (custom_info) { - custom_info_ = *custom_info; - } -} - -CrashGenerationClient::~CrashGenerationClient() { - if (crash_event_) { - CloseHandle(crash_event_); - } - - if (crash_generated_) { - CloseHandle(crash_generated_); - } - - if (server_alive_) { - CloseHandle(server_alive_); - } -} - -// Performs the registration step with the server process. -// The registration step involves communicating with the server -// via a named pipe. The client sends the following pieces of -// data to the server: -// -// * Message tag indicating the client is requesting registration. -// * Process id of the client process. -// * Address of a DWORD variable in the client address space -// that will contain the thread id of the client thread that -// caused the crash. -// * Address of a EXCEPTION_POINTERS* variable in the client -// address space that will point to an instance of EXCEPTION_POINTERS -// when the crash happens. -// * Address of an instance of MDRawAssertionInfo that will contain -// relevant information in case of non-exception crashes like assertion -// failures and pure calls. -// -// In return the client expects the following information from the server: -// -// * Message tag indicating successful registration. -// * Server process id. -// * Handle to an object that client can signal to request dump -// generation from the server. -// * Handle to an object that client can wait on after requesting -// dump generation for the server to finish dump generation. -// * Handle to a mutex object that client can wait on to make sure -// server is still alive. -// -// If any step of the expected behavior mentioned above fails, the -// registration step is not considered successful and hence out-of-process -// dump generation service is not available. -// -// Returns true if the registration is successful; false otherwise. -bool CrashGenerationClient::Register() { - if (IsRegistered()) { - return true; - } - - HANDLE pipe = ConnectToServer(); - if (!pipe) { - return false; - } - - bool success = RegisterClient(pipe); - CloseHandle(pipe); - return success; -} - -bool CrashGenerationClient::RequestUpload(DWORD crash_id) { - HANDLE pipe = ConnectToServer(); - if (!pipe) { - return false; - } - - CustomClientInfo custom_info = {NULL, 0}; - ProtocolMessage msg(MESSAGE_TAG_UPLOAD_REQUEST, crash_id, - static_cast(NULL), NULL, NULL, NULL, - custom_info, NULL, NULL, NULL); - DWORD bytes_count = 0; - bool success = WriteFile(pipe, &msg, sizeof(msg), &bytes_count, NULL) != 0; - - CloseHandle(pipe); - return success; -} - -HANDLE CrashGenerationClient::ConnectToServer() { - HANDLE pipe = ConnectToPipe(pipe_name_.c_str(), - kPipeDesiredAccess, - kPipeFlagsAndAttributes); - if (!pipe) { - return NULL; - } - - DWORD mode = kPipeMode; - if (!SetNamedPipeHandleState(pipe, &mode, NULL, NULL)) { - CloseHandle(pipe); - pipe = NULL; - } - - return pipe; -} - -bool CrashGenerationClient::RegisterClient(HANDLE pipe) { - ProtocolMessage msg(MESSAGE_TAG_REGISTRATION_REQUEST, - GetCurrentProcessId(), - dump_type_, - &thread_id_, - &exception_pointers_, - &assert_info_, - custom_info_, - NULL, - NULL, - NULL); - ProtocolMessage reply; - DWORD bytes_count = 0; - // The call to TransactNamedPipe below can be changed to a call - // to TransactNamedPipeDebugHelper to help repro some scenarios. - // For details see comments for TransactNamedPipeDebugHelper. - if (!TransactNamedPipe(pipe, - &msg, - sizeof(msg), - &reply, - sizeof(ProtocolMessage), - &bytes_count, - NULL)) { - return false; - } - - if (!ValidateResponse(reply)) { - return false; - } - - ProtocolMessage ack_msg; - ack_msg.tag = MESSAGE_TAG_REGISTRATION_ACK; - - if (!WriteFile(pipe, &ack_msg, sizeof(ack_msg), &bytes_count, NULL)) { - return false; - } - crash_event_ = reply.dump_request_handle; - crash_generated_ = reply.dump_generated_handle; - server_alive_ = reply.server_alive_handle; - server_process_id_ = reply.id; - - return true; -} - -HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name, - DWORD pipe_access, - DWORD flags_attrs) { - if (pipe_handle_) { - HANDLE t = pipe_handle_; - pipe_handle_ = NULL; - return t; - } - - for (int i = 0; i < kPipeConnectMaxAttempts; ++i) { - HANDLE pipe = CreateFile(pipe_name, - pipe_access, - 0, - NULL, - OPEN_EXISTING, - flags_attrs, - NULL); - if (pipe != INVALID_HANDLE_VALUE) { - return pipe; - } - - // Cannot continue retrying if error is something other than - // ERROR_PIPE_BUSY. - if (GetLastError() != ERROR_PIPE_BUSY) { - break; - } - - // Cannot continue retrying if wait on pipe fails. - if (!WaitNamedPipe(pipe_name, kPipeBusyWaitTimeoutMs)) { - break; - } - } - - return NULL; -} - -bool CrashGenerationClient::ValidateResponse( - const ProtocolMessage& msg) const { - return (msg.tag == MESSAGE_TAG_REGISTRATION_RESPONSE) && - (msg.id != 0) && - (msg.dump_request_handle != NULL) && - (msg.dump_generated_handle != NULL) && - (msg.server_alive_handle != NULL); -} - -bool CrashGenerationClient::IsRegistered() const { - return crash_event_ != NULL; -} - -bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info, - MDRawAssertionInfo* assert_info) { - if (!IsRegistered()) { - return false; - } - - exception_pointers_ = ex_info; - thread_id_ = GetCurrentThreadId(); - - if (assert_info) { - memcpy(&assert_info_, assert_info, sizeof(assert_info_)); - } else { - memset(&assert_info_, 0, sizeof(assert_info_)); - } - - return SignalCrashEventAndWait(); -} - -bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info) { - return RequestDump(ex_info, NULL); -} - -bool CrashGenerationClient::RequestDump(MDRawAssertionInfo* assert_info) { - return RequestDump(NULL, assert_info); -} - -bool CrashGenerationClient::SignalCrashEventAndWait() { - assert(crash_event_); - assert(crash_generated_); - assert(server_alive_); - - // Reset the dump generated event before signaling the crash - // event so that the server can set the dump generated event - // once it is done generating the event. - if (!ResetEvent(crash_generated_)) { - return false; - } - - if (!SetEvent(crash_event_)) { - return false; - } - - HANDLE wait_handles[kWaitEventCount] = {crash_generated_, server_alive_}; - - DWORD result = WaitForMultipleObjects(kWaitEventCount, - wait_handles, - FALSE, - kWaitForServerTimeoutMs); - - // Crash dump was successfully generated only if the server - // signaled the crash generated event. - return result == WAIT_OBJECT_0; -} - -HANDLE CrashGenerationClient::DuplicatePipeToClientProcess(const wchar_t* pipe_name, - HANDLE hProcess) { - for (int i = 0; i < kPipeConnectMaxAttempts; ++i) { - HANDLE local_pipe = CreateFile(pipe_name, kPipeDesiredAccess, - 0, NULL, OPEN_EXISTING, - kPipeFlagsAndAttributes, NULL); - if (local_pipe != INVALID_HANDLE_VALUE) { - HANDLE remotePipe = INVALID_HANDLE_VALUE; - if (DuplicateHandle(GetCurrentProcess(), local_pipe, - hProcess, &remotePipe, 0, FALSE, - DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { - return remotePipe; - } else { - return INVALID_HANDLE_VALUE; - } - } - - // Cannot continue retrying if the error wasn't a busy pipe. - if (GetLastError() != ERROR_PIPE_BUSY) { - return INVALID_HANDLE_VALUE; - } - - if (!WaitNamedPipe(pipe_name, kPipeBusyWaitTimeoutMs)) { - return INVALID_HANDLE_VALUE; - } - } - return INVALID_HANDLE_VALUE; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.h b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.h deleted file mode 100644 index 457f73195..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_client.h +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ -#define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ - -#include -#include -#include -#include -#include "client/windows/common/ipc_protocol.h" -#include "common/scoped_ptr.h" - -namespace google_breakpad { - -struct CustomClientInfo; - -// Abstraction of client-side implementation of out of process -// crash generation. -// -// The process that desires to have out-of-process crash dump -// generation service can use this class in the following way: -// -// * Create an instance. -// * Call Register method so that the client tries to register -// with the server process and check the return value. If -// registration is not successful, out-of-process crash dump -// generation will not be available -// * Request dump generation by calling either of the two -// overloaded RequestDump methods - one in case of exceptions -// and the other in case of assertion failures -// -// Note that it is the responsibility of the client code of -// this class to set the unhandled exception filter with the -// system by calling the SetUnhandledExceptionFilter function -// and the client code should explicitly request dump generation. -class CrashGenerationClient { - public: - CrashGenerationClient(const wchar_t* pipe_name, - MINIDUMP_TYPE dump_type, - const CustomClientInfo* custom_info); - - CrashGenerationClient(HANDLE pipe_handle, - MINIDUMP_TYPE dump_type, - const CustomClientInfo* custom_info); - - ~CrashGenerationClient(); - - // Registers the client process with the crash server. - // - // Returns true if the registration is successful; false otherwise. - bool Register(); - - // Requests the crash server to upload a previous dump with the - // given crash id. - bool RequestUpload(DWORD crash_id); - - bool RequestDump(EXCEPTION_POINTERS* ex_info, - MDRawAssertionInfo* assert_info); - - // Requests the crash server to generate a dump with the given - // exception information. - // - // Returns true if the dump was successful; false otherwise. Note that - // if the registration step was not performed or it was not successful, - // false will be returned. - bool RequestDump(EXCEPTION_POINTERS* ex_info); - - // Requests the crash server to generate a dump with the given - // assertion information. - // - // Returns true if the dump was successful; false otherwise. Note that - // if the registration step was not performed or it was not successful, - // false will be returned. - bool RequestDump(MDRawAssertionInfo* assert_info); - - // If the crash generation client is running in a sandbox that prevents it - // from opening the named pipe directly, the server process may open the - // handle and duplicate it into the client process with this helper method. - // Returns INVALID_HANDLE_VALUE on failure. The process must have been opened - // with the PROCESS_DUP_HANDLE access right. - static HANDLE DuplicatePipeToClientProcess(const wchar_t* pipe_name, - HANDLE hProcess); - - private: - // Connects to the appropriate pipe and sets the pipe handle state. - // - // Returns the pipe handle if everything goes well; otherwise Returns NULL. - HANDLE ConnectToServer(); - - // Performs a handshake with the server over the given pipe which should be - // already connected to the server. - // - // Returns true if handshake with the server was successful; false otherwise. - bool RegisterClient(HANDLE pipe); - - // Validates the given server response. - bool ValidateResponse(const ProtocolMessage& msg) const; - - // Returns true if the registration step succeeded; false otherwise. - bool IsRegistered() const; - - // Connects to the given named pipe with given parameters. - // - // Returns true if the connection is successful; false otherwise. - HANDLE ConnectToPipe(const wchar_t* pipe_name, - DWORD pipe_access, - DWORD flags_attrs); - - // Signals the crash event and wait for the server to generate crash. - bool SignalCrashEventAndWait(); - - // Pipe name to use to talk to server. - std::wstring pipe_name_; - - // Pipe handle duplicated from server process. Only valid before - // Register is called. - HANDLE pipe_handle_; - - // Custom client information - CustomClientInfo custom_info_; - - // Type of dump to generate. - MINIDUMP_TYPE dump_type_; - - // Event to signal in case of a crash. - HANDLE crash_event_; - - // Handle to wait on after signaling a crash for the server - // to finish generating crash dump. - HANDLE crash_generated_; - - // Handle to a mutex that will become signaled with WAIT_ABANDONED - // if the server process goes down. - HANDLE server_alive_; - - // Server process id. - DWORD server_process_id_; - - // Id of the thread that caused the crash. - DWORD thread_id_; - - // Exception pointers for an exception crash. - EXCEPTION_POINTERS* exception_pointers_; - - // Assertion info for an invalid parameter or pure call crash. - MDRawAssertionInfo assert_info_; - - // Disable copy ctor and operator=. - CrashGenerationClient(const CrashGenerationClient& crash_client); - CrashGenerationClient& operator=(const CrashGenerationClient& crash_client); -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.cc deleted file mode 100644 index bb0968fe0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.cc +++ /dev/null @@ -1,931 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/crash_generation/crash_generation_server.h" -#include -#include -#include -#include "client/windows/common/auto_critical_section.h" -#include "common/scoped_ptr.h" - -#include "client/windows/crash_generation/client_info.h" - -namespace google_breakpad { - -// Output buffer size. -static const size_t kOutBufferSize = 64; - -// Input buffer size. -static const size_t kInBufferSize = 64; - -// Access flags for the client on the dump request event. -static const DWORD kDumpRequestEventAccess = EVENT_MODIFY_STATE; - -// Access flags for the client on the dump generated event. -static const DWORD kDumpGeneratedEventAccess = EVENT_MODIFY_STATE | - SYNCHRONIZE; - -// Access flags for the client on the mutex. -static const DWORD kMutexAccess = SYNCHRONIZE; - -// Attribute flags for the pipe. -static const DWORD kPipeAttr = FILE_FLAG_FIRST_PIPE_INSTANCE | - PIPE_ACCESS_DUPLEX | - FILE_FLAG_OVERLAPPED; - -// Mode for the pipe. -static const DWORD kPipeMode = PIPE_TYPE_MESSAGE | - PIPE_READMODE_MESSAGE | - PIPE_WAIT; - -// For pipe I/O, execute the callback in the wait thread itself, -// since the callback does very little work. The callback executes -// the code for one of the states of the server state machine and -// the code for all of the states perform async I/O and hence -// finish very quickly. -static const ULONG kPipeIOThreadFlags = WT_EXECUTEINWAITTHREAD; - -// Dump request threads will, most likely, generate dumps. That may -// take some time to finish, so specify WT_EXECUTELONGFUNCTION flag. -static const ULONG kDumpRequestThreadFlags = WT_EXECUTEINWAITTHREAD | - WT_EXECUTELONGFUNCTION; - -static bool IsClientRequestValid(const ProtocolMessage& msg) { - return msg.tag == MESSAGE_TAG_UPLOAD_REQUEST || - (msg.tag == MESSAGE_TAG_REGISTRATION_REQUEST && - msg.id != 0 && - msg.thread_id != NULL && - msg.exception_pointers != NULL && - msg.assert_info != NULL); -} - -#ifndef NDEBUG -static bool CheckForIOIncomplete(bool success) { - // We should never get an I/O incomplete since we should not execute this - // unless the operation has finished and the overlapped event is signaled. If - // we do get INCOMPLETE, we have a bug in our code. - return success ? false : (GetLastError() == ERROR_IO_INCOMPLETE); -} -#endif - -CrashGenerationServer::CrashGenerationServer( - const std::wstring& pipe_name, - SECURITY_ATTRIBUTES* pipe_sec_attrs, - OnClientConnectedCallback connect_callback, - void* connect_context, - OnClientDumpRequestCallback dump_callback, - void* dump_context, - OnClientExitedCallback exit_callback, - void* exit_context, - OnClientUploadRequestCallback upload_request_callback, - void* upload_context, - bool generate_dumps, - const std::wstring* dump_path) - : pipe_name_(pipe_name), - pipe_sec_attrs_(pipe_sec_attrs), - pipe_(NULL), - pipe_wait_handle_(NULL), - server_alive_handle_(NULL), - connect_callback_(connect_callback), - connect_context_(connect_context), - dump_callback_(dump_callback), - dump_context_(dump_context), - exit_callback_(exit_callback), - exit_context_(exit_context), - upload_request_callback_(upload_request_callback), - upload_context_(upload_context), - generate_dumps_(generate_dumps), - pre_fetch_custom_info_(true), - dump_path_(dump_path ? *dump_path : L""), - server_state_(IPC_SERVER_STATE_UNINITIALIZED), - shutting_down_(false), - overlapped_(), - client_info_(NULL) { - InitializeCriticalSection(&sync_); -} - -// This should never be called from the OnPipeConnected callback. -// Otherwise the UnregisterWaitEx call below will cause a deadlock. -CrashGenerationServer::~CrashGenerationServer() { - // New scope to release the lock automatically. - { - // Make sure no clients are added or removed beyond this point. - // Before adding or removing any clients, the critical section - // must be entered and the shutting_down_ flag checked. The - // critical section is then exited only after the clients_ list - // modifications are done and the list is in a consistent state. - AutoCriticalSection lock(&sync_); - - // Indicate to existing threads that server is shutting down. - shutting_down_ = true; - } - // No one will modify the clients_ list beyond this point - - // not even from another thread. - - // Even if there are no current worker threads running, it is possible that - // an I/O request is pending on the pipe right now but not yet done. - // In fact, it's very likely this is the case unless we are in an ERROR - // state. If we don't wait for the pending I/O to be done, then when the I/O - // completes, it may write to invalid memory. AppVerifier will flag this - // problem too. So we disconnect from the pipe and then wait for the server - // to get into error state so that the pending I/O will fail and get - // cleared. - DisconnectNamedPipe(pipe_); - int num_tries = 100; - while (num_tries-- && server_state_ != IPC_SERVER_STATE_ERROR) { - Sleep(10); - } - - // Unregister wait on the pipe. - if (pipe_wait_handle_) { - // Wait for already executing callbacks to finish. - UnregisterWaitEx(pipe_wait_handle_, INVALID_HANDLE_VALUE); - } - - // Close the pipe to avoid further client connections. - if (pipe_) { - CloseHandle(pipe_); - } - - // Request all ClientInfo objects to unregister all waits. - // No need to enter the critical section because no one is allowed to modify - // the clients_ list once the shutting_down_ flag is set. - std::list::iterator iter; - for (iter = clients_.begin(); iter != clients_.end(); ++iter) { - ClientInfo* client_info = *iter; - // Unregister waits. Wait for already executing callbacks to finish. - // Unregister the client process exit wait first and only then unregister - // the dump request wait. The reason is that the OnClientExit callback - // also unregisters the dump request wait and such a race (doing the same - // unregistration from two threads) is undesirable. - client_info->UnregisterProcessExitWait(true); - client_info->UnregisterDumpRequestWaitAndBlockUntilNoPending(); - - // Destroying the ClientInfo here is safe because all wait operations for - // this ClientInfo were unregistered and no pending or running callbacks - // for this ClientInfo can possible exist (block_until_no_pending option - // was used). - delete client_info; - } - - if (server_alive_handle_) { - // Release the mutex before closing the handle so that clients requesting - // dumps wait for a long time for the server to generate a dump. - ReleaseMutex(server_alive_handle_); - CloseHandle(server_alive_handle_); - } - - if (overlapped_.hEvent) { - CloseHandle(overlapped_.hEvent); - } - - DeleteCriticalSection(&sync_); -} - -bool CrashGenerationServer::Start() { - if (server_state_ != IPC_SERVER_STATE_UNINITIALIZED) { - return false; - } - - server_state_ = IPC_SERVER_STATE_INITIAL; - - server_alive_handle_ = CreateMutex(NULL, TRUE, NULL); - if (!server_alive_handle_) { - return false; - } - - // Event to signal the client connection and pipe reads and writes. - overlapped_.hEvent = CreateEvent(NULL, // Security descriptor. - TRUE, // Manual reset. - FALSE, // Initially nonsignaled. - NULL); // Name. - if (!overlapped_.hEvent) { - return false; - } - - // Register a callback with the thread pool for the client connection. - if (!RegisterWaitForSingleObject(&pipe_wait_handle_, - overlapped_.hEvent, - OnPipeConnected, - this, - INFINITE, - kPipeIOThreadFlags)) { - return false; - } - - pipe_ = CreateNamedPipe(pipe_name_.c_str(), - kPipeAttr, - kPipeMode, - 1, - kOutBufferSize, - kInBufferSize, - 0, - pipe_sec_attrs_); - if (pipe_ == INVALID_HANDLE_VALUE) { - return false; - } - - // Kick-start the state machine. This will initiate an asynchronous wait - // for client connections. - if (!SetEvent(overlapped_.hEvent)) { - server_state_ = IPC_SERVER_STATE_ERROR; - return false; - } - - // If we are in error state, it's because we failed to start listening. - return true; -} - -// If the server thread serving clients ever gets into the -// ERROR state, reset the event, close the pipe and remain -// in the error state forever. Error state means something -// that we didn't account for has happened, and it's dangerous -// to do anything unknowingly. -void CrashGenerationServer::HandleErrorState() { - assert(server_state_ == IPC_SERVER_STATE_ERROR); - - // If the server is shutting down anyway, don't clean up - // here since shut down process will clean up. - if (shutting_down_) { - return; - } - - if (pipe_wait_handle_) { - UnregisterWait(pipe_wait_handle_); - pipe_wait_handle_ = NULL; - } - - if (pipe_) { - CloseHandle(pipe_); - pipe_ = NULL; - } - - if (overlapped_.hEvent) { - CloseHandle(overlapped_.hEvent); - overlapped_.hEvent = NULL; - } -} - -// When the server thread serving clients is in the INITIAL state, -// try to connect to the pipe asynchronously. If the connection -// finishes synchronously, directly go into the CONNECTED state; -// otherwise go into the CONNECTING state. For any problems, go -// into the ERROR state. -void CrashGenerationServer::HandleInitialState() { - assert(server_state_ == IPC_SERVER_STATE_INITIAL); - - if (!ResetEvent(overlapped_.hEvent)) { - EnterErrorState(); - return; - } - - bool success = ConnectNamedPipe(pipe_, &overlapped_) != FALSE; - DWORD error_code = success ? ERROR_SUCCESS : GetLastError(); - - // From MSDN, it is not clear that when ConnectNamedPipe is used - // in an overlapped mode, will it ever return non-zero value, and - // if so, in what cases. - assert(!success); - - switch (error_code) { - case ERROR_IO_PENDING: - EnterStateWhenSignaled(IPC_SERVER_STATE_CONNECTING); - break; - - case ERROR_PIPE_CONNECTED: - EnterStateImmediately(IPC_SERVER_STATE_CONNECTED); - break; - - default: - EnterErrorState(); - break; - } -} - -// When the server thread serving the clients is in the CONNECTING state, -// try to get the result of the asynchronous connection request using -// the OVERLAPPED object. If the result indicates the connection is done, -// go into the CONNECTED state. If the result indicates I/O is still -// INCOMPLETE, remain in the CONNECTING state. For any problems, -// go into the DISCONNECTING state. -void CrashGenerationServer::HandleConnectingState() { - assert(server_state_ == IPC_SERVER_STATE_CONNECTING); - - DWORD bytes_count = 0; - bool success = GetOverlappedResult(pipe_, - &overlapped_, - &bytes_count, - FALSE) != FALSE; - DWORD error_code = success ? ERROR_SUCCESS : GetLastError(); - - if (success) { - EnterStateImmediately(IPC_SERVER_STATE_CONNECTED); - } else if (error_code != ERROR_IO_INCOMPLETE) { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - } else { - // remain in CONNECTING state - } -} - -// When the server thread serving the clients is in the CONNECTED state, -// try to issue an asynchronous read from the pipe. If read completes -// synchronously or if I/O is pending then go into the READING state. -// For any problems, go into the DISCONNECTING state. -void CrashGenerationServer::HandleConnectedState() { - assert(server_state_ == IPC_SERVER_STATE_CONNECTED); - - DWORD bytes_count = 0; - memset(&msg_, 0, sizeof(msg_)); - bool success = ReadFile(pipe_, - &msg_, - sizeof(msg_), - &bytes_count, - &overlapped_) != FALSE; - DWORD error_code = success ? ERROR_SUCCESS : GetLastError(); - - // Note that the asynchronous read issued above can finish before the - // code below executes. But, it is okay to change state after issuing - // the asynchronous read. This is because even if the asynchronous read - // is done, the callback for it would not be executed until the current - // thread finishes its execution. - if (success || error_code == ERROR_IO_PENDING) { - EnterStateWhenSignaled(IPC_SERVER_STATE_READING); - } else { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - } -} - -// When the server thread serving the clients is in the READING state, -// try to get the result of the async read. If async read is done, -// go into the READ_DONE state. For any problems, go into the -// DISCONNECTING state. -void CrashGenerationServer::HandleReadingState() { - assert(server_state_ == IPC_SERVER_STATE_READING); - - DWORD bytes_count = 0; - bool success = GetOverlappedResult(pipe_, - &overlapped_, - &bytes_count, - FALSE) != FALSE; - if (success && bytes_count == sizeof(ProtocolMessage)) { - EnterStateImmediately(IPC_SERVER_STATE_READ_DONE); - return; - } - - assert(!CheckForIOIncomplete(success)); - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); -} - -// When the server thread serving the client is in the READ_DONE state, -// validate the client's request message, register the client by -// creating appropriate objects and prepare the response. Then try to -// write the response to the pipe asynchronously. If that succeeds, -// go into the WRITING state. For any problems, go into the DISCONNECTING -// state. -void CrashGenerationServer::HandleReadDoneState() { - assert(server_state_ == IPC_SERVER_STATE_READ_DONE); - - if (!IsClientRequestValid(msg_)) { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - return; - } - - if (msg_.tag == MESSAGE_TAG_UPLOAD_REQUEST) { - if (upload_request_callback_) - upload_request_callback_(upload_context_, msg_.id); - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - return; - } - - scoped_ptr client_info( - new ClientInfo(this, - msg_.id, - msg_.dump_type, - msg_.thread_id, - msg_.exception_pointers, - msg_.assert_info, - msg_.custom_client_info)); - - if (!client_info->Initialize()) { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - return; - } - - // Issues an asynchronous WriteFile call if successful. - // Iff successful, assigns ownership of the client_info pointer to the server - // instance, in which case we must be sure not to free it in this function. - if (!RespondToClient(client_info.get())) { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - return; - } - - // This is only valid as long as it can be found in the clients_ list - client_info_ = client_info.release(); - - // Note that the asynchronous write issued by RespondToClient function - // can finish before the code below executes. But it is okay to change - // state after issuing the asynchronous write. This is because even if - // the asynchronous write is done, the callback for it would not be - // executed until the current thread finishes its execution. - EnterStateWhenSignaled(IPC_SERVER_STATE_WRITING); -} - -// When the server thread serving the clients is in the WRITING state, -// try to get the result of the async write. If the async write is done, -// go into the WRITE_DONE state. For any problems, go into the -// DISONNECTING state. -void CrashGenerationServer::HandleWritingState() { - assert(server_state_ == IPC_SERVER_STATE_WRITING); - - DWORD bytes_count = 0; - bool success = GetOverlappedResult(pipe_, - &overlapped_, - &bytes_count, - FALSE) != FALSE; - if (success) { - EnterStateImmediately(IPC_SERVER_STATE_WRITE_DONE); - return; - } - - assert(!CheckForIOIncomplete(success)); - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); -} - -// When the server thread serving the clients is in the WRITE_DONE state, -// try to issue an async read on the pipe. If the read completes synchronously -// or if I/O is still pending then go into the READING_ACK state. For any -// issues, go into the DISCONNECTING state. -void CrashGenerationServer::HandleWriteDoneState() { - assert(server_state_ == IPC_SERVER_STATE_WRITE_DONE); - - DWORD bytes_count = 0; - bool success = ReadFile(pipe_, - &msg_, - sizeof(msg_), - &bytes_count, - &overlapped_) != FALSE; - DWORD error_code = success ? ERROR_SUCCESS : GetLastError(); - - if (success) { - EnterStateImmediately(IPC_SERVER_STATE_READING_ACK); - } else if (error_code == ERROR_IO_PENDING) { - EnterStateWhenSignaled(IPC_SERVER_STATE_READING_ACK); - } else { - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); - } -} - -// When the server thread serving the clients is in the READING_ACK state, -// try to get result of async read. Go into the DISCONNECTING state. -void CrashGenerationServer::HandleReadingAckState() { - assert(server_state_ == IPC_SERVER_STATE_READING_ACK); - - DWORD bytes_count = 0; - bool success = GetOverlappedResult(pipe_, - &overlapped_, - &bytes_count, - FALSE) != FALSE; - if (success) { - // The connection handshake with the client is now complete; perform - // the callback. - if (connect_callback_) { - // Note that there is only a single copy of the ClientInfo of the - // currently connected client. However it is being referenced from - // two different places: - // - the client_info_ member - // - the clients_ list - // The lifetime of this ClientInfo depends on the lifetime of the - // client process - basically it can go away at any time. - // However, as long as it is referenced by the clients_ list it - // is guaranteed to be valid. Enter the critical section and check - // to see whether the client_info_ can be found in the list. - // If found, execute the callback and only then leave the critical - // section. - AutoCriticalSection lock(&sync_); - - bool client_is_still_alive = false; - std::list::iterator iter; - for (iter = clients_.begin(); iter != clients_.end(); ++iter) { - if (client_info_ == *iter) { - client_is_still_alive = true; - break; - } - } - - if (client_is_still_alive) { - connect_callback_(connect_context_, client_info_); - } - } - } else { - assert(!CheckForIOIncomplete(success)); - } - - EnterStateImmediately(IPC_SERVER_STATE_DISCONNECTING); -} - -// When the server thread serving the client is in the DISCONNECTING state, -// disconnect from the pipe and reset the event. If anything fails, go into -// the ERROR state. If it goes well, go into the INITIAL state and set the -// event to start all over again. -void CrashGenerationServer::HandleDisconnectingState() { - assert(server_state_ == IPC_SERVER_STATE_DISCONNECTING); - - // Done serving the client. - client_info_ = NULL; - - overlapped_.Internal = NULL; - overlapped_.InternalHigh = NULL; - overlapped_.Offset = 0; - overlapped_.OffsetHigh = 0; - overlapped_.Pointer = NULL; - - if (!ResetEvent(overlapped_.hEvent)) { - EnterErrorState(); - return; - } - - if (!DisconnectNamedPipe(pipe_)) { - EnterErrorState(); - return; - } - - // If the server is shutting down do not connect to the - // next client. - if (shutting_down_) { - return; - } - - EnterStateImmediately(IPC_SERVER_STATE_INITIAL); -} - -void CrashGenerationServer::EnterErrorState() { - SetEvent(overlapped_.hEvent); - server_state_ = IPC_SERVER_STATE_ERROR; -} - -void CrashGenerationServer::EnterStateWhenSignaled(IPCServerState state) { - server_state_ = state; -} - -void CrashGenerationServer::EnterStateImmediately(IPCServerState state) { - server_state_ = state; - - if (!SetEvent(overlapped_.hEvent)) { - server_state_ = IPC_SERVER_STATE_ERROR; - } -} - -bool CrashGenerationServer::PrepareReply(const ClientInfo& client_info, - ProtocolMessage* reply) const { - reply->tag = MESSAGE_TAG_REGISTRATION_RESPONSE; - reply->id = GetCurrentProcessId(); - - if (CreateClientHandles(client_info, reply)) { - return true; - } - - // Closing of remote handles (belonging to a different process) can - // only be done through DuplicateHandle. - if (reply->dump_request_handle) { - DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle - reply->dump_request_handle, // hSourceHandle - NULL, // hTargetProcessHandle - 0, // lpTargetHandle - 0, // dwDesiredAccess - FALSE, // bInheritHandle - DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->dump_request_handle = NULL; - } - - if (reply->dump_generated_handle) { - DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle - reply->dump_generated_handle, // hSourceHandle - NULL, // hTargetProcessHandle - 0, // lpTargetHandle - 0, // dwDesiredAccess - FALSE, // bInheritHandle - DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->dump_generated_handle = NULL; - } - - if (reply->server_alive_handle) { - DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle - reply->server_alive_handle, // hSourceHandle - NULL, // hTargetProcessHandle - 0, // lpTargetHandle - 0, // dwDesiredAccess - FALSE, // bInheritHandle - DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->server_alive_handle = NULL; - } - - return false; -} - -bool CrashGenerationServer::CreateClientHandles(const ClientInfo& client_info, - ProtocolMessage* reply) const { - HANDLE current_process = GetCurrentProcess(); - if (!DuplicateHandle(current_process, - client_info.dump_requested_handle(), - client_info.process_handle(), - &reply->dump_request_handle, - kDumpRequestEventAccess, - FALSE, - 0)) { - return false; - } - - if (!DuplicateHandle(current_process, - client_info.dump_generated_handle(), - client_info.process_handle(), - &reply->dump_generated_handle, - kDumpGeneratedEventAccess, - FALSE, - 0)) { - return false; - } - - if (!DuplicateHandle(current_process, - server_alive_handle_, - client_info.process_handle(), - &reply->server_alive_handle, - kMutexAccess, - FALSE, - 0)) { - return false; - } - - return true; -} - -bool CrashGenerationServer::RespondToClient(ClientInfo* client_info) { - ProtocolMessage reply; - if (!PrepareReply(*client_info, &reply)) { - return false; - } - - DWORD bytes_count = 0; - bool success = WriteFile(pipe_, - &reply, - sizeof(reply), - &bytes_count, - &overlapped_) != FALSE; - DWORD error_code = success ? ERROR_SUCCESS : GetLastError(); - - if (!success && error_code != ERROR_IO_PENDING) { - return false; - } - - // Takes over ownership of client_info. We MUST return true if AddClient - // succeeds. - return AddClient(client_info); -} - -// The server thread servicing the clients runs this method. The method -// implements the state machine described in ReadMe.txt along with the -// helper methods HandleXXXState. -void CrashGenerationServer::HandleConnectionRequest() { - // If the server is shutting down, get into ERROR state, reset the event so - // more workers don't run and return immediately. - if (shutting_down_) { - server_state_ = IPC_SERVER_STATE_ERROR; - ResetEvent(overlapped_.hEvent); - return; - } - - switch (server_state_) { - case IPC_SERVER_STATE_ERROR: - HandleErrorState(); - break; - - case IPC_SERVER_STATE_INITIAL: - HandleInitialState(); - break; - - case IPC_SERVER_STATE_CONNECTING: - HandleConnectingState(); - break; - - case IPC_SERVER_STATE_CONNECTED: - HandleConnectedState(); - break; - - case IPC_SERVER_STATE_READING: - HandleReadingState(); - break; - - case IPC_SERVER_STATE_READ_DONE: - HandleReadDoneState(); - break; - - case IPC_SERVER_STATE_WRITING: - HandleWritingState(); - break; - - case IPC_SERVER_STATE_WRITE_DONE: - HandleWriteDoneState(); - break; - - case IPC_SERVER_STATE_READING_ACK: - HandleReadingAckState(); - break; - - case IPC_SERVER_STATE_DISCONNECTING: - HandleDisconnectingState(); - break; - - default: - assert(false); - // This indicates that we added one more state without - // adding handling code. - server_state_ = IPC_SERVER_STATE_ERROR; - break; - } -} - -bool CrashGenerationServer::AddClient(ClientInfo* client_info) { - HANDLE request_wait_handle = NULL; - if (!RegisterWaitForSingleObject(&request_wait_handle, - client_info->dump_requested_handle(), - OnDumpRequest, - client_info, - INFINITE, - kDumpRequestThreadFlags)) { - return false; - } - - client_info->set_dump_request_wait_handle(request_wait_handle); - - // OnClientEnd will be called when the client process terminates. - HANDLE process_wait_handle = NULL; - if (!RegisterWaitForSingleObject(&process_wait_handle, - client_info->process_handle(), - OnClientEnd, - client_info, - INFINITE, - WT_EXECUTEONLYONCE)) { - return false; - } - - client_info->set_process_exit_wait_handle(process_wait_handle); - - // New scope to hold the lock for the shortest time. - { - AutoCriticalSection lock(&sync_); - if (shutting_down_) { - // If server is shutting down, don't add new clients - return false; - } - clients_.push_back(client_info); - } - - return true; -} - -// static -void CALLBACK CrashGenerationServer::OnPipeConnected(void* context, BOOLEAN) { - assert(context); - - CrashGenerationServer* obj = - reinterpret_cast(context); - obj->HandleConnectionRequest(); -} - -// static -void CALLBACK CrashGenerationServer::OnDumpRequest(void* context, BOOLEAN) { - assert(context); - ClientInfo* client_info = reinterpret_cast(context); - - CrashGenerationServer* crash_server = client_info->crash_server(); - assert(crash_server); - if (crash_server->pre_fetch_custom_info_) { - client_info->PopulateCustomInfo(); - } - crash_server->HandleDumpRequest(*client_info); - - ResetEvent(client_info->dump_requested_handle()); -} - -// static -void CALLBACK CrashGenerationServer::OnClientEnd(void* context, BOOLEAN) { - assert(context); - ClientInfo* client_info = reinterpret_cast(context); - - CrashGenerationServer* crash_server = client_info->crash_server(); - assert(crash_server); - - crash_server->HandleClientProcessExit(client_info); -} - -void CrashGenerationServer::HandleClientProcessExit(ClientInfo* client_info) { - assert(client_info); - - // Must unregister the dump request wait operation and wait for any - // dump requests that might be pending to finish before proceeding - // with the client_info cleanup. - client_info->UnregisterDumpRequestWaitAndBlockUntilNoPending(); - - if (exit_callback_) { - exit_callback_(exit_context_, client_info); - } - - // Start a new scope to release lock automatically. - { - AutoCriticalSection lock(&sync_); - if (shutting_down_) { - // The crash generation server is shutting down and as part of the - // shutdown process it will delete all clients from the clients_ list. - return; - } - clients_.remove(client_info); - } - - // Explicitly unregister the process exit wait using the non-blocking method. - // Otherwise, the destructor will attempt to unregister it using the blocking - // method which will lead to a deadlock because it is being called from the - // callback of the same wait operation - client_info->UnregisterProcessExitWait(false); - - delete client_info; -} - -void CrashGenerationServer::HandleDumpRequest(const ClientInfo& client_info) { - bool execute_callback = true; - // Generate the dump only if it's explicitly requested by the - // server application; otherwise the server might want to generate - // dump in the callback. - std::wstring dump_path; - if (generate_dumps_) { - if (!GenerateDump(client_info, &dump_path)) { - // client proccess terminated or some other error - execute_callback = false; - } - } - - if (dump_callback_ && execute_callback) { - std::wstring* ptr_dump_path = (dump_path == L"") ? NULL : &dump_path; - dump_callback_(dump_context_, &client_info, ptr_dump_path); - } - - SetEvent(client_info.dump_generated_handle()); -} - -bool CrashGenerationServer::GenerateDump(const ClientInfo& client, - std::wstring* dump_path) { - assert(client.pid() != 0); - assert(client.process_handle()); - - // We have to get the address of EXCEPTION_INFORMATION from - // the client process address space. - EXCEPTION_POINTERS* client_ex_info = NULL; - if (!client.GetClientExceptionInfo(&client_ex_info)) { - return false; - } - - DWORD client_thread_id = 0; - if (!client.GetClientThreadId(&client_thread_id)) { - return false; - } - - MinidumpGenerator dump_generator(dump_path_, - client.process_handle(), - client.pid(), - client_thread_id, - GetCurrentThreadId(), - client_ex_info, - client.assert_info(), - client.dump_type(), - true); - if (!dump_generator.GenerateDumpFile(dump_path)) { - return false; - } - return dump_generator.WriteMinidump(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.h b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.h deleted file mode 100644 index 0ea90e510..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/crash_generation_server.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ -#define CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ - -#include -#include -#include "client/windows/common/ipc_protocol.h" -#include "client/windows/crash_generation/minidump_generator.h" -#include "common/scoped_ptr.h" - -namespace google_breakpad { -class ClientInfo; - -// Abstraction for server side implementation of out-of-process crash -// generation protocol for Windows platform only. It generates Windows -// minidump files for client processes that request dump generation. When -// the server is requested to start listening for clients (by calling the -// Start method), it creates a named pipe and waits for the clients to -// register. In response, it hands them event handles that the client can -// signal to request dump generation. When the clients request dump -// generation in this way, the server generates Windows minidump files. -class CrashGenerationServer { - public: - typedef void (*OnClientConnectedCallback)(void* context, - const ClientInfo* client_info); - - typedef void (*OnClientDumpRequestCallback)(void* context, - const ClientInfo* client_info, - const std::wstring* file_path); - - typedef void (*OnClientExitedCallback)(void* context, - const ClientInfo* client_info); - - typedef void (*OnClientUploadRequestCallback)(void* context, - const DWORD crash_id); - - // Creates an instance with the given parameters. - // - // Parameter pipe_name: Name of the Windows named pipe - // Parameter pipe_sec_attrs Security attributes to set on the pipe. Pass - // NULL to use default security on the pipe. By default, the pipe created - // allows Local System, Administrators and the Creator full control and - // the Everyone group read access on the pipe. - // Parameter connect_callback: Callback for a new client connection. - // Parameter connect_context: Context for client connection callback. - // Parameter crash_callback: Callback for a client crash dump request. - // Parameter crash_context: Context for client crash dump request callback. - // Parameter exit_callback: Callback for client process exit. - // Parameter exit_context: Context for client exit callback. - // Parameter generate_dumps: Whether to automatically generate dumps. - // Client code of this class might want to generate dumps explicitly in the - // crash dump request callback. In that case, false can be passed for this - // parameter. - // Parameter dump_path: Path for generating dumps; required only if true is - // passed for generateDumps parameter; NULL can be passed otherwise. - CrashGenerationServer(const std::wstring& pipe_name, - SECURITY_ATTRIBUTES* pipe_sec_attrs, - OnClientConnectedCallback connect_callback, - void* connect_context, - OnClientDumpRequestCallback dump_callback, - void* dump_context, - OnClientExitedCallback exit_callback, - void* exit_context, - OnClientUploadRequestCallback upload_request_callback, - void* upload_context, - bool generate_dumps, - const std::wstring* dump_path); - - ~CrashGenerationServer(); - - // Performs initialization steps needed to start listening to clients. Upon - // successful return clients may connect to this server's pipe. - // - // Returns true if initialization is successful; false otherwise. - bool Start(); - - void pre_fetch_custom_info(bool do_pre_fetch) { - pre_fetch_custom_info_ = do_pre_fetch; - } - - private: - // Various states the client can be in during the handshake with - // the server. - enum IPCServerState { - // Server starts in this state. - IPC_SERVER_STATE_UNINITIALIZED, - - // Server is in error state and it cannot serve any clients. - IPC_SERVER_STATE_ERROR, - - // Server starts in this state. - IPC_SERVER_STATE_INITIAL, - - // Server has issued an async connect to the pipe and it is waiting - // for the connection to be established. - IPC_SERVER_STATE_CONNECTING, - - // Server is connected successfully. - IPC_SERVER_STATE_CONNECTED, - - // Server has issued an async read from the pipe and it is waiting for - // the read to finish. - IPC_SERVER_STATE_READING, - - // Server is done reading from the pipe. - IPC_SERVER_STATE_READ_DONE, - - // Server has issued an async write to the pipe and it is waiting for - // the write to finish. - IPC_SERVER_STATE_WRITING, - - // Server is done writing to the pipe. - IPC_SERVER_STATE_WRITE_DONE, - - // Server has issued an async read from the pipe for an ack and it - // is waiting for the read to finish. - IPC_SERVER_STATE_READING_ACK, - - // Server is done writing to the pipe and it is now ready to disconnect - // and reconnect. - IPC_SERVER_STATE_DISCONNECTING - }; - - // - // Helper methods to handle various server IPC states. - // - void HandleErrorState(); - void HandleInitialState(); - void HandleConnectingState(); - void HandleConnectedState(); - void HandleReadingState(); - void HandleReadDoneState(); - void HandleWritingState(); - void HandleWriteDoneState(); - void HandleReadingAckState(); - void HandleDisconnectingState(); - - // Prepares reply for a client from the given parameters. - bool PrepareReply(const ClientInfo& client_info, - ProtocolMessage* reply) const; - - // Duplicates various handles in the ClientInfo object for the client - // process and stores them in the given ProtocolMessage instance. If - // creating any handle fails, ProtocolMessage will contain the handles - // already created successfully, which should be closed by the caller. - bool CreateClientHandles(const ClientInfo& client_info, - ProtocolMessage* reply) const; - - // Response to the given client. Return true if all steps of - // responding to the client succeed, false otherwise. - bool RespondToClient(ClientInfo* client_info); - - // Handles a connection request from the client. - void HandleConnectionRequest(); - - // Handles a dump request from the client. - void HandleDumpRequest(const ClientInfo& client_info); - - // Callback for pipe connected event. - static void CALLBACK OnPipeConnected(void* context, BOOLEAN timer_or_wait); - - // Callback for a dump request. - static void CALLBACK OnDumpRequest(void* context, BOOLEAN timer_or_wait); - - // Callback for client process exit event. - static void CALLBACK OnClientEnd(void* context, BOOLEAN timer_or_wait); - - // Handles client process exit. - void HandleClientProcessExit(ClientInfo* client_info); - - // Adds the given client to the list of registered clients. - bool AddClient(ClientInfo* client_info); - - // Generates dump for the given client. - bool GenerateDump(const ClientInfo& client, std::wstring* dump_path); - - // Puts the server in a permanent error state and sets a signal such that - // the state will be immediately entered after the current state transition - // is complete. - void EnterErrorState(); - - // Puts the server in the specified state and sets a signal such that the - // state is immediately entered after the current state transition is - // complete. - void EnterStateImmediately(IPCServerState state); - - // Puts the server in the specified state. No signal will be set, so the state - // transition will only occur when signaled manually or by completion of an - // asynchronous IO operation. - void EnterStateWhenSignaled(IPCServerState state); - - // Sync object for thread-safe access to the shared list of clients. - CRITICAL_SECTION sync_; - - // List of clients. - std::list clients_; - - // Pipe name. - std::wstring pipe_name_; - - // Pipe security attributes - SECURITY_ATTRIBUTES* pipe_sec_attrs_; - - // Handle to the pipe used for handshake with clients. - HANDLE pipe_; - - // Pipe wait handle. - HANDLE pipe_wait_handle_; - - // Handle to server-alive mutex. - HANDLE server_alive_handle_; - - // Callback for a successful client connection. - OnClientConnectedCallback connect_callback_; - - // Context for client connected callback. - void* connect_context_; - - // Callback for a client dump request. - OnClientDumpRequestCallback dump_callback_; - - // Context for client dump request callback. - void* dump_context_; - - // Callback for client process exit. - OnClientExitedCallback exit_callback_; - - // Context for client process exit callback. - void* exit_context_; - - // Callback for upload request. - OnClientUploadRequestCallback upload_request_callback_; - - // Context for upload request callback. - void* upload_context_; - - // Whether to generate dumps. - bool generate_dumps_; - - // Wether to populate custom information up-front. - bool pre_fetch_custom_info_; - - // The dump path for the server. - const std::wstring dump_path_; - - // State of the server in performing the IPC with the client. - // Note that since we restrict the pipe to one instance, we - // only need to keep one state of the server. Otherwise, server - // would have one state per client it is talking to. - IPCServerState server_state_; - - // Whether the server is shutting down. - bool shutting_down_; - - // Overlapped instance for async I/O on the pipe. - OVERLAPPED overlapped_; - - // Message object used in IPC with the client. - ProtocolMessage msg_; - - // Client Info for the client that's connecting to the server. - ClientInfo* client_info_; - - // Disable copy ctor and operator=. - CrashGenerationServer(const CrashGenerationServer& crash_server); - CrashGenerationServer& operator=(const CrashGenerationServer& crash_server); -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.cc deleted file mode 100644 index 786c9b937..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.cc +++ /dev/null @@ -1,579 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/crash_generation/minidump_generator.h" - -#include -#include - -#include -#include -#include -#include - -#include "client/windows/common/auto_critical_section.h" -#include "common/scoped_ptr.h" -#include "common/windows/guid_string.h" - -using std::wstring; - -namespace { - -// A helper class used to collect handle operations data. Unlike -// |MiniDumpWithHandleData| it records the operations for a single handle value -// only, making it possible to include this information to a minidump. -class HandleTraceData { - public: - HandleTraceData(); - ~HandleTraceData(); - - // Collects the handle operations data and formats a user stream to be added - // to the minidump. - bool CollectHandleData(HANDLE process_handle, - EXCEPTION_POINTERS* exception_pointers); - - // Fills the user dump entry with a pointer to the collected handle operations - // data. Returns |true| if the entry was initialized successfully, or |false| - // if no trace data is available. - bool GetUserStream(MINIDUMP_USER_STREAM* user_stream); - - private: - // Reads the exception code from the client process's address space. - // This routine assumes that the client process's pointer width matches ours. - static bool ReadExceptionCode(HANDLE process_handle, - EXCEPTION_POINTERS* exception_pointers, - DWORD* exception_code); - - // Stores handle operations retrieved by VerifierEnumerateResource(). - static ULONG CALLBACK RecordHandleOperations(void* resource_description, - void* enumeration_context, - ULONG* enumeration_level); - - // Function pointer type for VerifierEnumerateResource, which is looked up - // dynamically. - typedef BOOL (WINAPI* VerifierEnumerateResourceType)( - HANDLE Process, - ULONG Flags, - ULONG ResourceType, - AVRF_RESOURCE_ENUMERATE_CALLBACK ResourceCallback, - PVOID EnumerationContext); - - // Handle to dynamically loaded verifier.dll. - HMODULE verifier_module_; - - // Pointer to the VerifierEnumerateResource function. - VerifierEnumerateResourceType enumerate_resource_; - - // Handle value to look for. - ULONG64 handle_; - - // List of handle operations for |handle_|. - std::list operations_; - - // Minidump stream data. - std::vector stream_; -}; - -HandleTraceData::HandleTraceData() - : verifier_module_(NULL), - enumerate_resource_(NULL), - handle_(NULL) { -} - -HandleTraceData::~HandleTraceData() { - if (verifier_module_) { - FreeLibrary(verifier_module_); - } -} - -bool HandleTraceData::CollectHandleData( - HANDLE process_handle, - EXCEPTION_POINTERS* exception_pointers) { - DWORD exception_code; - if (!ReadExceptionCode(process_handle, exception_pointers, &exception_code)) { - return false; - } - - // Verify whether the execption is STATUS_INVALID_HANDLE. Do not record any - // handle information if it is a different exception to keep the minidump - // small. - if (exception_code != STATUS_INVALID_HANDLE) { - return true; - } - - // Load verifier!VerifierEnumerateResource() dynamically. - verifier_module_ = LoadLibrary(TEXT("verifier.dll")); - if (!verifier_module_) { - return false; - } - - enumerate_resource_ = reinterpret_cast( - GetProcAddress(verifier_module_, "VerifierEnumerateResource")); - if (!enumerate_resource_) { - return false; - } - - // STATUS_INVALID_HANDLE does not provide the offending handle value in - // the exception parameters so we have to guess. At the moment we scan - // the handle operations trace looking for the last invalid handle operation - // and record only the operations for that handle value. - if (enumerate_resource_(process_handle, - 0, - AvrfResourceHandleTrace, - &RecordHandleOperations, - this) != ERROR_SUCCESS) { - // The handle tracing must have not been enabled. - return true; - } - - // Now that |handle_| is initialized, purge all irrelevant operations. - std::list::iterator i = operations_.begin(); - std::list::iterator i_end = operations_.end(); - while (i != i_end) { - if (i->Handle == handle_) { - ++i; - } else { - i = operations_.erase(i); - } - } - - // Convert the list of recorded operations to a minidump stream. - stream_.resize(sizeof(MINIDUMP_HANDLE_OPERATION_LIST) + - sizeof(AVRF_HANDLE_OPERATION) * operations_.size()); - - MINIDUMP_HANDLE_OPERATION_LIST* stream_data = - reinterpret_cast( - &stream_.front()); - stream_data->SizeOfHeader = sizeof(MINIDUMP_HANDLE_OPERATION_LIST); - stream_data->SizeOfEntry = sizeof(AVRF_HANDLE_OPERATION); - stream_data->NumberOfEntries = static_cast(operations_.size()); - stream_data->Reserved = 0; - std::copy(operations_.begin(), - operations_.end(), -#ifdef _MSC_VER - stdext::checked_array_iterator( - reinterpret_cast(stream_data + 1), - operations_.size()) -#else - reinterpret_cast(stream_data + 1) -#endif - ); - - return true; -} - -bool HandleTraceData::GetUserStream(MINIDUMP_USER_STREAM* user_stream) { - if (stream_.empty()) { - return false; - } else { - user_stream->Type = HandleOperationListStream; - user_stream->BufferSize = static_cast(stream_.size()); - user_stream->Buffer = &stream_.front(); - return true; - } -} - -bool HandleTraceData::ReadExceptionCode( - HANDLE process_handle, - EXCEPTION_POINTERS* exception_pointers, - DWORD* exception_code) { - EXCEPTION_POINTERS pointers; - if (!ReadProcessMemory(process_handle, - exception_pointers, - &pointers, - sizeof(pointers), - NULL)) { - return false; - } - - if (!ReadProcessMemory(process_handle, - pointers.ExceptionRecord, - exception_code, - sizeof(*exception_code), - NULL)) { - return false; - } - - return true; -} - -ULONG CALLBACK HandleTraceData::RecordHandleOperations( - void* resource_description, - void* enumeration_context, - ULONG* enumeration_level) { - AVRF_HANDLE_OPERATION* description = - reinterpret_cast(resource_description); - HandleTraceData* self = - reinterpret_cast(enumeration_context); - - // Remember the last invalid handle operation. - if (description->OperationType == OperationDbBADREF) { - self->handle_ = description->Handle; - } - - // Record all handle operations. - self->operations_.push_back(*description); - - *enumeration_level = HeapEnumerationEverything; - return ERROR_SUCCESS; -} - -} // namespace - -namespace google_breakpad { - -MinidumpGenerator::MinidumpGenerator( - const std::wstring& dump_path, - const HANDLE process_handle, - const DWORD process_id, - const DWORD thread_id, - const DWORD requesting_thread_id, - EXCEPTION_POINTERS* exception_pointers, - MDRawAssertionInfo* assert_info, - const MINIDUMP_TYPE dump_type, - const bool is_client_pointers) - : dbghelp_module_(NULL), - write_dump_(NULL), - rpcrt4_module_(NULL), - create_uuid_(NULL), - process_handle_(process_handle), - process_id_(process_id), - thread_id_(thread_id), - requesting_thread_id_(requesting_thread_id), - exception_pointers_(exception_pointers), - assert_info_(assert_info), - dump_type_(dump_type), - is_client_pointers_(is_client_pointers), - dump_path_(dump_path), - dump_file_(INVALID_HANDLE_VALUE), - full_dump_file_(INVALID_HANDLE_VALUE), - dump_file_is_internal_(false), - full_dump_file_is_internal_(false), - additional_streams_(NULL), - callback_info_(NULL) { - InitializeCriticalSection(&module_load_sync_); - InitializeCriticalSection(&get_proc_address_sync_); -} - -MinidumpGenerator::~MinidumpGenerator() { - if (dump_file_is_internal_ && dump_file_ != INVALID_HANDLE_VALUE) { - CloseHandle(dump_file_); - } - - if (full_dump_file_is_internal_ && full_dump_file_ != INVALID_HANDLE_VALUE) { - CloseHandle(full_dump_file_); - } - - if (dbghelp_module_) { - FreeLibrary(dbghelp_module_); - } - - if (rpcrt4_module_) { - FreeLibrary(rpcrt4_module_); - } - - DeleteCriticalSection(&get_proc_address_sync_); - DeleteCriticalSection(&module_load_sync_); -} - -bool MinidumpGenerator::WriteMinidump() { - bool full_memory_dump = (dump_type_ & MiniDumpWithFullMemory) != 0; - if (dump_file_ == INVALID_HANDLE_VALUE || - (full_memory_dump && full_dump_file_ == INVALID_HANDLE_VALUE)) { - return false; - } - - MiniDumpWriteDumpType write_dump = GetWriteDump(); - if (!write_dump) { - return false; - } - - MINIDUMP_EXCEPTION_INFORMATION* dump_exception_pointers = NULL; - MINIDUMP_EXCEPTION_INFORMATION dump_exception_info; - - // Setup the exception information object only if it's a dump - // due to an exception. - if (exception_pointers_) { - dump_exception_pointers = &dump_exception_info; - dump_exception_info.ThreadId = thread_id_; - dump_exception_info.ExceptionPointers = exception_pointers_; - dump_exception_info.ClientPointers = is_client_pointers_; - } - - // Add an MDRawBreakpadInfo stream to the minidump, to provide additional - // information about the exception handler to the Breakpad processor. - // The information will help the processor determine which threads are - // relevant. The Breakpad processor does not require this information but - // can function better with Breakpad-generated dumps when it is present. - // The native debugger is not harmed by the presence of this information. - MDRawBreakpadInfo breakpad_info = {0}; - if (!is_client_pointers_) { - // Set the dump thread id and requesting thread id only in case of - // in-process dump generation. - breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; - breakpad_info.dump_thread_id = thread_id_; - breakpad_info.requesting_thread_id = requesting_thread_id_; - } - - int additional_streams_count = additional_streams_ ? - additional_streams_->UserStreamCount : 0; - scoped_array user_stream_array( - new MINIDUMP_USER_STREAM[3 + additional_streams_count]); - user_stream_array[0].Type = MD_BREAKPAD_INFO_STREAM; - user_stream_array[0].BufferSize = sizeof(breakpad_info); - user_stream_array[0].Buffer = &breakpad_info; - - MINIDUMP_USER_STREAM_INFORMATION user_streams; - user_streams.UserStreamCount = 1; - user_streams.UserStreamArray = user_stream_array.get(); - - MDRawAssertionInfo* actual_assert_info = assert_info_; - MDRawAssertionInfo client_assert_info = {{0}}; - - if (assert_info_) { - // If the assertion info object lives in the client process, - // read the memory of the client process. - if (is_client_pointers_) { - SIZE_T bytes_read = 0; - if (!ReadProcessMemory(process_handle_, - assert_info_, - &client_assert_info, - sizeof(client_assert_info), - &bytes_read)) { - if (dump_file_is_internal_) - CloseHandle(dump_file_); - if (full_dump_file_is_internal_ && - full_dump_file_ != INVALID_HANDLE_VALUE) - CloseHandle(full_dump_file_); - return false; - } - - if (bytes_read != sizeof(client_assert_info)) { - if (dump_file_is_internal_) - CloseHandle(dump_file_); - if (full_dump_file_is_internal_ && - full_dump_file_ != INVALID_HANDLE_VALUE) - CloseHandle(full_dump_file_); - return false; - } - - actual_assert_info = &client_assert_info; - } - - user_stream_array[1].Type = MD_ASSERTION_INFO_STREAM; - user_stream_array[1].BufferSize = sizeof(MDRawAssertionInfo); - user_stream_array[1].Buffer = actual_assert_info; - ++user_streams.UserStreamCount; - } - - if (additional_streams_) { - for (size_t i = 0; - i < additional_streams_->UserStreamCount; - i++, user_streams.UserStreamCount++) { - user_stream_array[user_streams.UserStreamCount].Type = - additional_streams_->UserStreamArray[i].Type; - user_stream_array[user_streams.UserStreamCount].BufferSize = - additional_streams_->UserStreamArray[i].BufferSize; - user_stream_array[user_streams.UserStreamCount].Buffer = - additional_streams_->UserStreamArray[i].Buffer; - } - } - - // If the process is terminated by STATUS_INVALID_HANDLE exception store - // the trace of operations for the offending handle value. Do nothing special - // if the client already requested the handle trace to be stored in the dump. - HandleTraceData handle_trace_data; - if (exception_pointers_ && (dump_type_ & MiniDumpWithHandleData) == 0) { - if (!handle_trace_data.CollectHandleData(process_handle_, - exception_pointers_)) { - if (dump_file_is_internal_) - CloseHandle(dump_file_); - if (full_dump_file_is_internal_ && - full_dump_file_ != INVALID_HANDLE_VALUE) - CloseHandle(full_dump_file_); - return false; - } - } - - bool result_full_memory = true; - if (full_memory_dump) { - result_full_memory = write_dump( - process_handle_, - process_id_, - full_dump_file_, - static_cast((dump_type_ & (~MiniDumpNormal)) - | MiniDumpWithHandleData), - exception_pointers_ ? &dump_exception_info : NULL, - &user_streams, - NULL) != FALSE; - } - - // Add handle operations trace stream to the minidump if it was collected. - if (handle_trace_data.GetUserStream( - &user_stream_array[user_streams.UserStreamCount])) { - ++user_streams.UserStreamCount; - } - - bool result_minidump = write_dump( - process_handle_, - process_id_, - dump_file_, - static_cast((dump_type_ & (~MiniDumpWithFullMemory)) - | MiniDumpNormal), - exception_pointers_ ? &dump_exception_info : NULL, - &user_streams, - callback_info_) != FALSE; - - return result_minidump && result_full_memory; -} - -bool MinidumpGenerator::GenerateDumpFile(wstring* dump_path) { - // The dump file was already set by handle or this function was previously - // called. - if (dump_file_ != INVALID_HANDLE_VALUE) { - return false; - } - - wstring dump_file_path; - if (!GenerateDumpFilePath(&dump_file_path)) { - return false; - } - - dump_file_ = CreateFile(dump_file_path.c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (dump_file_ == INVALID_HANDLE_VALUE) { - return false; - } - - dump_file_is_internal_ = true; - *dump_path = dump_file_path; - return true; -} - -bool MinidumpGenerator::GenerateFullDumpFile(wstring* full_dump_path) { - // A full minidump was not requested. - if ((dump_type_ & MiniDumpWithFullMemory) == 0) { - return false; - } - - // The dump file was already set by handle or this function was previously - // called. - if (full_dump_file_ != INVALID_HANDLE_VALUE) { - return false; - } - - wstring full_dump_file_path; - if (!GenerateDumpFilePath(&full_dump_file_path)) { - return false; - } - full_dump_file_path.resize(full_dump_file_path.size() - 4); // strip .dmp - full_dump_file_path.append(TEXT("-full.dmp")); - - full_dump_file_ = CreateFile(full_dump_file_path.c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (full_dump_file_ == INVALID_HANDLE_VALUE) { - return false; - } - - full_dump_file_is_internal_ = true; - *full_dump_path = full_dump_file_path; - return true; -} - -HMODULE MinidumpGenerator::GetDbghelpModule() { - AutoCriticalSection lock(&module_load_sync_); - if (!dbghelp_module_) { - dbghelp_module_ = LoadLibrary(TEXT("dbghelp.dll")); - } - - return dbghelp_module_; -} - -MinidumpGenerator::MiniDumpWriteDumpType MinidumpGenerator::GetWriteDump() { - AutoCriticalSection lock(&get_proc_address_sync_); - if (!write_dump_) { - HMODULE module = GetDbghelpModule(); - if (module) { - FARPROC proc = GetProcAddress(module, "MiniDumpWriteDump"); - write_dump_ = reinterpret_cast(proc); - } - } - - return write_dump_; -} - -HMODULE MinidumpGenerator::GetRpcrt4Module() { - AutoCriticalSection lock(&module_load_sync_); - if (!rpcrt4_module_) { - rpcrt4_module_ = LoadLibrary(TEXT("rpcrt4.dll")); - } - - return rpcrt4_module_; -} - -MinidumpGenerator::UuidCreateType MinidumpGenerator::GetCreateUuid() { - AutoCriticalSection lock(&module_load_sync_); - if (!create_uuid_) { - HMODULE module = GetRpcrt4Module(); - if (module) { - FARPROC proc = GetProcAddress(module, "UuidCreate"); - create_uuid_ = reinterpret_cast(proc); - } - } - - return create_uuid_; -} - -bool MinidumpGenerator::GenerateDumpFilePath(wstring* file_path) { - UUID id = {0}; - - UuidCreateType create_uuid = GetCreateUuid(); - if (!create_uuid) { - return false; - } - - create_uuid(&id); - wstring id_str = GUIDString::GUIDToWString(&id); - - *file_path = dump_path_ + TEXT("\\") + id_str + TEXT(".dmp"); - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.h b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.h deleted file mode 100644 index a3c123056..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/minidump_generator.h +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_ -#define CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_ - -#include -#include -#include -#include -#include -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// Abstraction for various objects and operations needed to generate -// minidump on Windows. This abstraction is useful to hide all the gory -// details for minidump generation and provide a clean interface to -// the clients to generate minidumps. -class MinidumpGenerator { - public: - // Creates an instance with the given parameters. - // is_client_pointers specifies whether the exception_pointers and - // assert_info point into the process that is being dumped. - // Before calling WriteMinidump on the returned instance a dump file muct be - // specified by a call to either SetDumpFile() or GenerateDumpFile(). - // If a full dump file will be requested via a subsequent call to either - // SetFullDumpFile or GenerateFullDumpFile() dump_type must include - // MiniDumpWithFullMemory. - MinidumpGenerator(const std::wstring& dump_path, - const HANDLE process_handle, - const DWORD process_id, - const DWORD thread_id, - const DWORD requesting_thread_id, - EXCEPTION_POINTERS* exception_pointers, - MDRawAssertionInfo* assert_info, - const MINIDUMP_TYPE dump_type, - const bool is_client_pointers); - - ~MinidumpGenerator(); - - void SetDumpFile(const HANDLE dump_file) { dump_file_ = dump_file; } - void SetFullDumpFile(const HANDLE full_dump_file) { - full_dump_file_ = full_dump_file; - } - - // Generate the name for the dump file that will be written to once - // WriteMinidump() is called. Can only be called once and cannot be called - // if the dump file is set via SetDumpFile(). - bool GenerateDumpFile(std::wstring* dump_path); - - // Generate the name for the full dump file that will be written to once - // WriteMinidump() is called. Cannot be called unless the minidump type - // includes MiniDumpWithFullMemory. Can only be called once and cannot be - // called if the dump file is set via SetFullDumpFile(). - bool GenerateFullDumpFile(std::wstring* full_dump_path); - - void SetAdditionalStreams( - MINIDUMP_USER_STREAM_INFORMATION* additional_streams) { - additional_streams_ = additional_streams; - } - - void SetCallback(MINIDUMP_CALLBACK_INFORMATION* callback_info) { - callback_info_ = callback_info; - } - - // Writes the minidump with the given parameters. Stores the - // dump file path in the dump_path parameter if dump generation - // succeeds. - bool WriteMinidump(); - - private: - // Function pointer type for MiniDumpWriteDump, which is looked up - // dynamically. - typedef BOOL (WINAPI* MiniDumpWriteDumpType)( - HANDLE hProcess, - DWORD ProcessId, - HANDLE hFile, - MINIDUMP_TYPE DumpType, - CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); - - // Function pointer type for UuidCreate, which is looked up dynamically. - typedef RPC_STATUS (RPC_ENTRY* UuidCreateType)(UUID* Uuid); - - // Loads the appropriate DLL lazily in a thread safe way. - HMODULE GetDbghelpModule(); - - // Loads the appropriate DLL and gets a pointer to the MiniDumpWriteDump - // function lazily and in a thread-safe manner. - MiniDumpWriteDumpType GetWriteDump(); - - // Loads the appropriate DLL lazily in a thread safe way. - HMODULE GetRpcrt4Module(); - - // Loads the appropriate DLL and gets a pointer to the UuidCreate - // function lazily and in a thread-safe manner. - UuidCreateType GetCreateUuid(); - - // Returns the path for the file to write dump to. - bool GenerateDumpFilePath(std::wstring* file_path); - - // Handle to dynamically loaded DbgHelp.dll. - HMODULE dbghelp_module_; - - // Pointer to the MiniDumpWriteDump function. - MiniDumpWriteDumpType write_dump_; - - // Handle to dynamically loaded rpcrt4.dll. - HMODULE rpcrt4_module_; - - // Pointer to the UuidCreate function. - UuidCreateType create_uuid_; - - // Handle for the process to dump. - HANDLE process_handle_; - - // Process ID for the process to dump. - DWORD process_id_; - - // The crashing thread ID. - DWORD thread_id_; - - // The thread ID which is requesting the dump. - DWORD requesting_thread_id_; - - // Pointer to the exception information for the crash. This may point to an - // address in the crashing process so it should not be dereferenced. - EXCEPTION_POINTERS* exception_pointers_; - - // Assertion info for the report. - MDRawAssertionInfo* assert_info_; - - // Type of minidump to generate. - MINIDUMP_TYPE dump_type_; - - // Specifies whether the exception_pointers_ reference memory in the crashing - // process. - bool is_client_pointers_; - - // Folder path to store dump files. - std::wstring dump_path_; - - // The file where the dump will be written. - HANDLE dump_file_; - - // The file where the full dump will be written. - HANDLE full_dump_file_; - - // Tracks whether the dump file handle is managed externally. - bool dump_file_is_internal_; - - // Tracks whether the full dump file handle is managed externally. - bool full_dump_file_is_internal_; - - // Additional streams to be written to the dump. - MINIDUMP_USER_STREAM_INFORMATION* additional_streams_; - - // The user defined callback for the various stages of the dump process. - MINIDUMP_CALLBACK_INFORMATION* callback_info_; - - // Critical section to sychronize action of loading modules dynamically. - CRITICAL_SECTION module_load_sync_; - - // Critical section to synchronize action of dynamically getting function - // addresses from modules. - CRITICAL_SECTION get_proc_address_sync_; -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_CRASH_GENERATION_MINIDUMP_GENERATOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/objs.mozbuild b/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/objs.mozbuild deleted file mode 100644 index 549c14e10..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation/objs.mozbuild +++ /dev/null @@ -1,17 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -lobjs_crash_generation = [ - 'client_info.cc', - 'crash_generation_client.cc', - 'crash_generation_server.cc', - 'minidump_generator.cc', -] - -subdir = 'toolkit/crashreporter/google-breakpad/src/client/windows/crash_generation' -objs_crash_generation = [ - '/%s/%s' % (subdir, s) for s in lobjs_crash_generation -] diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.cc deleted file mode 100644 index 1f7b19f9a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.cc +++ /dev/null @@ -1,1073 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include -#include - -#include "common/windows/string_utils-inl.h" - -#include "client/windows/common/ipc_protocol.h" -#include "client/windows/handler/exception_handler.h" -#include "common/windows/guid_string.h" - -namespace google_breakpad { - -// This is passed as the context to the MinidumpWriteDump callback. -typedef struct { - AppMemoryList::const_iterator iter; - AppMemoryList::const_iterator end; -} MinidumpCallbackContext; - -vector* ExceptionHandler::handler_stack_ = NULL; -LONG ExceptionHandler::handler_stack_index_ = 0; -CRITICAL_SECTION ExceptionHandler::handler_stack_critical_section_; -volatile LONG ExceptionHandler::instance_count_ = 0; - -ExceptionHandler::ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - const wchar_t* pipe_name, - const CustomClientInfo* custom_info) { - Initialize(dump_path, - filter, - callback, - callback_context, - handler_types, - dump_type, - pipe_name, - NULL, // pipe_handle - NULL, // crash_generation_client - custom_info); -} - -ExceptionHandler::ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - HANDLE pipe_handle, - const CustomClientInfo* custom_info) { - Initialize(dump_path, - filter, - callback, - callback_context, - handler_types, - dump_type, - NULL, // pipe_name - pipe_handle, - NULL, // crash_generation_client - custom_info); -} - -ExceptionHandler::ExceptionHandler( - const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - CrashGenerationClient* crash_generation_client) { - // The dump_type, pipe_name and custom_info that are passed in to Initialize() - // are not used. The ones set in crash_generation_client are used instead. - Initialize(dump_path, - filter, - callback, - callback_context, - handler_types, - MiniDumpNormal, // dump_type - not used - NULL, // pipe_name - not used - NULL, // pipe_handle - crash_generation_client, - NULL); // custom_info - not used -} - -ExceptionHandler::ExceptionHandler(const wstring &dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types) { - Initialize(dump_path, - filter, - callback, - callback_context, - handler_types, - MiniDumpNormal, - NULL, // pipe_name - NULL, // pipe_handle - NULL, // crash_generation_client - NULL); // custom_info -} - -void ExceptionHandler::Initialize( - const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - const wchar_t* pipe_name, - HANDLE pipe_handle, - CrashGenerationClient* crash_generation_client, - const CustomClientInfo* custom_info) { - LONG instance_count = InterlockedIncrement(&instance_count_); - filter_ = filter; - callback_ = callback; - callback_context_ = callback_context; - dump_path_c_ = NULL; - next_minidump_id_c_ = NULL; - next_minidump_path_c_ = NULL; - dbghelp_module_ = NULL; - minidump_write_dump_ = NULL; - dump_type_ = dump_type; - rpcrt4_module_ = NULL; - uuid_create_ = NULL; - handler_types_ = handler_types; - previous_filter_ = NULL; -#if _MSC_VER >= 1400 // MSVC 2005/8 - previous_iph_ = NULL; -#endif // _MSC_VER >= 1400 - previous_pch_ = NULL; - handler_thread_ = NULL; - is_shutdown_ = false; - handler_start_semaphore_ = NULL; - handler_finish_semaphore_ = NULL; - requesting_thread_id_ = 0; - exception_info_ = NULL; - assertion_ = NULL; - handler_return_value_ = false; - handle_debug_exceptions_ = false; - consume_invalid_handle_exceptions_ = false; - - // Attempt to use out-of-process if user has specified a pipe or a - // crash generation client. - scoped_ptr client; - if (crash_generation_client) { - client.reset(crash_generation_client); - } else if (pipe_name) { - client.reset( - new CrashGenerationClient(pipe_name, dump_type_, custom_info)); - } else if (pipe_handle) { - client.reset( - new CrashGenerationClient(pipe_handle, dump_type_, custom_info)); - } - - if (client.get() != NULL) { - // If successful in registering with the monitoring process, - // there is no need to setup in-process crash generation. - if (client->Register()) { - crash_generation_client_.reset(client.release()); - } - } - - if (!IsOutOfProcess()) { - // Either client did not ask for out-of-process crash generation - // or registration with the server process failed. In either case, - // setup to do in-process crash generation. - - // Set synchronization primitives and the handler thread. Each - // ExceptionHandler object gets its own handler thread because that's the - // only way to reliably guarantee sufficient stack space in an exception, - // and it allows an easy way to get a snapshot of the requesting thread's - // context outside of an exception. - InitializeCriticalSection(&handler_critical_section_); - handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); - assert(handler_start_semaphore_ != NULL); - - handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); - assert(handler_finish_semaphore_ != NULL); - - // Don't attempt to create the thread if we could not create the semaphores. - if (handler_finish_semaphore_ != NULL && handler_start_semaphore_ != NULL) { - DWORD thread_id; - const int kExceptionHandlerThreadInitialStackSize = 64 * 1024; - handler_thread_ = CreateThread(NULL, // lpThreadAttributes - kExceptionHandlerThreadInitialStackSize, - ExceptionHandlerThreadMain, - this, // lpParameter - 0, // dwCreationFlags - &thread_id); - assert(handler_thread_ != NULL); - } - - dbghelp_module_ = LoadLibrary(L"dbghelp.dll"); - if (dbghelp_module_) { - minidump_write_dump_ = reinterpret_cast( - GetProcAddress(dbghelp_module_, "MiniDumpWriteDump")); - } - - // Load this library dynamically to not affect existing projects. Most - // projects don't link against this directly, it's usually dynamically - // loaded by dependent code. - rpcrt4_module_ = LoadLibrary(L"rpcrt4.dll"); - if (rpcrt4_module_) { - uuid_create_ = reinterpret_cast( - GetProcAddress(rpcrt4_module_, "UuidCreate")); - } - - // set_dump_path calls UpdateNextID. This sets up all of the path and id - // strings, and their equivalent c_str pointers. - set_dump_path(dump_path); - } - - // Reserve one element for the instruction memory - AppMemory instruction_memory; - instruction_memory.ptr = NULL; - instruction_memory.length = 0; - app_memory_info_.push_back(instruction_memory); - - // There is a race condition here. If the first instance has not yet - // initialized the critical section, the second (and later) instances may - // try to use uninitialized critical section object. The feature of multiple - // instances in one module is not used much, so leave it as is for now. - // One way to solve this in the current design (that is, keeping the static - // handler stack) is to use spin locks with volatile bools to synchronize - // the handler stack. This works only if the compiler guarantees to generate - // cache coherent code for volatile. - // TODO(munjal): Fix this in a better way by changing the design if possible. - - // Lazy initialization of the handler_stack_critical_section_ - if (instance_count == 1) { - InitializeCriticalSection(&handler_stack_critical_section_); - } - - if (handler_types != HANDLER_NONE) { - EnterCriticalSection(&handler_stack_critical_section_); - - // The first time an ExceptionHandler that installs a handler is - // created, set up the handler stack. - if (!handler_stack_) { - handler_stack_ = new vector(); - } - handler_stack_->push_back(this); - - if (handler_types & HANDLER_EXCEPTION) - previous_filter_ = SetUnhandledExceptionFilter(HandleException); - -#if _MSC_VER >= 1400 // MSVC 2005/8 - if (handler_types & HANDLER_INVALID_PARAMETER) - previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter); -#endif // _MSC_VER >= 1400 - - if (handler_types & HANDLER_PURECALL) - previous_pch_ = _set_purecall_handler(HandlePureVirtualCall); - - LeaveCriticalSection(&handler_stack_critical_section_); - } -} - -ExceptionHandler::~ExceptionHandler() { - if (dbghelp_module_) { - FreeLibrary(dbghelp_module_); - } - - if (rpcrt4_module_) { - FreeLibrary(rpcrt4_module_); - } - - if (handler_types_ != HANDLER_NONE) { - EnterCriticalSection(&handler_stack_critical_section_); - - if (handler_types_ & HANDLER_EXCEPTION) - SetUnhandledExceptionFilter(previous_filter_); - -#if _MSC_VER >= 1400 // MSVC 2005/8 - if (handler_types_ & HANDLER_INVALID_PARAMETER) - _set_invalid_parameter_handler(previous_iph_); -#endif // _MSC_VER >= 1400 - - if (handler_types_ & HANDLER_PURECALL) - _set_purecall_handler(previous_pch_); - - if (handler_stack_->back() == this) { - handler_stack_->pop_back(); - } else { - // TODO(mmentovai): use advapi32!ReportEvent to log the warning to the - // system's application event log. - fprintf(stderr, "warning: removing Breakpad handler out of order\n"); - vector::iterator iterator = handler_stack_->begin(); - while (iterator != handler_stack_->end()) { - if (*iterator == this) { - iterator = handler_stack_->erase(iterator); - } else { - ++iterator; - } - } - } - - if (handler_stack_->empty()) { - // When destroying the last ExceptionHandler that installed a handler, - // clean up the handler stack. - delete handler_stack_; - handler_stack_ = NULL; - } - - LeaveCriticalSection(&handler_stack_critical_section_); - } - - // Some of the objects were only initialized if out of process - // registration was not done. - if (!IsOutOfProcess()) { -#ifdef BREAKPAD_NO_TERMINATE_THREAD - // Clean up the handler thread and synchronization primitives. The handler - // thread is either waiting on the semaphore to handle a crash or it is - // handling a crash. Coming out of the wait is fast but wait more in the - // eventuality a crash is handled. This compilation option results in a - // deadlock if the exception handler is destroyed while executing code - // inside DllMain. - is_shutdown_ = true; - ReleaseSemaphore(handler_start_semaphore_, 1, NULL); - const int kWaitForHandlerThreadMs = 60000; - WaitForSingleObject(handler_thread_, kWaitForHandlerThreadMs); -#else - TerminateThread(handler_thread_, 1); -#endif // BREAKPAD_NO_TERMINATE_THREAD - - CloseHandle(handler_thread_); - handler_thread_ = NULL; - DeleteCriticalSection(&handler_critical_section_); - CloseHandle(handler_start_semaphore_); - CloseHandle(handler_finish_semaphore_); - } - - // There is a race condition in the code below: if this instance is - // deleting the static critical section and a new instance of the class - // is created, then there is a possibility that the critical section be - // initialized while the same critical section is being deleted. Given the - // usage pattern for the code, this race condition is unlikely to hit, but it - // is a race condition nonetheless. - if (InterlockedDecrement(&instance_count_) == 0) { - DeleteCriticalSection(&handler_stack_critical_section_); - } -} - -bool ExceptionHandler::RequestUpload(DWORD crash_id) { - return crash_generation_client_->RequestUpload(crash_id); -} - -// static -DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) { - ExceptionHandler* self = reinterpret_cast(lpParameter); - assert(self); - assert(self->handler_start_semaphore_ != NULL); - assert(self->handler_finish_semaphore_ != NULL); - - while (true) { - if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) == - WAIT_OBJECT_0) { - // Perform the requested action. - if (self->is_shutdown_) { - // The instance of the exception handler is being destroyed. - break; - } else { - self->handler_return_value_ = - self->WriteMinidumpWithException(self->requesting_thread_id_, - self->exception_info_, - self->assertion_); - } - - // Allow the requesting thread to proceed. - ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL); - } - } - - // This statement is not reached when the thread is unconditionally - // terminated by the ExceptionHandler destructor. - return 0; -} - -// HandleException and HandleInvalidParameter must create an -// AutoExceptionHandler object to maintain static state and to determine which -// ExceptionHandler instance to use. The constructor locates the correct -// instance, and makes it available through get_handler(). The destructor -// restores the state in effect prior to allocating the AutoExceptionHandler. -class AutoExceptionHandler { - public: - AutoExceptionHandler() { - // Increment handler_stack_index_ so that if another Breakpad handler is - // registered using this same HandleException function, and it needs to be - // called while this handler is running (either because this handler - // declines to handle the exception, or an exception occurs during - // handling), HandleException will find the appropriate ExceptionHandler - // object in handler_stack_ to deliver the exception to. - // - // Because handler_stack_ is addressed in reverse (as |size - index|), - // preincrementing handler_stack_index_ avoids needing to subtract 1 from - // the argument to |at|. - // - // The index is maintained instead of popping elements off of the handler - // stack and pushing them at the end of this method. This avoids ruining - // the order of elements in the stack in the event that some other thread - // decides to manipulate the handler stack (such as creating a new - // ExceptionHandler object) while an exception is being handled. - EnterCriticalSection(&ExceptionHandler::handler_stack_critical_section_); - handler_ = ExceptionHandler::handler_stack_->at( - ExceptionHandler::handler_stack_->size() - - ++ExceptionHandler::handler_stack_index_); - - // In case another exception occurs while this handler is doing its thing, - // it should be delivered to the previous filter. - SetUnhandledExceptionFilter(handler_->previous_filter_); -#if _MSC_VER >= 1400 // MSVC 2005/8 - _set_invalid_parameter_handler(handler_->previous_iph_); -#endif // _MSC_VER >= 1400 - _set_purecall_handler(handler_->previous_pch_); - } - - ~AutoExceptionHandler() { - // Put things back the way they were before entering this handler. - SetUnhandledExceptionFilter(ExceptionHandler::HandleException); -#if _MSC_VER >= 1400 // MSVC 2005/8 - _set_invalid_parameter_handler(ExceptionHandler::HandleInvalidParameter); -#endif // _MSC_VER >= 1400 - _set_purecall_handler(ExceptionHandler::HandlePureVirtualCall); - - --ExceptionHandler::handler_stack_index_; - LeaveCriticalSection(&ExceptionHandler::handler_stack_critical_section_); - } - - ExceptionHandler* get_handler() const { return handler_; } - - private: - ExceptionHandler* handler_; -}; - -// static -LONG ExceptionHandler::HandleException(EXCEPTION_POINTERS* exinfo) { - AutoExceptionHandler auto_exception_handler; - ExceptionHandler* current_handler = auto_exception_handler.get_handler(); - - // Ignore EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP exceptions. This - // logic will short-circuit before calling WriteMinidumpOnHandlerThread, - // allowing something else to handle the breakpoint without incurring the - // overhead transitioning to and from the handler thread. This behavior - // can be overridden by calling ExceptionHandler::set_handle_debug_exceptions. - DWORD code = exinfo->ExceptionRecord->ExceptionCode; - LONG action; - bool is_debug_exception = (code == EXCEPTION_BREAKPOINT) || - (code == EXCEPTION_SINGLE_STEP); - - if (code == EXCEPTION_INVALID_HANDLE && - current_handler->consume_invalid_handle_exceptions_) { - return EXCEPTION_CONTINUE_EXECUTION; - } - - bool success = false; - - if (!is_debug_exception || - current_handler->get_handle_debug_exceptions()) { - // If out-of-proc crash handler client is available, we have to use that - // to generate dump and we cannot fall back on in-proc dump generation - // because we never prepared for an in-proc dump generation - - // In case of out-of-process dump generation, directly call - // WriteMinidumpWithException since there is no separate thread running. - if (current_handler->IsOutOfProcess()) { - success = current_handler->WriteMinidumpWithException( - GetCurrentThreadId(), - exinfo, - NULL); - } else { - success = current_handler->WriteMinidumpOnHandlerThread(exinfo, NULL); - } - } - - // The handler fully handled the exception. Returning - // EXCEPTION_EXECUTE_HANDLER indicates this to the system, and usually - // results in the application being terminated. - // - // Note: If the application was launched from within the Cygwin - // environment, returning EXCEPTION_EXECUTE_HANDLER seems to cause the - // application to be restarted. - if (success) { - action = EXCEPTION_EXECUTE_HANDLER; - } else { - // There was an exception, it was a breakpoint or something else ignored - // above, or it was passed to the handler, which decided not to handle it. - // This could be because the filter callback didn't want it, because - // minidump writing failed for some reason, or because the post-minidump - // callback function indicated failure. Give the previous handler a - // chance to do something with the exception. If there is no previous - // handler, return EXCEPTION_CONTINUE_SEARCH, which will allow a debugger - // or native "crashed" dialog to handle the exception. - if (current_handler->previous_filter_) { - action = current_handler->previous_filter_(exinfo); - } else { - action = EXCEPTION_CONTINUE_SEARCH; - } - } - - return action; -} - -#if _MSC_VER >= 1400 // MSVC 2005/8 -// static -void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression, - const wchar_t* function, - const wchar_t* file, - unsigned int line, - uintptr_t reserved) { - // This is an invalid parameter, not an exception. It's safe to play with - // sprintf here. - AutoExceptionHandler auto_exception_handler; - ExceptionHandler* current_handler = auto_exception_handler.get_handler(); - - MDRawAssertionInfo assertion; - memset(&assertion, 0, sizeof(assertion)); - _snwprintf_s(reinterpret_cast(assertion.expression), - sizeof(assertion.expression) / sizeof(assertion.expression[0]), - _TRUNCATE, L"%s", expression); - _snwprintf_s(reinterpret_cast(assertion.function), - sizeof(assertion.function) / sizeof(assertion.function[0]), - _TRUNCATE, L"%s", function); - _snwprintf_s(reinterpret_cast(assertion.file), - sizeof(assertion.file) / sizeof(assertion.file[0]), - _TRUNCATE, L"%s", file); - assertion.line = line; - assertion.type = MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER; - - // Make up an exception record for the current thread and CPU context - // to make it possible for the crash processor to classify these - // as do regular crashes, and to make it humane for developers to - // analyze them. - EXCEPTION_RECORD exception_record = {}; - CONTEXT exception_context = {}; - EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; - - ::RtlCaptureContext(&exception_context); - - exception_record.ExceptionCode = STATUS_INVALID_PARAMETER; - - // We store pointers to the the expression and function strings, - // and the line as exception parameters to make them easy to - // access by the developer on the far side. - exception_record.NumberParameters = 3; - exception_record.ExceptionInformation[0] = - reinterpret_cast(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&assertion.file); - exception_record.ExceptionInformation[2] = assertion.line; - - bool success = false; - // In case of out-of-process dump generation, directly call - // WriteMinidumpWithException since there is no separate thread running. - if (current_handler->IsOutOfProcess()) { - success = current_handler->WriteMinidumpWithException( - GetCurrentThreadId(), - &exception_ptrs, - &assertion); - } else { - success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, - &assertion); - } - - if (!success) { - if (current_handler->previous_iph_) { - // The handler didn't fully handle the exception. Give it to the - // previous invalid parameter handler. - current_handler->previous_iph_(expression, - function, - file, - line, - reserved); - } else { - // If there's no previous handler, pass the exception back in to the - // invalid parameter handler's core. That's the routine that called this - // function, but now, since this function is no longer registered (and in - // fact, no function at all is registered), this will result in the - // default code path being taken: _CRT_DEBUGGER_HOOK and _invoke_watson. - // Use _invalid_parameter where it exists (in _DEBUG builds) as it passes - // more information through. In non-debug builds, it is not available, - // so fall back to using _invalid_parameter_noinfo. See invarg.c in the - // CRT source. -#ifdef _DEBUG - _invalid_parameter(expression, function, file, line, reserved); -#else // _DEBUG - _invalid_parameter_noinfo(); -#endif // _DEBUG - } - } - - // The handler either took care of the invalid parameter problem itself, - // or passed it on to another handler. "Swallow" it by exiting, paralleling - // the behavior of "swallowing" exceptions. - exit(0); -} -#endif // _MSC_VER >= 1400 - -// static -void ExceptionHandler::HandlePureVirtualCall() { - // This is an pure virtual function call, not an exception. It's safe to - // play with sprintf here. - AutoExceptionHandler auto_exception_handler; - ExceptionHandler* current_handler = auto_exception_handler.get_handler(); - - MDRawAssertionInfo assertion; - memset(&assertion, 0, sizeof(assertion)); - assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL; - - // Make up an exception record for the current thread and CPU context - // to make it possible for the crash processor to classify these - // as do regular crashes, and to make it humane for developers to - // analyze them. - EXCEPTION_RECORD exception_record = {}; - CONTEXT exception_context = {}; - EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; - - ::RtlCaptureContext(&exception_context); - - exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - - // We store pointers to the the expression and function strings, - // and the line as exception parameters to make them easy to - // access by the developer on the far side. - exception_record.NumberParameters = 3; - exception_record.ExceptionInformation[0] = - reinterpret_cast(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&assertion.file); - exception_record.ExceptionInformation[2] = assertion.line; - - bool success = false; - // In case of out-of-process dump generation, directly call - // WriteMinidumpWithException since there is no separate thread running. - - if (current_handler->IsOutOfProcess()) { - success = current_handler->WriteMinidumpWithException( - GetCurrentThreadId(), - &exception_ptrs, - &assertion); - } else { - success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, - &assertion); - } - - if (!success) { - if (current_handler->previous_pch_) { - // The handler didn't fully handle the exception. Give it to the - // previous purecall handler. - current_handler->previous_pch_(); - } else { - // If there's no previous handler, return and let _purecall handle it. - // This will just put up an assertion dialog. - return; - } - } - - // The handler either took care of the invalid parameter problem itself, - // or passed it on to another handler. "Swallow" it by exiting, paralleling - // the behavior of "swallowing" exceptions. - exit(0); -} - -bool ExceptionHandler::WriteMinidumpOnHandlerThread( - EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) { - EnterCriticalSection(&handler_critical_section_); - - // There isn't much we can do if the handler thread - // was not successfully created. - if (handler_thread_ == NULL) { - LeaveCriticalSection(&handler_critical_section_); - return false; - } - - // The handler thread should only be created when the semaphores are valid. - assert(handler_start_semaphore_ != NULL); - assert(handler_finish_semaphore_ != NULL); - - // Set up data to be passed in to the handler thread. - requesting_thread_id_ = GetCurrentThreadId(); - exception_info_ = exinfo; - assertion_ = assertion; - - // This causes the handler thread to call WriteMinidumpWithException. - ReleaseSemaphore(handler_start_semaphore_, 1, NULL); - - // Wait until WriteMinidumpWithException is done and collect its return value. - WaitForSingleObject(handler_finish_semaphore_, INFINITE); - bool status = handler_return_value_; - - // Clean up. - requesting_thread_id_ = 0; - exception_info_ = NULL; - assertion_ = NULL; - - LeaveCriticalSection(&handler_critical_section_); - - return status; -} - -bool ExceptionHandler::WriteMinidump() { - // Make up an exception record for the current thread and CPU context - // to make it possible for the crash processor to classify these - // as do regular crashes, and to make it humane for developers to - // analyze them. - EXCEPTION_RECORD exception_record = {}; - CONTEXT exception_context = {}; - EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; - - ::RtlCaptureContext(&exception_context); - exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - - return WriteMinidumpForException(&exception_ptrs); -} - -bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) { - // In case of out-of-process dump generation, directly call - // WriteMinidumpWithException since there is no separate thread running. - if (IsOutOfProcess()) { - return WriteMinidumpWithException(GetCurrentThreadId(), - exinfo, - NULL); - } - - bool success = WriteMinidumpOnHandlerThread(exinfo, NULL); - UpdateNextID(); - return success; -} - -// static -bool ExceptionHandler::WriteMinidump(const wstring &dump_path, - MinidumpCallback callback, - void* callback_context, - MINIDUMP_TYPE dump_type) { - ExceptionHandler handler(dump_path, NULL, callback, callback_context, - HANDLER_NONE, dump_type, (HANDLE)NULL, NULL); - return handler.WriteMinidump(); -} - -// static -bool ExceptionHandler::WriteMinidumpForChild(HANDLE child, - DWORD child_blamed_thread, - const wstring& dump_path, - MinidumpCallback callback, - void* callback_context, - MINIDUMP_TYPE dump_type) { - EXCEPTION_RECORD ex; - CONTEXT ctx; - EXCEPTION_POINTERS exinfo = { NULL, NULL }; - // As documented on MSDN, on failure SuspendThread returns (DWORD) -1 - const DWORD kFailedToSuspendThread = static_cast(-1); - DWORD last_suspend_count = kFailedToSuspendThread; - HANDLE child_thread_handle = OpenThread(THREAD_GET_CONTEXT | - THREAD_QUERY_INFORMATION | - THREAD_SUSPEND_RESUME, - FALSE, - child_blamed_thread); - // This thread may have died already, so not opening the handle is a - // non-fatal error. - if (child_thread_handle != NULL) { - last_suspend_count = SuspendThread(child_thread_handle); - if (last_suspend_count != kFailedToSuspendThread) { - ctx.ContextFlags = CONTEXT_ALL; - if (GetThreadContext(child_thread_handle, &ctx)) { - memset(&ex, 0, sizeof(ex)); - ex.ExceptionCode = EXCEPTION_BREAKPOINT; -#if defined(_M_IX86) - ex.ExceptionAddress = reinterpret_cast(ctx.Eip); -#elif defined(_M_X64) - ex.ExceptionAddress = reinterpret_cast(ctx.Rip); -#endif - exinfo.ExceptionRecord = &ex; - exinfo.ContextRecord = &ctx; - } - } - } - - ExceptionHandler handler(dump_path, NULL, callback, callback_context, - HANDLER_NONE, dump_type, (HANDLE)NULL, NULL); - bool success = handler.WriteMinidumpWithExceptionForProcess( - child_blamed_thread, - exinfo.ExceptionRecord ? &exinfo : NULL, - NULL, child, false); - - if (last_suspend_count != kFailedToSuspendThread) { - ResumeThread(child_thread_handle); - } - - CloseHandle(child_thread_handle); - - if (callback) { - success = callback(handler.dump_path_c_, handler.next_minidump_id_c_, - callback_context, NULL, NULL, success); - } - - return success; -} - -bool ExceptionHandler::WriteMinidumpWithException( - DWORD requesting_thread_id, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion) { - // Give user code a chance to approve or prevent writing a minidump. If the - // filter returns false, don't handle the exception at all. If this method - // was called as a result of an exception, returning false will cause - // HandleException to call any previous handler or return - // EXCEPTION_CONTINUE_SEARCH on the exception thread, allowing it to appear - // as though this handler were not present at all. - if (filter_ && !filter_(callback_context_, exinfo, assertion)) { - return false; - } - - bool success = false; - if (IsOutOfProcess()) { - success = crash_generation_client_->RequestDump(exinfo, assertion); - } else { - success = WriteMinidumpWithExceptionForProcess(requesting_thread_id, - exinfo, - assertion, - GetCurrentProcess(), - true); - } - - if (callback_) { - // TODO(munjal): In case of out-of-process dump generation, both - // dump_path_c_ and next_minidump_id_ will be NULL. For out-of-process - // scenario, the server process ends up creating the dump path and dump - // id so they are not known to the client. - success = callback_(dump_path_c_, next_minidump_id_c_, callback_context_, - exinfo, assertion, success); - } - - return success; -} - -// static -BOOL CALLBACK ExceptionHandler::MinidumpWriteDumpCallback( - PVOID context, - const PMINIDUMP_CALLBACK_INPUT callback_input, - PMINIDUMP_CALLBACK_OUTPUT callback_output) { - switch (callback_input->CallbackType) { - case MemoryCallback: { - MinidumpCallbackContext* callback_context = - reinterpret_cast(context); - if (callback_context->iter == callback_context->end) - return FALSE; - - // Include the specified memory region. - callback_output->MemoryBase = callback_context->iter->ptr; - callback_output->MemorySize = callback_context->iter->length; - callback_context->iter++; - return TRUE; - } - - // Include all modules. - case IncludeModuleCallback: - case ModuleCallback: - return TRUE; - - // Include all threads. - case IncludeThreadCallback: - case ThreadCallback: - return TRUE; - - // Stop receiving cancel callbacks. - case CancelCallback: - callback_output->CheckCancel = FALSE; - callback_output->Cancel = FALSE; - return TRUE; - } - // Ignore other callback types. - return FALSE; -} - -bool ExceptionHandler::WriteMinidumpWithExceptionForProcess( - DWORD requesting_thread_id, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - HANDLE process, - bool write_requester_stream) { - bool success = false; - if (minidump_write_dump_) { - HANDLE dump_file = CreateFile(next_minidump_path_c_, - GENERIC_WRITE, - 0, // no sharing - NULL, - CREATE_NEW, // fail if exists - FILE_ATTRIBUTE_NORMAL, - NULL); - if (dump_file != INVALID_HANDLE_VALUE) { - MINIDUMP_EXCEPTION_INFORMATION except_info; - except_info.ThreadId = requesting_thread_id; - except_info.ExceptionPointers = exinfo; - except_info.ClientPointers = FALSE; - - // Leave room in user_stream_array for possible breakpad and - // assertion info streams. - MINIDUMP_USER_STREAM user_stream_array[2]; - MINIDUMP_USER_STREAM_INFORMATION user_streams; - user_streams.UserStreamCount = 0; - user_streams.UserStreamArray = user_stream_array; - - if (write_requester_stream) { - // Add an MDRawBreakpadInfo stream to the minidump, to provide - // additional information about the exception handler to the Breakpad - // processor. The information will help the processor determine which - // threads are relevant. The Breakpad processor does not require this - // information but can function better with Breakpad-generated dumps - // when it is present. The native debugger is not harmed by the - // presence of this information. - MDRawBreakpadInfo breakpad_info; - breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; - breakpad_info.dump_thread_id = GetCurrentThreadId(); - breakpad_info.requesting_thread_id = requesting_thread_id; - - int index = user_streams.UserStreamCount; - user_stream_array[index].Type = MD_BREAKPAD_INFO_STREAM; - user_stream_array[index].BufferSize = sizeof(breakpad_info); - user_stream_array[index].Buffer = &breakpad_info; - ++user_streams.UserStreamCount; - } - - if (assertion) { - int index = user_streams.UserStreamCount; - user_stream_array[index].Type = MD_ASSERTION_INFO_STREAM; - user_stream_array[index].BufferSize = sizeof(MDRawAssertionInfo); - user_stream_array[index].Buffer = assertion; - ++user_streams.UserStreamCount; - } - - // Older versions of DbgHelp.dll don't correctly put the memory around - // the faulting instruction pointer into the minidump. This - // callback will ensure that it gets included. - if (exinfo) { - // Find a memory region of 256 bytes centered on the - // faulting instruction pointer. - const ULONG64 instruction_pointer = -#if defined(_M_IX86) - exinfo->ContextRecord->Eip; -#elif defined(_M_AMD64) - exinfo->ContextRecord->Rip; -#else -#error Unsupported platform -#endif - - MEMORY_BASIC_INFORMATION info; - if (VirtualQueryEx(process, - reinterpret_cast(instruction_pointer), - &info, - sizeof(MEMORY_BASIC_INFORMATION)) != 0 && - info.State == MEM_COMMIT) { - // Attempt to get 128 bytes before and after the instruction - // pointer, but settle for whatever's available up to the - // boundaries of the memory region. - const ULONG64 kIPMemorySize = 256; - ULONG64 base = - (std::max)(reinterpret_cast(info.BaseAddress), - instruction_pointer - (kIPMemorySize / 2)); - ULONG64 end_of_range = - (std::min)(instruction_pointer + (kIPMemorySize / 2), - reinterpret_cast(info.BaseAddress) - + info.RegionSize); - ULONG size = static_cast(end_of_range - base); - - AppMemory& elt = app_memory_info_.front(); - elt.ptr = base; - elt.length = size; - } - } - - MinidumpCallbackContext context; - context.iter = app_memory_info_.begin(); - context.end = app_memory_info_.end(); - - // Skip the reserved element if there was no instruction memory - if (context.iter->ptr == 0) { - context.iter++; - } - - MINIDUMP_CALLBACK_INFORMATION callback; - callback.CallbackRoutine = MinidumpWriteDumpCallback; - callback.CallbackParam = reinterpret_cast(&context); - - // The explicit comparison to TRUE avoids a warning (C4800). - success = (minidump_write_dump_(process, - GetProcessId(process), - dump_file, - dump_type_, - exinfo ? &except_info : NULL, - &user_streams, - &callback) == TRUE); - - CloseHandle(dump_file); - } - } - - return success; -} - -void ExceptionHandler::UpdateNextID() { - assert(uuid_create_); - UUID id = {0}; - if (uuid_create_) { - uuid_create_(&id); - } - next_minidump_id_ = GUIDString::GUIDToWString(&id); - next_minidump_id_c_ = next_minidump_id_.c_str(); - - wchar_t minidump_path[MAX_PATH]; - swprintf(minidump_path, MAX_PATH, L"%s\\%s.dmp", - dump_path_c_, next_minidump_id_c_); - - // remove when VC++7.1 is no longer supported - minidump_path[MAX_PATH - 1] = L'\0'; - - next_minidump_path_ = minidump_path; - next_minidump_path_c_ = next_minidump_path_.c_str(); -} - -void ExceptionHandler::RegisterAppMemory(void* ptr, size_t length) { - AppMemoryList::iterator iter = - std::find(app_memory_info_.begin(), app_memory_info_.end(), ptr); - if (iter != app_memory_info_.end()) { - // Don't allow registering the same pointer twice. - return; - } - - AppMemory app_memory; - app_memory.ptr = reinterpret_cast(ptr); - app_memory.length = static_cast(length); - app_memory_info_.push_back(app_memory); -} - -void ExceptionHandler::UnregisterAppMemory(void* ptr) { - AppMemoryList::iterator iter = - std::find(app_memory_info_.begin(), app_memory_info_.end(), ptr); - if (iter != app_memory_info_.end()) { - app_memory_info_.erase(iter); - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.gyp deleted file mode 100644 index c5733277d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.gyp +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'exception_handler', - 'type': 'static_library', - 'sources': [ - "exception_handler.cc", - "exception_handler.h", - ], - 'dependencies': [ - '../breakpad_client.gyp:common', - '../crash_generation/crash_generation.gyp:crash_generation_server', - ] - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.h b/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.h deleted file mode 100644 index 11babe513..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/exception_handler.h +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ExceptionHandler can write a minidump file when an exception occurs, -// or when WriteMinidump() is called explicitly by your program. -// -// To have the exception handler write minidumps when an uncaught exception -// (crash) occurs, you should create an instance early in the execution -// of your program, and keep it around for the entire time you want to -// have crash handling active (typically, until shutdown). -// -// If you want to write minidumps without installing the exception handler, -// you can create an ExceptionHandler with install_handler set to false, -// then call WriteMinidump. You can also use this technique if you want to -// use different minidump callbacks for different call sites. -// -// In either case, a callback function is called when a minidump is written, -// which receives the unqiue id of the minidump. The caller can use this -// id to collect and write additional application state, and to launch an -// external crash-reporting application. -// -// It is important that creation and destruction of ExceptionHandler objects -// be nested cleanly, when using install_handler = true. -// Avoid the following pattern: -// ExceptionHandler *e = new ExceptionHandler(...); -// ExceptionHandler *f = new ExceptionHandler(...); -// delete e; -// This will put the exception filter stack into an inconsistent state. - -#ifndef CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__ -#define CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__ - -#include -#include -#include -#include - -#pragma warning(push) -// Disable exception handler warnings. -#pragma warning(disable:4530) - -#include -#include -#include - -#include "client/windows/common/ipc_protocol.h" -#include "client/windows/crash_generation/crash_generation_client.h" -#include "common/scoped_ptr.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -using std::vector; -using std::wstring; - -// These entries store a list of memory regions that the client wants included -// in the minidump. -struct AppMemory { - ULONG64 ptr; - ULONG length; - - bool operator==(const struct AppMemory& other) const { - return ptr == other.ptr; - } - - bool operator==(const void* other) const { - return ptr == reinterpret_cast(other); - } -}; -typedef std::list AppMemoryList; - -class ExceptionHandler { - public: - // A callback function to run before Breakpad performs any substantial - // processing of an exception. A FilterCallback is called before writing - // a minidump. context is the parameter supplied by the user as - // callback_context when the handler was created. exinfo points to the - // exception record, if any; assertion points to assertion information, - // if any. - // - // If a FilterCallback returns true, Breakpad will continue processing, - // attempting to write a minidump. If a FilterCallback returns false, - // Breakpad will immediately report the exception as unhandled without - // writing a minidump, allowing another handler the opportunity to handle it. - typedef bool (*FilterCallback)(void* context, EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion); - - // A callback function to run after the minidump has been written. - // minidump_id is a unique id for the dump, so the minidump - // file is \.dmp. context is the parameter supplied - // by the user as callback_context when the handler was created. exinfo - // points to the exception record, or NULL if no exception occurred. - // succeeded indicates whether a minidump file was successfully written. - // assertion points to information about an assertion if the handler was - // invoked by an assertion. - // - // If an exception occurred and the callback returns true, Breakpad will treat - // the exception as fully-handled, suppressing any other handlers from being - // notified of the exception. If the callback returns false, Breakpad will - // treat the exception as unhandled, and allow another handler to handle it. - // If there are no other handlers, Breakpad will report the exception to the - // system as unhandled, allowing a debugger or native crash dialog the - // opportunity to handle the exception. Most callback implementations - // should normally return the value of |succeeded|, or when they wish to - // not report an exception of handled, false. Callbacks will rarely want to - // return true directly (unless |succeeded| is true). - // - // For out-of-process dump generation, dump path and minidump ID will always - // be NULL. In case of out-of-process dump generation, the dump path and - // minidump id are controlled by the server process and are not communicated - // back to the crashing process. - typedef bool (*MinidumpCallback)(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded); - - // HandlerType specifies which types of handlers should be installed, if - // any. Use HANDLER_NONE for an ExceptionHandler that remains idle, - // without catching any failures on its own. This type of handler may - // still be triggered by calling WriteMinidump. Otherwise, use a - // combination of the other HANDLER_ values, or HANDLER_ALL to install - // all handlers. - enum HandlerType { - HANDLER_NONE = 0, - HANDLER_EXCEPTION = 1 << 0, // SetUnhandledExceptionFilter - HANDLER_INVALID_PARAMETER = 1 << 1, // _set_invalid_parameter_handler - HANDLER_PURECALL = 1 << 2, // _set_purecall_handler - HANDLER_ALL = HANDLER_EXCEPTION | - HANDLER_INVALID_PARAMETER | - HANDLER_PURECALL - }; - - // Creates a new ExceptionHandler instance to handle writing minidumps. - // Before writing a minidump, the optional filter callback will be called. - // Its return value determines whether or not Breakpad should write a - // minidump. Minidump files will be written to dump_path, and the optional - // callback is called after writing the dump file, as described above. - // handler_types specifies the types of handlers that should be installed. - ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types); - - // Creates a new ExceptionHandler instance that can attempt to perform - // out-of-process dump generation if pipe_name is not NULL. If pipe_name is - // NULL, or if out-of-process dump generation registration step fails, - // in-process dump generation will be used. This also allows specifying - // the dump type to generate. - ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - const wchar_t* pipe_name, - const CustomClientInfo* custom_info); - - // As above, creates a new ExceptionHandler instance to perform - // out-of-process dump generation if the given pipe_handle is not NULL. - ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - HANDLE pipe_handle, - const CustomClientInfo* custom_info); - - // ExceptionHandler that ENSURES out-of-process dump generation. Expects a - // crash generation client that is already registered with a crash generation - // server. Takes ownership of the passed-in crash_generation_client. - // - // Usage example: - // crash_generation_client = new CrashGenerationClient(..); - // if (crash_generation_client->Register()) { - // // Registration with the crash generation server succeeded. - // // Out-of-process dump generation is guaranteed. - // g_handler = new ExceptionHandler(.., crash_generation_client, ..); - // return true; - // } - ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - CrashGenerationClient* crash_generation_client); - - ~ExceptionHandler(); - - // Get and set the minidump path. - wstring dump_path() const { return dump_path_; } - void set_dump_path(const wstring &dump_path) { - dump_path_ = dump_path; - dump_path_c_ = dump_path_.c_str(); - UpdateNextID(); // Necessary to put dump_path_ in next_minidump_path_. - } - - // Requests that a previously reported crash be uploaded. - bool RequestUpload(DWORD crash_id); - - // Writes a minidump immediately. This can be used to capture the - // execution state independently of a crash. Returns true on success. - bool WriteMinidump(); - - // Writes a minidump immediately, with the user-supplied exception - // information. - bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo); - - // Convenience form of WriteMinidump which does not require an - // ExceptionHandler instance. - static bool WriteMinidump(const wstring &dump_path, - MinidumpCallback callback, void* callback_context, - MINIDUMP_TYPE dump_type = MiniDumpNormal); - - // Write a minidump of |child| immediately. This can be used to - // capture the execution state of |child| independently of a crash. - // Pass a meaningful |child_blamed_thread| to make that thread in - // the child process the one from which a crash signature is - // extracted. - static bool WriteMinidumpForChild(HANDLE child, - DWORD child_blamed_thread, - const wstring& dump_path, - MinidumpCallback callback, - void* callback_context, - MINIDUMP_TYPE dump_type = MiniDumpNormal); - - // Get the thread ID of the thread requesting the dump (either the exception - // thread or any other thread that called WriteMinidump directly). This - // may be useful if you want to include additional thread state in your - // dumps. - DWORD get_requesting_thread_id() const { return requesting_thread_id_; } - - // Controls behavior of EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP. - bool get_handle_debug_exceptions() const { return handle_debug_exceptions_; } - void set_handle_debug_exceptions(bool handle_debug_exceptions) { - handle_debug_exceptions_ = handle_debug_exceptions; - } - - // Controls behavior of EXCEPTION_INVALID_HANDLE. - bool get_consume_invalid_handle_exceptions() const { - return consume_invalid_handle_exceptions_; - } - void set_consume_invalid_handle_exceptions( - bool consume_invalid_handle_exceptions) { - consume_invalid_handle_exceptions_ = consume_invalid_handle_exceptions; - } - - // Returns whether out-of-process dump generation is used or not. - bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; } - - // Calling RegisterAppMemory(p, len) causes len bytes starting - // at address p to be copied to the minidump when a crash happens. - void RegisterAppMemory(void* ptr, size_t length); - void UnregisterAppMemory(void* ptr); - - private: - friend class AutoExceptionHandler; - - // Initializes the instance with given values. - void Initialize(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - const wchar_t* pipe_name, - HANDLE pipe_handle, - CrashGenerationClient* crash_generation_client, - const CustomClientInfo* custom_info); - - // Function pointer type for MiniDumpWriteDump, which is looked up - // dynamically. - typedef BOOL (WINAPI *MiniDumpWriteDump_type)( - HANDLE hProcess, - DWORD dwPid, - HANDLE hFile, - MINIDUMP_TYPE DumpType, - CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); - - // Function pointer type for UuidCreate, which is looked up dynamically. - typedef RPC_STATUS (RPC_ENTRY *UuidCreate_type)(UUID* Uuid); - - // Runs the main loop for the exception handler thread. - static DWORD WINAPI ExceptionHandlerThreadMain(void* lpParameter); - - // Called on the exception thread when an unhandled exception occurs. - // Signals the exception handler thread to handle the exception. - static LONG WINAPI HandleException(EXCEPTION_POINTERS* exinfo); - -#if _MSC_VER >= 1400 // MSVC 2005/8 - // This function will be called by some CRT functions when they detect - // that they were passed an invalid parameter. Note that in _DEBUG builds, - // the CRT may display an assertion dialog before calling this function, - // and the function will not be called unless the assertion dialog is - // dismissed by clicking "Ignore." - static void HandleInvalidParameter(const wchar_t* expression, - const wchar_t* function, - const wchar_t* file, - unsigned int line, - uintptr_t reserved); -#endif // _MSC_VER >= 1400 - - // This function will be called by the CRT when a pure virtual - // function is called. - static void HandlePureVirtualCall(); - - // This is called on the exception thread or on another thread that - // the user wishes to produce a dump from. It calls - // WriteMinidumpWithException on the handler thread, avoiding stack - // overflows and inconsistent dumps due to writing the dump from - // the exception thread. If the dump is requested as a result of an - // exception, exinfo contains exception information, otherwise, it - // is NULL. If the dump is requested as a result of an assertion - // (such as an invalid parameter being passed to a CRT function), - // assertion contains data about the assertion, otherwise, it is NULL. - bool WriteMinidumpOnHandlerThread(EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion); - - // This function is called on the handler thread. It calls into - // WriteMinidumpWithExceptionForProcess() with a handle to the - // current process. requesting_thread_id is the ID of the thread - // that requested the dump. If the dump is requested as a result of - // an exception, exinfo contains exception information, otherwise, - // it is NULL. - bool WriteMinidumpWithException(DWORD requesting_thread_id, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion); - - // This function is used as a callback when calling MinidumpWriteDump, - // in order to add additional memory regions to the dump. - static BOOL CALLBACK MinidumpWriteDumpCallback( - PVOID context, - const PMINIDUMP_CALLBACK_INPUT callback_input, - PMINIDUMP_CALLBACK_OUTPUT callback_output); - - // This function does the actual writing of a minidump. It is - // called on the handler thread. requesting_thread_id is the ID of - // the thread that requested the dump, if that information is - // meaningful. If the dump is requested as a result of an - // exception, exinfo contains exception information, otherwise, it - // is NULL. process is the one that will be dumped. If - // requesting_thread_id is meaningful and should be added to the - // minidump, write_requester_stream is |true|. - bool WriteMinidumpWithExceptionForProcess(DWORD requesting_thread_id, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - HANDLE process, - bool write_requester_stream); - - // Generates a new ID and stores it in next_minidump_id_, and stores the - // path of the next minidump to be written in next_minidump_path_. - void UpdateNextID(); - - FilterCallback filter_; - MinidumpCallback callback_; - void* callback_context_; - - scoped_ptr crash_generation_client_; - - // The directory in which a minidump will be written, set by the dump_path - // argument to the constructor, or set_dump_path. - wstring dump_path_; - - // The basename of the next minidump to be written, without the extension. - wstring next_minidump_id_; - - // The full pathname of the next minidump to be written, including the file - // extension. - wstring next_minidump_path_; - - // Pointers to C-string representations of the above. These are set when - // the above wstring versions are set in order to avoid calling c_str during - // an exception, as c_str may attempt to allocate heap memory. These - // pointers are not owned by the ExceptionHandler object, but their lifetimes - // should be equivalent to the lifetimes of the associated wstring, provided - // that the wstrings are not altered. - const wchar_t* dump_path_c_; - const wchar_t* next_minidump_id_c_; - const wchar_t* next_minidump_path_c_; - - HMODULE dbghelp_module_; - MiniDumpWriteDump_type minidump_write_dump_; - MINIDUMP_TYPE dump_type_; - - HMODULE rpcrt4_module_; - UuidCreate_type uuid_create_; - - // Tracks the handler types that were installed according to the - // handler_types constructor argument. - int handler_types_; - - // When installed_handler_ is true, previous_filter_ is the unhandled - // exception filter that was set prior to installing ExceptionHandler as - // the unhandled exception filter and pointing it to |this|. NULL indicates - // that there is no previous unhandled exception filter. - LPTOP_LEVEL_EXCEPTION_FILTER previous_filter_; - -#if _MSC_VER >= 1400 // MSVC 2005/8 - // Beginning in VC 8, the CRT provides an invalid parameter handler that will - // be called when some CRT functions are passed invalid parameters. In - // earlier CRTs, the same conditions would cause unexpected behavior or - // crashes. - _invalid_parameter_handler previous_iph_; -#endif // _MSC_VER >= 1400 - - // The CRT allows you to override the default handler for pure - // virtual function calls. - _purecall_handler previous_pch_; - - // The exception handler thread. - HANDLE handler_thread_; - - // True if the exception handler is being destroyed. - // Starting with MSVC 2005, Visual C has stronger guarantees on volatile vars. - // It has release semantics on write and acquire semantics on reads. - // See the msdn documentation. - volatile bool is_shutdown_; - - // The critical section enforcing the requirement that only one exception be - // handled by a handler at a time. - CRITICAL_SECTION handler_critical_section_; - - // Semaphores used to move exception handling between the exception thread - // and the handler thread. handler_start_semaphore_ is signalled by the - // exception thread to wake up the handler thread when an exception occurs. - // handler_finish_semaphore_ is signalled by the handler thread to wake up - // the exception thread when handling is complete. - HANDLE handler_start_semaphore_; - HANDLE handler_finish_semaphore_; - - // The next 2 fields contain data passed from the requesting thread to - // the handler thread. - - // The thread ID of the thread requesting the dump (either the exception - // thread or any other thread that called WriteMinidump directly). - DWORD requesting_thread_id_; - - // The exception info passed to the exception handler on the exception - // thread, if an exception occurred. NULL for user-requested dumps. - EXCEPTION_POINTERS* exception_info_; - - // If the handler is invoked due to an assertion, this will contain a - // pointer to the assertion information. It is NULL at other times. - MDRawAssertionInfo* assertion_; - - // The return value of the handler, passed from the handler thread back to - // the requesting thread. - bool handler_return_value_; - - // If true, the handler will intercept EXCEPTION_BREAKPOINT and - // EXCEPTION_SINGLE_STEP exceptions. Leave this false (the default) - // to not interfere with debuggers. - bool handle_debug_exceptions_; - - // If true, the handler will consume any EXCEPTION_INVALID_HANDLE exceptions. - // Leave this false (the default) to handle these exceptions as normal. - bool consume_invalid_handle_exceptions_; - - // Callers can request additional memory regions to be included in - // the dump. - AppMemoryList app_memory_info_; - - // A stack of ExceptionHandler objects that have installed unhandled - // exception filters. This vector is used by HandleException to determine - // which ExceptionHandler object to route an exception to. When an - // ExceptionHandler is created with install_handler true, it will append - // itself to this list. - static vector* handler_stack_; - - // The index of the ExceptionHandler in handler_stack_ that will handle the - // next exception. Note that 0 means the last entry in handler_stack_, 1 - // means the next-to-last entry, and so on. This is used by HandleException - // to support multiple stacked Breakpad handlers. - static LONG handler_stack_index_; - - // handler_stack_critical_section_ guards operations on handler_stack_ and - // handler_stack_index_. The critical section is initialized by the - // first instance of the class and destroyed by the last instance of it. - static CRITICAL_SECTION handler_stack_critical_section_; - - // The number of instances of this class. - static volatile LONG instance_count_; - - // disallow copy ctor and operator= - explicit ExceptionHandler(const ExceptionHandler &); - void operator=(const ExceptionHandler &); -}; - -} // namespace google_breakpad - -#pragma warning(pop) - -#endif // CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/objs.mozbuild b/toolkit/crashreporter/google-breakpad/src/client/windows/handler/objs.mozbuild deleted file mode 100644 index 6cabb09b7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/objs.mozbuild +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -lobjs_handler = [ - 'exception_handler.cc', -] - -subdir = 'toolkit/crashreporter/google-breakpad/src/client/windows/handler' -objs_handler = [ - '/%s/%s' % (subdir, s) for s in lobjs_handler -] diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.cc deleted file mode 100644 index 70c36b0e2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.cc +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Disable exception handler warnings. -#pragma warning( disable : 4530 ) - -#include - -#include "client/windows/sender/crash_report_sender.h" -#include "common/windows/http_upload.h" - -#if _MSC_VER < 1400 // MSVC 2005/8 -// Older MSVC doesn't have fscanf_s, but they are compatible as long as -// we don't use the string conversions (%s/%c/%S/%C). -#define fscanf_s fscanf -#endif - -namespace google_breakpad { - -static const char kCheckpointSignature[] = "GBP1\n"; - -CrashReportSender::CrashReportSender(const wstring &checkpoint_file) - : checkpoint_file_(checkpoint_file), - max_reports_per_day_(-1), - last_sent_date_(-1), - reports_sent_(0) { - FILE *fd; - if (OpenCheckpointFile(L"r", &fd) == 0) { - ReadCheckpoint(fd); - fclose(fd); - } -} - -ReportResult CrashReportSender::SendCrashReport( - const wstring &url, const map ¶meters, - const map &files, wstring *report_code) { - int today = GetCurrentDate(); - if (today == last_sent_date_ && - max_reports_per_day_ != -1 && - reports_sent_ >= max_reports_per_day_) { - return RESULT_THROTTLED; - } - - int http_response = 0; - bool result = HTTPUpload::SendRequest( - url, parameters, files, NULL, report_code, - &http_response); - - if (result) { - ReportSent(today); - return RESULT_SUCCEEDED; - } else if (http_response >= 400 && http_response < 500) { - return RESULT_REJECTED; - } else { - return RESULT_FAILED; - } -} - -void CrashReportSender::ReadCheckpoint(FILE *fd) { - char buf[128]; - if (!fgets(buf, sizeof(buf), fd) || - strcmp(buf, kCheckpointSignature) != 0) { - return; - } - - if (fscanf_s(fd, "%d\n", &last_sent_date_) != 1) { - last_sent_date_ = -1; - return; - } - if (fscanf_s(fd, "%d\n", &reports_sent_) != 1) { - reports_sent_ = 0; - return; - } -} - -void CrashReportSender::ReportSent(int today) { - // Update the report stats - if (today != last_sent_date_) { - last_sent_date_ = today; - reports_sent_ = 0; - } - ++reports_sent_; - - // Update the checkpoint file - FILE *fd; - if (OpenCheckpointFile(L"w", &fd) == 0) { - fputs(kCheckpointSignature, fd); - fprintf(fd, "%d\n", last_sent_date_); - fprintf(fd, "%d\n", reports_sent_); - fclose(fd); - } -} - -int CrashReportSender::GetCurrentDate() const { - SYSTEMTIME system_time; - GetSystemTime(&system_time); - return (system_time.wYear * 10000) + (system_time.wMonth * 100) + - system_time.wDay; -} - -int CrashReportSender::OpenCheckpointFile(const wchar_t *mode, FILE **fd) { - if (checkpoint_file_.empty()) { - return ENOENT; - } -#if _MSC_VER >= 1400 // MSVC 2005/8 - return _wfopen_s(fd, checkpoint_file_.c_str(), mode); -#else - *fd = _wfopen(checkpoint_file_.c_str(), mode); - if (*fd == NULL) { - return errno; - } - return 0; -#endif -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.gyp deleted file mode 100644 index dc8583a0a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.gyp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'crash_report_sender', - 'type': 'static_library', - 'sources': [ - 'crash_report_sender.cc', - 'crash_report_sender.h', - ], - 'dependencies': [ - '../breakpad_client.gyp:common' - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.h b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.h deleted file mode 100644 index 7786cc699..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/crash_report_sender.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__ -#define CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__ - -// CrashReportSender is a "static" class which provides an API to upload -// crash reports via HTTP(S). A crash report is formatted as a multipart POST -// request, which contains a set of caller-supplied string key/value pairs, -// and a minidump file to upload. -// -// To use this library in your project, you will need to link against -// wininet.lib. - -#pragma warning( push ) -// Disable exception handler warnings. -#pragma warning( disable : 4530 ) - -#include -#include - -namespace google_breakpad { - -using std::wstring; -using std::map; - -typedef enum { - RESULT_FAILED = 0, // Failed to communicate with the server; try later. - RESULT_REJECTED, // Successfully sent the crash report, but the - // server rejected it; don't resend this report. - RESULT_SUCCEEDED, // The server accepted the crash report. - RESULT_THROTTLED // No attempt was made to send the crash report, because - // we exceeded the maximum reports per day. -} ReportResult; - -class CrashReportSender { - public: - // Initializes a CrashReportSender instance. - // If checkpoint_file is non-empty, breakpad will persist crash report - // state to this file. A checkpoint file is required for - // set_max_reports_per_day() to function properly. - explicit CrashReportSender(const wstring &checkpoint_file); - ~CrashReportSender() {} - - // Sets the maximum number of crash reports that will be sent in a 24-hour - // period. This uses the state persisted to the checkpoint file. - // The default value of -1 means that there is no limit on reports sent. - void set_max_reports_per_day(int reports) { - max_reports_per_day_ = reports; - } - - int max_reports_per_day() const { return max_reports_per_day_; } - - // Sends the specified files, along with the map of - // name value pairs, as a multipart POST request to the given URL. - // Parameter names must contain only printable ASCII characters, - // and may not contain a quote (") character. - // Only HTTP(S) URLs are currently supported. The return value indicates - // the result of the operation (see above for possible results). - // If report_code is non-NULL and the report is sent successfully (that is, - // the return value is RESULT_SUCCEEDED), a code uniquely identifying the - // report will be returned in report_code. - // (Otherwise, report_code will be unchanged.) - ReportResult SendCrashReport(const wstring &url, - const map ¶meters, - const map &files, - wstring *report_code); - - private: - // Reads persistent state from a checkpoint file. - void ReadCheckpoint(FILE *fd); - - // Called when a new report has been sent, to update the checkpoint state. - void ReportSent(int today); - - // Returns today's date (UTC) formatted as YYYYMMDD. - int GetCurrentDate() const; - - // Opens the checkpoint file with the specified mode. - // Returns zero on success, or an error code on failure. - int OpenCheckpointFile(const wchar_t *mode, FILE **fd); - - wstring checkpoint_file_; - int max_reports_per_day_; - // The last date on which we sent a report, expressed as YYYYMMDD. - int last_sent_date_; - // Number of reports sent on last_sent_date_ - int reports_sent_; - - // Disallow copy constructor and operator= - explicit CrashReportSender(const CrashReportSender &); - void operator=(const CrashReportSender &); -}; - -} // namespace google_breakpad - -#pragma warning( pop ) - -#endif // CLIENT_WINDOWS_SENDER_CRASH_REPORT_SENDER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/objs.mozbuild b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/objs.mozbuild deleted file mode 100644 index 7b519328d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/objs.mozbuild +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -lobjs_sender = [ - 'crash_report_sender.cc', -] - -subdir = 'toolkit/crashreporter/google-breakpad/src/client/windows/sender' -objs_sender = [ - '/%s/%s' % (subdir, s) for s in lobjs_sender -] diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.cc deleted file mode 100644 index 32f78f2b9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/tests/crash_generation_app/abstract_class.h" - -namespace google_breakpad { - -Base::Base(Derived* derived) - : derived_(derived) { -} - -Base::~Base() { - derived_->DoSomething(); -} - -#pragma warning(push) -#pragma warning(disable:4355) -// Disable warning C4355: 'this' : used in base member initializer list. -Derived::Derived() - : Base(this) { // C4355 -} -#pragma warning(pop) - -void Derived::DoSomething() { -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.h b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.h deleted file mode 100644 index e3f2a4f37..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/abstract_class.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_ABSTRACT_CLASS_H__ -#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_ABSTRACT_CLASS_H__ - -namespace google_breakpad { - -// Dummy classes to help generate a pure call violation. - -class Derived; - -class Base { - public: - Base(Derived* derived); - virtual ~Base(); - virtual void DoSomething() = 0; - - private: - Derived* derived_; -}; - -class Derived : public Base { - public: - Derived(); - virtual void DoSomething(); -}; - -} // namespace google_breakpad - -#endif // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.cc deleted file mode 100644 index 0d837e521..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.cc +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// crash_generation_app.cpp : Defines the entry point for the application. -// - -#include "client/windows/tests/crash_generation_app/crash_generation_app.h" - -#include -#include - -#include "client/windows/crash_generation/client_info.h" -#include "client/windows/crash_generation/crash_generation_server.h" -#include "client/windows/handler/exception_handler.h" -#include "client/windows/common/ipc_protocol.h" - -#include "client/windows/tests/crash_generation_app/abstract_class.h" - -namespace google_breakpad { - -const int kMaxLoadString = 100; -const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashServices\\TestServer"; - -const DWORD kEditBoxStyles = WS_CHILD | - WS_VISIBLE | - WS_VSCROLL | - ES_LEFT | - ES_MULTILINE | - ES_AUTOVSCROLL | - ES_READONLY; - -// Maximum length of a line in the edit box. -const size_t kMaximumLineLength = 256; - -// CS to access edit control in a thread safe way. -static CRITICAL_SECTION* cs_edit = NULL; - -// Edit control. -static HWND client_status_edit_box; - -HINSTANCE current_instance; // Current instance. -TCHAR title[kMaxLoadString]; // Title bar text. -TCHAR window_class[kMaxLoadString]; // Main window class name. - -ATOM MyRegisterClass(HINSTANCE instance); -BOOL InitInstance(HINSTANCE, int); -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); - -static size_t kCustomInfoCount = 2; -static CustomInfoEntry kCustomInfoEntries[] = { - CustomInfoEntry(L"prod", L"CrashTestApp"), - CustomInfoEntry(L"ver", L"1.0"), -}; - -static ExceptionHandler* handler = NULL; -static CrashGenerationServer* crash_server = NULL; - -// Registers the window class. -// -// This function and its usage are only necessary if you want this code -// to be compatible with Win32 systems prior to the 'RegisterClassEx' -// function that was added to Windows 95. It is important to call this -// function so that the application will get 'well formed' small icons -// associated with it. -ATOM MyRegisterClass(HINSTANCE instance) { - WNDCLASSEX wcex; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = instance; - wcex.hIcon = LoadIcon(instance, - MAKEINTRESOURCE(IDI_CRASHGENERATIONAPP)); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CRASHGENERATIONAPP); - wcex.lpszClassName = window_class; - wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); - - return RegisterClassEx(&wcex); -} - -// Saves instance handle and creates main window -// -// In this function, we save the instance handle in a global variable and -// create and display the main program window. -BOOL InitInstance(HINSTANCE instance, int command_show) { - current_instance = instance; - HWND wnd = CreateWindow(window_class, - title, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - 0, - CW_USEDEFAULT, - 0, - NULL, - NULL, - instance, - NULL); - - if (!wnd) { - return FALSE; - } - - ShowWindow(wnd, command_show); - UpdateWindow(wnd); - - return TRUE; -} - -static void AppendTextToEditBox(TCHAR* text) { - EnterCriticalSection(cs_edit); - SYSTEMTIME current_time; - GetLocalTime(¤t_time); - TCHAR line[kMaximumLineLength]; - int result = swprintf_s(line, - kMaximumLineLength, - L"[%.2d-%.2d-%.4d %.2d:%.2d:%.2d] %s", - current_time.wMonth, - current_time.wDay, - current_time.wYear, - current_time.wHour, - current_time.wMinute, - current_time.wSecond, - text); - - if (result == -1) { - return; - } - - int length = GetWindowTextLength(client_status_edit_box); - SendMessage(client_status_edit_box, - EM_SETSEL, - (WPARAM)length, - (LPARAM)length); - SendMessage(client_status_edit_box, - EM_REPLACESEL, - (WPARAM)FALSE, - (LPARAM)line); - LeaveCriticalSection(cs_edit); -} - -static DWORD WINAPI AppendTextWorker(void* context) { - TCHAR* text = reinterpret_cast(context); - - AppendTextToEditBox(text); - delete[] text; - - return 0; -} - -bool ShowDumpResults(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - TCHAR* text = new TCHAR[kMaximumLineLength]; - text[0] = _T('\0'); - int result = swprintf_s(text, - kMaximumLineLength, - TEXT("Dump generation request %s\r\n"), - succeeded ? TEXT("succeeded") : TEXT("failed")); - if (result == -1) { - delete [] text; - } - - QueueUserWorkItem(AppendTextWorker, text, WT_EXECUTEDEFAULT); - return succeeded; -} - -static void ShowClientConnected(void* context, - const ClientInfo* client_info) { - TCHAR* line = new TCHAR[kMaximumLineLength]; - line[0] = _T('\0'); - int result = swprintf_s(line, - kMaximumLineLength, - L"Client connected:\t\t%d\r\n", - client_info->pid()); - - if (result == -1) { - delete[] line; - return; - } - - QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT); -} - -static void ShowClientCrashed(void* context, - const ClientInfo* client_info, - const wstring* dump_path) { - TCHAR* line = new TCHAR[kMaximumLineLength]; - line[0] = _T('\0'); - int result = swprintf_s(line, - kMaximumLineLength, - TEXT("Client requested dump:\t%d\r\n"), - client_info->pid()); - - if (result == -1) { - delete[] line; - return; - } - - QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT); - - CustomClientInfo custom_info = client_info->GetCustomInfo(); - if (custom_info.count <= 0) { - return; - } - - wstring str_line; - for (size_t i = 0; i < custom_info.count; ++i) { - if (i > 0) { - str_line += L", "; - } - str_line += custom_info.entries[i].name; - str_line += L": "; - str_line += custom_info.entries[i].value; - } - - line = new TCHAR[kMaximumLineLength]; - line[0] = _T('\0'); - result = swprintf_s(line, - kMaximumLineLength, - L"%s\n", - str_line.c_str()); - if (result == -1) { - delete[] line; - return; - } - QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT); -} - -static void ShowClientExited(void* context, - const ClientInfo* client_info) { - TCHAR* line = new TCHAR[kMaximumLineLength]; - line[0] = _T('\0'); - int result = swprintf_s(line, - kMaximumLineLength, - TEXT("Client exited:\t\t%d\r\n"), - client_info->pid()); - - if (result == -1) { - delete[] line; - return; - } - - QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT); -} - -void CrashServerStart() { - // Do not create another instance of the server. - if (crash_server) { - return; - } - - std::wstring dump_path = L"C:\\Dumps\\"; - - if (_wmkdir(dump_path.c_str()) && (errno != EEXIST)) { - MessageBoxW(NULL, L"Unable to create dump directory", L"Dumper", MB_OK); - return; - } - - crash_server = new CrashGenerationServer(kPipeName, - NULL, - ShowClientConnected, - NULL, - ShowClientCrashed, - NULL, - ShowClientExited, - NULL, - NULL, - NULL, - true, - &dump_path); - - if (!crash_server->Start()) { - MessageBoxW(NULL, L"Unable to start server", L"Dumper", MB_OK); - delete crash_server; - crash_server = NULL; - } -} - -void CrashServerStop() { - delete crash_server; - crash_server = NULL; -} - -void DerefZeroCrash() { - int* x = 0; - *x = 1; -} - -void InvalidParamCrash() { - printf(NULL); -} - -void PureCallCrash() { - Derived derived; -} - -void RequestDump() { - if (!handler->WriteMinidump()) { - MessageBoxW(NULL, L"Dump request failed", L"Dumper", MB_OK); - } - kCustomInfoEntries[1].set_value(L"1.1"); -} - -void CleanUp() { - if (cs_edit) { - DeleteCriticalSection(cs_edit); - delete cs_edit; - } - - if (handler) { - delete handler; - } - - if (crash_server) { - delete crash_server; - } -} - -// Processes messages for the main window. -// -// WM_COMMAND - process the application menu. -// WM_PAINT - Paint the main window. -// WM_DESTROY - post a quit message and return. -LRESULT CALLBACK WndProc(HWND wnd, - UINT message, - WPARAM w_param, - LPARAM l_param) { - int message_id; - int message_event; - PAINTSTRUCT ps; - HDC hdc; - - HINSTANCE instance = (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE); - - switch (message) { - case WM_COMMAND: - // Parse the menu selections. - message_id = LOWORD(w_param); - message_event = HIWORD(w_param); - switch (message_id) { - case IDM_ABOUT: - DialogBox(current_instance, - MAKEINTRESOURCE(IDD_ABOUTBOX), - wnd, - About); - break; - case IDM_EXIT: - DestroyWindow(wnd); - break; - case ID_SERVER_START: - CrashServerStart(); - break; - case ID_SERVER_STOP: - CrashServerStop(); - break; - case ID_CLIENT_DEREFZERO: - DerefZeroCrash(); - break; - case ID_CLIENT_INVALIDPARAM: - InvalidParamCrash(); - break; - case ID_CLIENT_PURECALL: - PureCallCrash(); - break; - case ID_CLIENT_REQUESTEXPLICITDUMP: - RequestDump(); - break; - default: - return DefWindowProc(wnd, message, w_param, l_param); - } - break; - case WM_CREATE: - client_status_edit_box = CreateWindow(TEXT("EDIT"), - NULL, - kEditBoxStyles, - 0, - 0, - 0, - 0, - wnd, - NULL, - instance, - NULL); - break; - case WM_SIZE: - // Make the edit control the size of the window's client area. - MoveWindow(client_status_edit_box, - 0, - 0, - LOWORD(l_param), // width of client area. - HIWORD(l_param), // height of client area. - TRUE); // repaint window. - break; - case WM_SETFOCUS: - SetFocus(client_status_edit_box); - break; - case WM_PAINT: - hdc = BeginPaint(wnd, &ps); - EndPaint(wnd, &ps); - break; - case WM_DESTROY: - CleanUp(); - PostQuitMessage(0); - break; - default: - return DefWindowProc(wnd, message, w_param, l_param); - } - - return 0; -} - -// Message handler for about box. -INT_PTR CALLBACK About(HWND dlg, - UINT message, - WPARAM w_param, - LPARAM l_param) { - UNREFERENCED_PARAMETER(l_param); - switch (message) { - case WM_INITDIALOG: - return (INT_PTR)TRUE; - - case WM_COMMAND: - if (LOWORD(w_param) == IDOK || LOWORD(w_param) == IDCANCEL) { - EndDialog(dlg, LOWORD(w_param)); - return (INT_PTR)TRUE; - } - break; - } - - return (INT_PTR)FALSE; -} - -} // namespace google_breakpad - -int APIENTRY _tWinMain(HINSTANCE instance, - HINSTANCE previous_instance, - LPTSTR command_line, - int command_show) { - using namespace google_breakpad; - - UNREFERENCED_PARAMETER(previous_instance); - UNREFERENCED_PARAMETER(command_line); - - cs_edit = new CRITICAL_SECTION(); - InitializeCriticalSection(cs_edit); - - CustomClientInfo custom_info = {kCustomInfoEntries, kCustomInfoCount}; - - CrashServerStart(); - // This is needed for CRT to not show dialog for invalid param - // failures and instead let the code handle it. - _CrtSetReportMode(_CRT_ASSERT, 0); - handler = new ExceptionHandler(L"C:\\dumps\\", - NULL, - google_breakpad::ShowDumpResults, - NULL, - ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, - kPipeName, - &custom_info); - - // Initialize global strings. - LoadString(instance, IDS_APP_TITLE, title, kMaxLoadString); - LoadString(instance, - IDC_CRASHGENERATIONAPP, - window_class, - kMaxLoadString); - MyRegisterClass(instance); - - // Perform application initialization. - if (!InitInstance(instance, command_show)) { - return FALSE; - } - - HACCEL accel_table = LoadAccelerators( - instance, - MAKEINTRESOURCE(IDC_CRASHGENERATIONAPP)); - - // Main message loop. - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) { - if (!TranslateAccelerator(msg.hwnd, accel_table, &msg)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - return static_cast(msg.wParam); -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.gyp deleted file mode 100644 index 3ce307da0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.gyp +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'crash_generation_app', - 'type': 'executable', - 'sources': [ - 'abstract_class.cc', - 'abstract_class.h', - 'crash_generation_app.cc', - 'crash_generation_app.h', - 'crash_generation_app.ico', - 'crash_generation_app.rc', - 'resource.h', - 'small.ico', - ], - 'libraries': [ - 'user32.lib', - ], - 'dependencies': [ - '../../breakpad_client.gyp:common', - '../../crash_generation/crash_generation.gyp:crash_generation_server', - '../../crash_generation/crash_generation.gyp:crash_generation_client', - '../../handler/exception_handler.gyp:exception_handler', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'SubSystem': '2', # Windows Subsystem as opposed to a console app - }, - }, - } - ] -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.h b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.h deleted file mode 100644 index 4d3bb6eb2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__ -#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__ - -#include "resource.h" - -#endif // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_CRASH_GENERATION_APP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.ico b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.ico deleted file mode 100644 index d551aa3aa..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.ico and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.rc b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.rc deleted file mode 100644 index a362562b9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/crash_generation_app.rc +++ /dev/null @@ -1,144 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_CRASHGENERATIONAPP ICON "crash_generation_app.ico" -IDI_SMALL ICON "small.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDC_CRASHGENERATIONAPP MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "E&xit", IDM_EXIT - END - POPUP "&Server" - BEGIN - MENUITEM "&Start", ID_SERVER_START - MENUITEM "S&top", ID_SERVER_STOP - END - POPUP "&Client" - BEGIN - MENUITEM "&Deref Zero", ID_CLIENT_DEREFZERO - MENUITEM "&Invalid Param", ID_CLIENT_INVALIDPARAM - MENUITEM "&Pure Call", ID_CLIENT_PURECALL - MENUITEM "&Request Dump", ID_CLIENT_REQUESTEXPLICITDUMP - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDC_CRASHGENERATIONAPP ACCELERATORS -BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUTBOX DIALOG 22, 17, 230, 75 -STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About" -FONT 8, "System" -BEGIN - ICON IDI_CRASHGENERATIONAPP,IDC_MYICON,14,9,16,16 - LTEXT "CrashGenerationApp Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX - LTEXT "Copyright (C) 2008",IDC_STATIC,49,20,119,8 - DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_APP_TITLE "CrashGenerationApp" - IDC_CRASHGENERATIONAPP "CRASHGENERATIONAPP" -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/resource.h b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/resource.h deleted file mode 100644 index 8c7f6570a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/resource.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// PreCompile.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#ifndef CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__ -#define CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by crash_generation_app.rc -// -#define IDC_MYICON 2 -#define IDD_CRASHGENERATIONAPP_DIALOG 102 -#define IDS_APP_TITLE 103 -#define IDD_ABOUTBOX 103 -#define IDM_ABOUT 104 -#define IDM_EXIT 105 -#define IDI_CRASHGENERATIONAPP 107 -#define IDI_SMALL 108 -#define IDC_CRASHGENERATIONAPP 109 -#define IDR_MAINFRAME 128 -#define ID_SERVER_START 32771 -#define ID_SERVER_STOP 32772 -#define ID_CLIENT_INVALIDPARAM 32773 -#define ID_CLIENT_ASSERTFAILURE 32774 -#define ID_CLIENT_DEREFZERO 32775 -#define ID_CLIENT_PURECALL 32777 -#define ID_CLIENT_REQUESTEXPLICITDUMP 32778 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32780 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif - -#endif // CLIENT_WINDOWS_TESTS_CRASH_GENERATION_APP_RESOURCE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/small.ico b/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/small.ico deleted file mode 100644 index d551aa3aa..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/small.ico and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp deleted file mode 100644 index b13603ef4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/client_tests.gyp +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'client_tests', - 'type': 'executable', - 'sources': [ - 'exception_handler_test.h', - 'exception_handler_test.cc', - 'exception_handler_death_test.cc', - 'exception_handler_nesting_test.cc', - 'minidump_test.cc', - 'dump_analysis.cc', - 'dump_analysis.h', - 'crash_generation_server_test.cc' - ], - 'dependencies': [ - 'testing.gyp:gtest', - 'testing.gyp:gmock', - '../breakpad_client.gyp:common', - '../crash_generation/crash_generation.gyp:crash_generation_server', - '../crash_generation/crash_generation.gyp:crash_generation_client', - '../handler/exception_handler.gyp:exception_handler', - 'processor_bits', - ] - }, - { - 'target_name': 'processor_bits', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)', - ] - }, - 'sources': [ - '<(DEPTH)/common/string_conversion.cc', - '<(DEPTH)/processor/basic_code_modules.cc', - '<(DEPTH)/processor/dump_context.cc', - '<(DEPTH)/processor/dump_object.cc', - '<(DEPTH)/processor/logging.cc', - '<(DEPTH)/processor/minidump.cc', - '<(DEPTH)/processor/pathname_stripper.cc', - '<(DEPTH)/processor/proc_maps_linux.cc', - ] - } - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc deleted file mode 100644 index b7b2b84f2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/crash_generation_server_test.cc +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/include/gmock/gmock.h" - -#include "client/windows/crash_generation/crash_generation_server.h" -#include "client/windows/common/ipc_protocol.h" - -using testing::_; - -namespace { - -const wchar_t kPipeName[] = - L"\\\\.\\pipe\\CrashGenerationServerTest\\TestCaseServer"; - -const DWORD kPipeDesiredAccess = FILE_READ_DATA | - FILE_WRITE_DATA | - FILE_WRITE_ATTRIBUTES; - -const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION | - SECURITY_SQOS_PRESENT; - -const DWORD kPipeMode = PIPE_READMODE_MESSAGE; - -#define arraysize(f) (sizeof(f) / sizeof(*f)) -const google_breakpad::CustomInfoEntry kCustomInfoEntries[] = { - google_breakpad::CustomInfoEntry(L"prod", L"CrashGenerationServerTest"), - google_breakpad::CustomInfoEntry(L"ver", L"1.0"), -}; - -class CrashGenerationServerTest : public ::testing::Test { - public: - CrashGenerationServerTest() - : crash_generation_server_(kPipeName, - NULL, - CallOnClientConnected, &mock_callbacks_, - CallOnClientDumpRequested, &mock_callbacks_, - CallOnClientExited, &mock_callbacks_, - CallOnClientUploadRequested, &mock_callbacks_, - false, - NULL), - thread_id_(0), - exception_pointers_(NULL) { - memset(&assert_info_, 0, sizeof(assert_info_)); - } - - protected: - class MockCrashGenerationServerCallbacks { - public: - MOCK_METHOD1(OnClientConnected, - void(const google_breakpad::ClientInfo* client_info)); - MOCK_METHOD2(OnClientDumpRequested, - void(const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path)); - MOCK_METHOD1(OnClientExited, - void(const google_breakpad::ClientInfo* client_info)); - MOCK_METHOD1(OnClientUploadRequested, - void(const DWORD crash_id)); - }; - - enum ClientFault { - NO_FAULT, - CLOSE_AFTER_CONNECT, - SEND_INVALID_REGISTRATION, - TRUNCATE_REGISTRATION, - CLOSE_AFTER_REGISTRATION, - RESPONSE_BUFFER_TOO_SMALL, - CLOSE_AFTER_RESPONSE, - SEND_INVALID_ACK - }; - - void SetUp() { - ASSERT_TRUE(crash_generation_server_.Start()); - } - - void FaultyClient(ClientFault fault_type) { - HANDLE pipe = CreateFile(kPipeName, - kPipeDesiredAccess, - 0, - NULL, - OPEN_EXISTING, - kPipeFlagsAndAttributes, - NULL); - - if (pipe == INVALID_HANDLE_VALUE) { - ASSERT_EQ(ERROR_PIPE_BUSY, GetLastError()); - - // Cannot continue retrying if wait on pipe fails. - ASSERT_TRUE(WaitNamedPipe(kPipeName, 500)); - - pipe = CreateFile(kPipeName, - kPipeDesiredAccess, - 0, - NULL, - OPEN_EXISTING, - kPipeFlagsAndAttributes, - NULL); - } - - ASSERT_NE(pipe, INVALID_HANDLE_VALUE); - - DWORD mode = kPipeMode; - ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, NULL, NULL)); - - DoFaultyClient(fault_type, pipe); - - CloseHandle(pipe); - } - - void DoTestFault(ClientFault fault) { - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)).Times(0); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(fault)); - - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - - ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT)); - - // Slight hack. The OnClientConnected is only invoked after the ack is - // received by the server. At that point, the FaultyClient call has already - // returned. The best way to wait until the server is done handling that is - // to send one more ping, whose processing will be blocked by delivery of - // the OnClientConnected message. - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); - } - - MockCrashGenerationServerCallbacks mock_callbacks_; - - private: - // Depends on the caller to successfully open the pipe before invocation and - // to close it immediately afterwards. - void DoFaultyClient(ClientFault fault_type, HANDLE pipe) { - if (fault_type == CLOSE_AFTER_CONNECT) { - return; - } - - google_breakpad::CustomClientInfo custom_info = {kCustomInfoEntries, - arraysize(kCustomInfoEntries)}; - - google_breakpad::ProtocolMessage msg( - fault_type == SEND_INVALID_REGISTRATION ? - google_breakpad::MESSAGE_TAG_NONE : - google_breakpad::MESSAGE_TAG_REGISTRATION_REQUEST, - GetCurrentProcessId(), - MiniDumpNormal, - &thread_id_, - &exception_pointers_, - &assert_info_, - custom_info, - NULL, - NULL, - NULL); - - DWORD bytes_count = 0; - - ASSERT_TRUE(WriteFile(pipe, - &msg, - fault_type == TRUNCATE_REGISTRATION ? - sizeof(msg) / 2 : sizeof(msg), - &bytes_count, - NULL)); - - if (fault_type == CLOSE_AFTER_REGISTRATION) { - return; - } - - google_breakpad::ProtocolMessage reply; - - if (!ReadFile(pipe, - &reply, - fault_type == RESPONSE_BUFFER_TOO_SMALL ? - sizeof(google_breakpad::ProtocolMessage) / 2 : - sizeof(google_breakpad::ProtocolMessage), - &bytes_count, - NULL)) { - switch (fault_type) { - case TRUNCATE_REGISTRATION: - case RESPONSE_BUFFER_TOO_SMALL: - case SEND_INVALID_REGISTRATION: - return; - - default: - FAIL() << "Unexpectedly failed to register."; - } - } - - if (fault_type == CLOSE_AFTER_RESPONSE) { - return; - } - - google_breakpad::ProtocolMessage ack_msg; - ack_msg.tag = google_breakpad::MESSAGE_TAG_REGISTRATION_ACK; - - ASSERT_TRUE(WriteFile(pipe, - &ack_msg, - SEND_INVALID_ACK ? - sizeof(ack_msg) : sizeof(ack_msg) / 2, - &bytes_count, - NULL)); - - return; - } - - static void CallOnClientConnected( - void* context, const google_breakpad::ClientInfo* client_info) { - static_cast(context)-> - OnClientConnected(client_info); - } - - static void CallOnClientDumpRequested( - void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path) { - static_cast(context)-> - OnClientDumpRequested(client_info, file_path); - } - - static void CallOnClientExited( - void* context, const google_breakpad::ClientInfo* client_info) { - static_cast(context)-> - OnClientExited(client_info); - } - - static void CallOnClientUploadRequested(void* context, const DWORD crash_id) { - static_cast(context)-> - OnClientUploadRequested(crash_id); - } - - DWORD thread_id_; - EXCEPTION_POINTERS* exception_pointers_; - MDRawAssertionInfo assert_info_; - - google_breakpad::CrashGenerationServer crash_generation_server_; -}; - -TEST_F(CrashGenerationServerTest, PingServerTest) { - DoTestFault(CLOSE_AFTER_CONNECT); -} - -TEST_F(CrashGenerationServerTest, InvalidRegistration) { - DoTestFault(SEND_INVALID_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, TruncateRegistration) { - DoTestFault(TRUNCATE_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, CloseAfterRegistration) { - DoTestFault(CLOSE_AFTER_REGISTRATION); -} - -TEST_F(CrashGenerationServerTest, ResponseBufferTooSmall) { - DoTestFault(RESPONSE_BUFFER_TOO_SMALL); -} - -TEST_F(CrashGenerationServerTest, CloseAfterResponse) { - DoTestFault(CLOSE_AFTER_RESPONSE); -} - -// It turns out that, as long as you send one byte, the ACK is accepted and -// registration succeeds. -TEST_F(CrashGenerationServerTest, SendInvalidAck) { - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(SEND_INVALID_ACK)); - - // See DoTestFault for an explanation of this line - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); - - EXPECT_CALL(mock_callbacks_, OnClientConnected(_)); - ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT)); - - // See DoTestFault for an explanation of this line - ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT)); -} - -} // anonymous namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc deleted file mode 100644 index 6bf854719..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.cc +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -#include "client/windows/unittests/dump_analysis.h" // NOLINT -#include "testing/gtest/include/gtest/gtest.h" - -DumpAnalysis::~DumpAnalysis() { - if (dump_file_view_ != NULL) { - EXPECT_TRUE(::UnmapViewOfFile(dump_file_view_)); - ::CloseHandle(dump_file_mapping_); - dump_file_mapping_ = NULL; - } - - if (dump_file_handle_ != NULL) { - ::CloseHandle(dump_file_handle_); - dump_file_handle_ = NULL; - } -} - -void DumpAnalysis::EnsureDumpMapped() { - if (dump_file_view_ == NULL) { - dump_file_handle_ = ::CreateFile(dump_file_.c_str(), - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - ASSERT_TRUE(dump_file_handle_ != NULL); - ASSERT_TRUE(dump_file_mapping_ == NULL); - - dump_file_mapping_ = ::CreateFileMapping(dump_file_handle_, - NULL, - PAGE_READONLY, - 0, - 0, - NULL); - ASSERT_TRUE(dump_file_mapping_ != NULL); - - dump_file_view_ = ::MapViewOfFile(dump_file_mapping_, - FILE_MAP_READ, - 0, - 0, - 0); - ASSERT_TRUE(dump_file_view_ != NULL); - } -} - -bool DumpAnalysis::HasTebs() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; - size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - - if (thread_list_size > 0 && thread_list != NULL) { - for (ULONG i = 0; i < thread_list->NumberOfThreads; ++i) { - if (!HasMemory(thread_list->Threads[i].Teb)) - return false; - } - - return true; - } - - // No thread list, no TEB info. - return false; -} - -bool DumpAnalysis::HasPeb() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; - size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - - if (thread_list_size > 0 && thread_list != NULL && - thread_list->NumberOfThreads > 0) { - FakeTEB* teb = NULL; - if (!HasMemory(thread_list->Threads[0].Teb, &teb)) - return false; - - return HasMemory(teb->peb); - } - - return false; -} - -bool DumpAnalysis::HasStream(ULONG stream_number) const { - void* stream = NULL; - size_t stream_size = GetStreamImpl(stream_number, &stream); - return stream_size > 0 && stream != NULL; -} - -size_t DumpAnalysis::GetStreamImpl(ULONG stream_number, void** stream) const { - MINIDUMP_DIRECTORY* directory = NULL; - ULONG memory_list_size = 0; - BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_, - stream_number, - &directory, - stream, - &memory_list_size); - - return ret ? memory_list_size : 0; -} - -bool DumpAnalysis::HasMemoryImpl(const void *addr_in, size_t structuresize, - void **structure) const { - uintptr_t address = reinterpret_cast(addr_in); - MINIDUMP_MEMORY_LIST* memory_list = NULL; - size_t memory_list_size = GetStream(MemoryListStream, &memory_list); - if (memory_list_size > 0 && memory_list != NULL) { - for (ULONG i = 0; i < memory_list->NumberOfMemoryRanges; ++i) { - MINIDUMP_MEMORY_DESCRIPTOR& descr = memory_list->MemoryRanges[i]; - const uintptr_t range_start = - static_cast(descr.StartOfMemoryRange); - uintptr_t range_end = range_start + descr.Memory.DataSize; - - if (address >= range_start && - address + structuresize < range_end) { - // The start address falls in the range, and the end address is - // in bounds, return a pointer to the structure if requested. - if (structure != NULL) - *structure = RVA_TO_ADDR(dump_file_view_, descr.Memory.Rva); - - return true; - } - } - } - - // We didn't find the range in a MINIDUMP_MEMORY_LIST, so maybe this - // is a full dump using MINIDUMP_MEMORY64_LIST with all the memory at the - // end of the dump file. - MINIDUMP_MEMORY64_LIST* memory64_list = NULL; - memory_list_size = GetStream(Memory64ListStream, &memory64_list); - if (memory_list_size > 0 && memory64_list != NULL) { - // Keep track of where the current descriptor maps to. - RVA64 curr_rva = memory64_list->BaseRva; - for (ULONG i = 0; i < memory64_list->NumberOfMemoryRanges; ++i) { - MINIDUMP_MEMORY_DESCRIPTOR64& descr = memory64_list->MemoryRanges[i]; - uintptr_t range_start = - static_cast(descr.StartOfMemoryRange); - uintptr_t range_end = range_start + static_cast(descr.DataSize); - - if (address >= range_start && - address + structuresize < range_end) { - // The start address falls in the range, and the end address is - // in bounds, return a pointer to the structure if requested. - if (structure != NULL) - *structure = RVA_TO_ADDR(dump_file_view_, curr_rva); - - return true; - } - - // Advance the current RVA. - curr_rva += descr.DataSize; - } - } - - return false; -} diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h deleted file mode 100644 index 6cef48d81..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_ -#define CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_ - -#include "client/windows/crash_generation/minidump_generator.h" - -// Convenience to get to the PEB pointer in a TEB. -struct FakeTEB { - char dummy[0x30]; - void* peb; -}; - -class DumpAnalysis { - public: - explicit DumpAnalysis(const std::wstring& file_path) - : dump_file_(file_path), dump_file_view_(NULL), dump_file_mapping_(NULL), - dump_file_handle_(NULL) { - EnsureDumpMapped(); - } - ~DumpAnalysis(); - - bool HasStream(ULONG stream_number) const; - - // This is template to keep type safety in the front, but we end up casting - // to void** inside the implementation to pass the pointer to Win32. So - // casting here is considered safe. - template - size_t GetStream(ULONG stream_number, StreamType** stream) const { - return GetStreamImpl(stream_number, reinterpret_cast(stream)); - } - - bool HasTebs() const; - bool HasPeb() const; - bool HasMemory(ULONG64 address) const { - return HasMemory(address, NULL); - } - - bool HasMemory(const void* address) const { - return HasMemory(address, NULL); - } - - template - bool HasMemory(ULONG64 address, StructureType** structure = NULL) const { - // We can't cope with 64 bit addresses for now. - if (address > 0xFFFFFFFFUL) - return false; - - return HasMemory(reinterpret_cast(address), structure); - } - - template - bool HasMemory(const void* addr_in, StructureType** structure = NULL) const { - return HasMemoryImpl(addr_in, sizeof(StructureType), - reinterpret_cast(structure)); - } - - protected: - void EnsureDumpMapped(); - - HANDLE dump_file_mapping_; - HANDLE dump_file_handle_; - void* dump_file_view_; - std::wstring dump_file_; - - private: - // This is the implementation of GetStream<>. - size_t GetStreamImpl(ULONG stream_number, void** stream) const; - - // This is the implementation of HasMemory<>. - bool HasMemoryImpl(const void* addr_in, size_t pointersize, - void** structure) const; -}; - -#endif // CLIENT_WINDOWS_UNITTESTS_DUMP_ANALYSIS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc deleted file mode 100644 index 079ca3d6f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_death_test.cc +++ /dev/null @@ -1,582 +0,0 @@ -// Copyright 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/windows/crash_generation/crash_generation_server.h" -#include "client/windows/handler/exception_handler.h" -#include "client/windows/unittests/exception_handler_test.h" -#include "common/windows/string_utils-inl.h" -#include "google_breakpad/processor/minidump.h" - -namespace { - -using std::wstring; -using namespace google_breakpad; - -const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashTest\\TestCaseServer"; -const char kSuccessIndicator[] = "success"; -const char kFailureIndicator[] = "failure"; - -// Utility function to test for a path's existence. -BOOL DoesPathExist(const TCHAR *path_name); - -enum OutOfProcGuarantee { - OUT_OF_PROC_GUARANTEED, - OUT_OF_PROC_BEST_EFFORT, -}; - -class ExceptionHandlerDeathTest : public ::testing::Test { - protected: - // Member variable for each test that they can use - // for temporary storage. - TCHAR temp_path_[MAX_PATH]; - // Actually constructs a temp path name. - virtual void SetUp(); - // A helper method that tests can use to crash. - void DoCrashAccessViolation(const OutOfProcGuarantee out_of_proc_guarantee); - void DoCrashPureVirtualCall(); -}; - -void ExceptionHandlerDeathTest::SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - TCHAR temp_path[MAX_PATH] = { '\0' }; - TCHAR test_name_wide[MAX_PATH] = { '\0' }; - // We want the temporary directory to be what the OS returns - // to us, + the test case name. - GetTempPath(MAX_PATH, temp_path); - // The test case name is exposed as a c-style string, - // convert it to a wchar_t string. - int dwRet = MultiByteToWideChar(CP_ACP, 0, test_info->name(), - strlen(test_info->name()), - test_name_wide, - MAX_PATH); - if (!dwRet) { - assert(false); - } - StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); -} - -BOOL DoesPathExist(const TCHAR *path_name) { - DWORD flags = GetFileAttributes(path_name); - if (flags == INVALID_FILE_ATTRIBUTES) { - return FALSE; - } - return TRUE; -} - -bool MinidumpWrittenCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - if (succeeded && DoesPathExist(dump_path)) { - fprintf(stderr, kSuccessIndicator); - } else { - fprintf(stderr, kFailureIndicator); - } - // If we don't flush, the output doesn't get sent before - // this process dies. - fflush(stderr); - return succeeded; -} - -TEST_F(ExceptionHandlerDeathTest, InProcTest) { - // For the in-proc test, we just need to instantiate an exception - // handler in in-proc mode, and crash. Since the entire test is - // reexecuted in the child process, we don't have to worry about - // the semantics of the exception handler being inherited/not - // inherited across CreateProcess(). - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( - new google_breakpad::ExceptionHandler( - temp_path_, - NULL, - &MinidumpWrittenCallback, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL)); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - int *i = NULL; - ASSERT_DEATH((*i)++, kSuccessIndicator); -} - -static bool gDumpCallbackCalled = false; - -void clientDumpCallback(void *dump_context, - const google_breakpad::ClientInfo *client_info, - const std::wstring *dump_path) { - gDumpCallbackCalled = true; -} - -void ExceptionHandlerDeathTest::DoCrashAccessViolation( - const OutOfProcGuarantee out_of_proc_guarantee) { - scoped_ptr exc; - - if (out_of_proc_guarantee == OUT_OF_PROC_GUARANTEED) { - google_breakpad::CrashGenerationClient *client = - new google_breakpad::CrashGenerationClient(kPipeName, - MiniDumpNormal, - NULL); // custom_info - ASSERT_TRUE(client->Register()); - exc.reset(new google_breakpad::ExceptionHandler( - temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_ALL, - client)); - } else { - ASSERT_TRUE(out_of_proc_guarantee == OUT_OF_PROC_BEST_EFFORT); - exc.reset(new google_breakpad::ExceptionHandler( - temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, - kPipeName, - NULL)); // custom_info - } - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - // Although this is executing in the child process of the death test, - // if it's not true we'll still get an error rather than the crash - // being expected. - ASSERT_TRUE(exc->IsOutOfProcess()); - int *i = NULL; - printf("%d\n", (*i)++); -} - -TEST_F(ExceptionHandlerDeathTest, OutOfProcTest) { - // We can take advantage of a detail of google test here to save some - // complexity in testing: when you do a death test, it actually forks. - // So we can make the main test harness the crash generation server, - // and call ASSERT_DEATH on a NULL dereference, it to expecting test - // the out of process scenario, since it's happening in a different - // process! This is different from the above because, above, we pass - // a NULL pipe name, and we also don't start a crash generation server. - - ASSERT_TRUE(DoesPathExist(temp_path_)); - std::wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - gDumpCallbackCalled = false; - ASSERT_DEATH(this->DoCrashAccessViolation(OUT_OF_PROC_BEST_EFFORT), ""); - EXPECT_TRUE(gDumpCallbackCalled); -} - -TEST_F(ExceptionHandlerDeathTest, OutOfProcGuaranteedTest) { - // This is similar to the previous test (OutOfProcTest). The only difference - // is that in this test, the crash generation client is created and registered - // with the crash generation server outside of the ExceptionHandler - // constructor which allows breakpad users to opt out of the default - // in-process dump generation when the registration with the crash generation - // server fails. - - ASSERT_TRUE(DoesPathExist(temp_path_)); - std::wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - gDumpCallbackCalled = false; - ASSERT_DEATH(this->DoCrashAccessViolation(OUT_OF_PROC_GUARANTEED), ""); - EXPECT_TRUE(gDumpCallbackCalled); -} - -TEST_F(ExceptionHandlerDeathTest, InvalidParameterTest) { - using google_breakpad::ExceptionHandler; - - ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, - ExceptionHandler::HANDLER_INVALID_PARAMETER); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Call with a bad argument. The invalid parameter will be swallowed - // and a dump will be generated, the process will exit(0). - ASSERT_EXIT(printf(NULL), ::testing::ExitedWithCode(0), ""); -} - - -struct PureVirtualCallBase { - PureVirtualCallBase() { - // We have to reinterpret so the linker doesn't get confused because the - // method isn't defined. - reinterpret_cast(this)->PureFunction(); - } - virtual ~PureVirtualCallBase() {} - virtual void PureFunction() const = 0; -}; -struct PureVirtualCall : public PureVirtualCallBase { - PureVirtualCall() { PureFunction(); } - virtual void PureFunction() const {} -}; - -void ExceptionHandlerDeathTest::DoCrashPureVirtualCall() { - PureVirtualCall instance; -} - -TEST_F(ExceptionHandlerDeathTest, PureVirtualCallTest) { - using google_breakpad::ExceptionHandler; - - ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, - ExceptionHandler::HANDLER_PURECALL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Calls a pure virtual function. - EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), ""); -} - -wstring find_minidump_in_directory(const wstring &directory) { - wstring search_path = directory + L"\\*"; - WIN32_FIND_DATA find_data; - HANDLE find_handle = FindFirstFileW(search_path.c_str(), &find_data); - if (find_handle == INVALID_HANDLE_VALUE) - return wstring(); - - wstring filename; - do { - const wchar_t extension[] = L".dmp"; - const int extension_length = sizeof(extension) / sizeof(extension[0]) - 1; - const int filename_length = wcslen(find_data.cFileName); - if (filename_length > extension_length && - wcsncmp(extension, - find_data.cFileName + filename_length - extension_length, - extension_length) == 0) { - filename = directory + L"\\" + find_data.cFileName; - break; - } - } while (FindNextFile(find_handle, &find_data)); - FindClose(find_handle); - return filename; -} - -#ifndef ADDRESS_SANITIZER - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( - new google_breakpad::ExceptionHandler( - temp_path_, - NULL, - NULL, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL)); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - // Get some executable memory. - const uint32_t kMemorySize = 256; // bytes - const int kOffset = kMemorySize / 2; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - char* memory = reinterpret_cast(VirtualAlloc(NULL, - kMemorySize, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE)); - ASSERT_TRUE(memory); - - // Write some instructions that will crash. Put them - // in the middle of the block of memory, because the - // minidump should contain 128 bytes on either side of the - // instruction pointer. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kOffset]; - uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes))); - EXPECT_EQ(0, memcmp(bytes + kOffset, instructions, sizeof(instructions))); - EXPECT_EQ(0, memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes))); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( - new google_breakpad::ExceptionHandler( - temp_path_, - NULL, - NULL, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL)); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - SYSTEM_INFO sSysInfo; // Useful information about the system - GetSystemInfo(&sSysInfo); // Initialize the structure. - - const uint32_t kMemorySize = 256; // bytes - const DWORD kPageSize = sSysInfo.dwPageSize; - const int kOffset = 0; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - // Get some executable memory. Specifically, reserve two pages, - // but only commit the second. - char* all_memory = reinterpret_cast(VirtualAlloc(NULL, - kPageSize * 2, - MEM_RESERVE, - PAGE_NOACCESS)); - ASSERT_TRUE(all_memory); - char* memory = all_memory + kPageSize; - ASSERT_TRUE(VirtualAlloc(memory, kPageSize, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)); - - // Write some instructions that will crash. Put them - // in the middle of the block of memory, because the - // minidump should contain 128 bytes on either side of the - // instruction pointer. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemorySize / 2, region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t suffix_bytes[kMemorySize / 2 - sizeof(instructions)]; - memset(suffix_bytes, 0, sizeof(suffix_bytes)); - EXPECT_TRUE(memcmp(bytes + kOffset, - instructions, sizeof(instructions)) == 0); - EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions), - suffix_bytes, sizeof(suffix_bytes)) == 0); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( - new google_breakpad::ExceptionHandler( - temp_path_, - NULL, - NULL, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL)); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - SYSTEM_INFO sSysInfo; // Useful information about the system - GetSystemInfo(&sSysInfo); // Initialize the structure. - - const DWORD kPageSize = sSysInfo.dwPageSize; - // This crashes with SIGILL on x86/x86-64/arm. - const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - const int kOffset = kPageSize - sizeof(instructions); - // Get some executable memory. Specifically, reserve two pages, - // but only commit the first. - char* memory = reinterpret_cast(VirtualAlloc(NULL, - kPageSize * 2, - MEM_RESERVE, - PAGE_NOACCESS)); - ASSERT_TRUE(memory); - ASSERT_TRUE(VirtualAlloc(memory, kPageSize, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)); - - // Write some instructions that will crash. - memcpy(memory + kOffset, instructions, sizeof(instructions)); - - // Now execute the instructions, which should crash. - typedef void (*void_function)(void); - void_function memory_function = - reinterpret_cast(memory + kOffset); - ASSERT_DEATH(memory_function(), ""); - - // free the memory. - VirtualFree(memory, 0, MEM_RELEASE); - - // Verify that the resulting minidump contains the memory around the IP - wstring minidump_filename_wide = find_minidump_in_directory(temp_path_); - ASSERT_FALSE(minidump_filename_wide.empty()); - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(minidump_filename_wide, - &minidump_filename)); - - // Read the minidump. Locate the exception record and the - // memory list, and then ensure that there is a memory region - // in the memory list that covers the instruction pointer from - // the exception record. - { - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpException* exception = minidump.GetException(); - MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(exception); - ASSERT_TRUE(memory_list); - ASSERT_LT((unsigned)0, memory_list->region_count()); - - MinidumpContext* context = exception->GetContext(); - ASSERT_TRUE(context); - - uint64_t instruction_pointer; - ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); - - MinidumpMemoryRegion* region = - memory_list->GetMemoryRegionForAddress(instruction_pointer); - ASSERT_TRUE(region); - - const size_t kPrefixSize = 128; // bytes - EXPECT_EQ(kPrefixSize + sizeof(instructions), region->GetSize()); - const uint8_t* bytes = region->GetMemory(); - ASSERT_TRUE(bytes); - - uint8_t prefix_bytes[kPrefixSize]; - memset(prefix_bytes, 0, sizeof(prefix_bytes)); - EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes))); - EXPECT_EQ(0, memcmp(bytes + kPrefixSize, - instructions, sizeof(instructions))); - } - - DeleteFileW(minidump_filename_wide.c_str()); -} - -#endif // !ADDRESS_SANITIZER - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc deleted file mode 100644 index 3ae1d7cd0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_nesting_test.cc +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/windows/handler/exception_handler.h" -#include "client/windows/unittests/exception_handler_test.h" - -namespace { - -const char kFoo[] = "foo"; -const char kBar[] = "bar"; - -const char kStartOfLine[] = "^"; -const char kEndOfLine[] = "$"; - -const char kFilterReturnsTrue[] = "filter_returns_true"; -const char kFilterReturnsFalse[] = "filter_returns_false"; - -const char kCallbackReturnsTrue[] = "callback_returns_true"; -const char kCallbackReturnsFalse[] = "callback_returns_false"; - -bool DoesPathExist(const wchar_t *path_name) { - DWORD flags = GetFileAttributes(path_name); - if (flags == INVALID_FILE_ATTRIBUTES) { - return false; - } - return true; -} - -// A callback function to run before Breakpad performs any substantial -// processing of an exception. A FilterCallback is called before writing -// a minidump. context is the parameter supplied by the user as -// callback_context when the handler was created. exinfo points to the -// exception record, if any; assertion points to assertion information, -// if any. -// -// If a FilterCallback returns true, Breakpad will continue processing, -// attempting to write a minidump. If a FilterCallback returns false, -// Breakpad will immediately report the exception as unhandled without -// writing a minidump, allowing another handler the opportunity to handle it. -template -bool CrashHandlerFilter(void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion) { - if (filter_return_value) { - fprintf(stderr, kFilterReturnsTrue); - } else { - fprintf(stderr, kFilterReturnsFalse); - } - fflush(stderr); - - return filter_return_value; -} - -// A callback function to run after the minidump has been written. -// minidump_id is a unique id for the dump, so the minidump -// file is \.dmp. context is the parameter supplied -// by the user as callback_context when the handler was created. exinfo -// points to the exception record, or NULL if no exception occurred. -// succeeded indicates whether a minidump file was successfully written. -// assertion points to information about an assertion if the handler was -// invoked by an assertion. -// -// If an exception occurred and the callback returns true, Breakpad will treat -// the exception as fully-handled, suppressing any other handlers from being -// notified of the exception. If the callback returns false, Breakpad will -// treat the exception as unhandled, and allow another handler to handle it. -// If there are no other handlers, Breakpad will report the exception to the -// system as unhandled, allowing a debugger or native crash dialog the -// opportunity to handle the exception. Most callback implementations -// should normally return the value of |succeeded|, or when they wish to -// not report an exception of handled, false. Callbacks will rarely want to -// return true directly (unless |succeeded| is true). -// -// For out-of-process dump generation, dump path and minidump ID will always -// be NULL. In case of out-of-process dump generation, the dump path and -// minidump id are controlled by the server process and are not communicated -// back to the crashing process. -template -bool MinidumpWrittenCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - bool rv = false; - if (callback_return_value && - succeeded && - DoesPathExist(dump_path)) { - rv = true; - fprintf(stderr, kCallbackReturnsTrue); - } else { - fprintf(stderr, kCallbackReturnsFalse); - } - fflush(stderr); - - return rv; -} - - -void DoCrash(const char *message) { - if (message) { - fprintf(stderr, "%s", message); - fflush(stderr); - } - int *i = NULL; - (*i)++; - - ASSERT_TRUE(false); -} - -void InstallExceptionHandlerAndCrash(bool install_filter, - bool filter_return_value, - bool install_callback, - bool callback_return_value) { - wchar_t temp_path[MAX_PATH] = { '\0' }; - GetTempPath(MAX_PATH, temp_path); - - ASSERT_TRUE(DoesPathExist(temp_path)); - google_breakpad::ExceptionHandler exc( - temp_path, - install_filter ? - (filter_return_value ? - &CrashHandlerFilter : - &CrashHandlerFilter) : - NULL, - install_callback ? - (callback_return_value ? - &MinidumpWrittenCallback : - &MinidumpWrittenCallback) : - NULL, - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - DoCrash(NULL); -} - -TEST(AssertDeathSanity, Simple) { - ASSERT_DEATH(DoCrash(NULL), ""); -} - -TEST(AssertDeathSanity, Regex) { - ASSERT_DEATH(DoCrash(kFoo), - std::string(kStartOfLine) + - std::string(kFoo) + - std::string(kEndOfLine)); - - ASSERT_DEATH(DoCrash(kBar), - std::string(kStartOfLine) + - std::string(kBar) + - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerCallbacks, FilterTrue_No_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - true, // filter_return_value - false, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsTrue) + - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerCallbacks, FilterTrue_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - true, // filter_return_value - true, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsTrue) + - std::string(kCallbackReturnsFalse) + - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerCallbacks, FilterFalse_No_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - false, // filter_return_value - false, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsFalse) + - std::string(kEndOfLine)); -} - -// Callback shouldn't be executed when filter returns false -TEST(ExceptionHandlerCallbacks, FilterFalse_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - false, // filter_return_value - true, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsFalse) + - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerCallbacks, No_Filter_No_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(false, // install_filter - true, // filter_return_value - false, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerCallbacks, No_Filter_Callback) { - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(false, // install_filter - true, // filter_return_value - true, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kCallbackReturnsFalse) + - std::string(kEndOfLine)); -} - - -TEST(ExceptionHandlerNesting, Skip_From_Inner_Filter) { - wchar_t temp_path[MAX_PATH] = { '\0' }; - GetTempPath(MAX_PATH, temp_path); - - ASSERT_TRUE(DoesPathExist(temp_path)); - google_breakpad::ExceptionHandler exc( - temp_path, - &CrashHandlerFilter, - &MinidumpWrittenCallback, - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); - - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - false, // filter_return_value - true, // install_callback - true), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsFalse) + // inner filter - std::string(kFilterReturnsTrue) + // outer filter - std::string(kCallbackReturnsFalse) + // outer callback - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerNesting, Skip_From_Inner_Callback) { - wchar_t temp_path[MAX_PATH] = { '\0' }; - GetTempPath(MAX_PATH, temp_path); - - ASSERT_TRUE(DoesPathExist(temp_path)); - google_breakpad::ExceptionHandler exc( - temp_path, - &CrashHandlerFilter, - &MinidumpWrittenCallback, - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); - - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - true, // filter_return_value - true, // install_callback - false), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsTrue) + // inner filter - std::string(kCallbackReturnsFalse) + // inner callback - std::string(kFilterReturnsTrue) + // outer filter - std::string(kCallbackReturnsFalse) + // outer callback - std::string(kEndOfLine)); -} - -TEST(ExceptionHandlerNesting, Handled_By_Inner_Handler) { - wchar_t temp_path[MAX_PATH] = { '\0' }; - GetTempPath(MAX_PATH, temp_path); - - ASSERT_TRUE(DoesPathExist(temp_path)); - google_breakpad::ExceptionHandler exc( - temp_path, - &CrashHandlerFilter, - &MinidumpWrittenCallback, - NULL, // callback_context - google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); - - ASSERT_DEATH( - InstallExceptionHandlerAndCrash(true, // install_filter - true, // filter_return_value - true, // install_callback - true), // callback_return_value - std::string(kStartOfLine) + - std::string(kFilterReturnsTrue) + // inner filter - std::string(kCallbackReturnsTrue) + // inner callback - std::string(kEndOfLine)); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc deleted file mode 100644 index 55275323e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.cc +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/windows/unittests/exception_handler_test.h" - -#include -#include -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "client/windows/crash_generation/crash_generation_server.h" -#include "client/windows/handler/exception_handler.h" -#include "client/windows/unittests/dump_analysis.h" // NOLINT -#include "common/windows/string_utils-inl.h" -#include "google_breakpad/processor/minidump.h" - -namespace testing { - -DisableExceptionHandlerInScope::DisableExceptionHandlerInScope() { - catch_exceptions_ = GTEST_FLAG(catch_exceptions); - GTEST_FLAG(catch_exceptions) = false; -} - -DisableExceptionHandlerInScope::~DisableExceptionHandlerInScope() { - GTEST_FLAG(catch_exceptions) = catch_exceptions_; -} - -} // namespace testing - -namespace { - -using std::wstring; -using namespace google_breakpad; - -const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashTest\\TestCaseServer"; -const char kSuccessIndicator[] = "success"; -const char kFailureIndicator[] = "failure"; - -const MINIDUMP_TYPE kFullDumpType = static_cast( - MiniDumpWithFullMemory | // Full memory from process. - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithHandleData); // Get all handle information. - -class ExceptionHandlerTest : public ::testing::Test { - protected: - // Member variable for each test that they can use - // for temporary storage. - TCHAR temp_path_[MAX_PATH]; - - // Actually constructs a temp path name. - virtual void SetUp(); - - // Deletes temporary files. - virtual void TearDown(); - - void DoCrashInvalidParameter(); - void DoCrashPureVirtualCall(); - - // Utility function to test for a path's existence. - static BOOL DoesPathExist(const TCHAR *path_name); - - // Client callback. - static void ClientDumpCallback( - void *dump_context, - const google_breakpad::ClientInfo *client_info, - const std::wstring *dump_path); - - static bool DumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded); - - static std::wstring dump_file; - static std::wstring full_dump_file; -}; - -std::wstring ExceptionHandlerTest::dump_file; -std::wstring ExceptionHandlerTest::full_dump_file; - -void ExceptionHandlerTest::SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - TCHAR temp_path[MAX_PATH] = { '\0' }; - TCHAR test_name_wide[MAX_PATH] = { '\0' }; - // We want the temporary directory to be what the OS returns - // to us, + the test case name. - GetTempPath(MAX_PATH, temp_path); - // THe test case name is exposed to use as a c-style string, - // But we might be working in UNICODE here on Windows. - int dwRet = MultiByteToWideChar(CP_ACP, 0, test_info->name(), - strlen(test_info->name()), - test_name_wide, - MAX_PATH); - if (!dwRet) { - assert(false); - } - StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); -} - -void ExceptionHandlerTest::TearDown() { - if (!dump_file.empty()) { - ::DeleteFile(dump_file.c_str()); - dump_file = L""; - } - if (!full_dump_file.empty()) { - ::DeleteFile(full_dump_file.c_str()); - full_dump_file = L""; - } -} - -BOOL ExceptionHandlerTest::DoesPathExist(const TCHAR *path_name) { - DWORD flags = GetFileAttributes(path_name); - if (flags == INVALID_FILE_ATTRIBUTES) { - return FALSE; - } - return TRUE; -} - -// static -void ExceptionHandlerTest::ClientDumpCallback( - void *dump_context, - const google_breakpad::ClientInfo *client_info, - const wstring *dump_path) { - dump_file = *dump_path; - // Create the full dump file name from the dump path. - full_dump_file = dump_file.substr(0, dump_file.length() - 4) + L"-full.dmp"; -} - -// static -bool ExceptionHandlerTest::DumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - dump_file = dump_path; - dump_file += L"\\"; - dump_file += minidump_id; - dump_file += L".dmp"; - return succeeded; -} - -void ExceptionHandlerTest::DoCrashInvalidParameter() { - google_breakpad::ExceptionHandler *exc = - new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, - google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER, - kFullDumpType, kPipeName, NULL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Although this is executing in the child process of the death test, - // if it's not true we'll still get an error rather than the crash - // being expected. - ASSERT_TRUE(exc->IsOutOfProcess()); - printf(NULL); -} - - -struct PureVirtualCallBase { - PureVirtualCallBase() { - // We have to reinterpret so the linker doesn't get confused because the - // method isn't defined. - reinterpret_cast(this)->PureFunction(); - } - virtual ~PureVirtualCallBase() {} - virtual void PureFunction() const = 0; -}; -struct PureVirtualCall : public PureVirtualCallBase { - PureVirtualCall() { PureFunction(); } - virtual void PureFunction() const {} -}; - -void ExceptionHandlerTest::DoCrashPureVirtualCall() { - google_breakpad::ExceptionHandler *exc = - new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, - google_breakpad::ExceptionHandler::HANDLER_PURECALL, - kFullDumpType, kPipeName, NULL); - - // Disable the message box for assertions - _CrtSetReportMode(_CRT_ASSERT, 0); - - // Although this is executing in the child process of the death test, - // if it's not true we'll still get an error rather than the crash - // being expected. - ASSERT_TRUE(exc->IsOutOfProcess()); - - // Create a new frame to ensure PureVirtualCall is not optimized to some - // other line in this function. - { - PureVirtualCall instance; - } -} - -// This test validates that the minidump is written correctly. -TEST_F(ExceptionHandlerTest, InvalidParameterMiniDumpTest) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - - // Call with a bad argument - ASSERT_TRUE(DoesPathExist(temp_path_)); - wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - EXPECT_EXIT(DoCrashInvalidParameter(), ::testing::ExitedWithCode(0), ""); - ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); - ASSERT_TRUE(DoesPathExist(dump_file.c_str())); - - // Verify the dump for infos. - DumpAnalysis mini(dump_file); - DumpAnalysis full(full_dump_file); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - // Minidump should have a memory listing, but no 64-bit memory. - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - - EXPECT_FALSE(full.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - - -// This test validates that the minidump is written correctly. -TEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) { - ASSERT_TRUE(DoesPathExist(temp_path_)); - - // Call with a bad argument - ASSERT_TRUE(DoesPathExist(temp_path_)); - wstring dump_path(temp_path_); - google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); - - ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); - - // This HAS to be EXPECT_, because when this test case is executed in the - // child process, the server registration will fail due to the named pipe - // being the same. - EXPECT_TRUE(server.Start()); - EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), ""); - ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty()); - ASSERT_TRUE(DoesPathExist(dump_file.c_str())); - - // Verify the dump for infos. - DumpAnalysis mini(dump_file); - DumpAnalysis full(full_dump_file); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - // Minidump should have a memory listing, but no 64-bit memory. - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - - EXPECT_FALSE(full.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - -// Test that writing a minidump produces a valid minidump containing -// some expected structures. -TEST_F(ExceptionHandlerTest, WriteMinidumpTest) { - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - NULL, - ExceptionHandler::HANDLER_ALL); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - ASSERT_TRUE(handler.WriteMinidump()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump and verify some info. - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - // TODO(ted): more comprehensive tests... -} - -// Test that an additional memory region can be included in the minidump. -TEST_F(ExceptionHandlerTest, AdditionalMemory) { - SYSTEM_INFO si; - GetSystemInfo(&si); - const uint32_t kMemorySize = si.dwPageSize; - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - NULL, - ExceptionHandler::HANDLER_ALL); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - // Add the memory region to the list of memory to be included. - handler.RegisterAppMemory(memory, kMemorySize); - ASSERT_TRUE(handler.WriteMinidump()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump. Ensure that the memory region is present - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - ASSERT_TRUE(region); - - EXPECT_EQ(kMemoryAddress, region->GetBase()); - EXPECT_EQ(kMemorySize, region->GetSize()); - - // Verify memory contents. - EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize)); - - delete[] memory; -} - -// Test that a memory region that was previously registered -// can be unregistered. -TEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) { - SYSTEM_INFO si; - GetSystemInfo(&si); - const uint32_t kMemorySize = si.dwPageSize; - - // Get some heap memory. - uint8_t* memory = new uint8_t[kMemorySize]; - const uintptr_t kMemoryAddress = reinterpret_cast(memory); - ASSERT_TRUE(memory); - - // Stick some data into the memory so the contents can be verified. - for (uint32_t i = 0; i < kMemorySize; ++i) { - memory[i] = i % 255; - } - - ExceptionHandler handler(temp_path_, - NULL, - DumpCallback, - NULL, - ExceptionHandler::HANDLER_ALL); - - // Disable GTest SEH handler - testing::DisableExceptionHandlerInScope disable_exception_handler; - - // Add the memory region to the list of memory to be included. - handler.RegisterAppMemory(memory, kMemorySize); - - // ...and then remove it - handler.UnregisterAppMemory(memory); - - ASSERT_TRUE(handler.WriteMinidump()); - ASSERT_FALSE(dump_file.empty()); - - string minidump_filename; - ASSERT_TRUE(WindowsStringUtils::safe_wcstombs(dump_file, - &minidump_filename)); - - // Read the minidump. Ensure that the memory region is not present. - Minidump minidump(minidump_filename); - ASSERT_TRUE(minidump.Read()); - - MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(dump_memory_list); - const MinidumpMemoryRegion* region = - dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress); - EXPECT_FALSE(region); - - delete[] memory; -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h deleted file mode 100644 index ef973e539..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/exception_handler_test.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_ -#define CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_ - -namespace testing { - -// By default, GTest (on Windows) installs a SEH filter (and a handler) before -// starting to run all the tests in order to avoid test interruptions is some -// of the tests are crashing. Unfortunately, this functionality prevents the -// execution to reach the UnhandledExceptionFilter installed by Google-Breakpad -// ExceptionHandler so in order to test the Google-Breakpad exception handling -// code the exception handling done by GTest must be disabled. -// Usage: -// -// google_breakpad::ExceptionHandler exc(...); -// -// // Disable GTest SEH handler -// testing::DisableExceptionHandlerInScope disable_exception_handler; -// ... -// ASSERT_DEATH( ... some crash ...); -// -class DisableExceptionHandlerInScope { - public: - DisableExceptionHandlerInScope(); - ~DisableExceptionHandlerInScope(); - - private: - bool catch_exceptions_; -}; - -} // namespace testing - -#endif // CLIENT_WINDOWS_UNITTESTS_EXCEPTION_HANDLER_TEST_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc deleted file mode 100644 index 8d2d726c4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/minidump_test.cc +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -#include "client/windows/crash_generation/minidump_generator.h" -#include "client/windows/unittests/dump_analysis.h" // NOLINT - -#include "gtest/gtest.h" - -namespace { - -// Minidump with stacks, PEB, TEB, and unloaded module list. -const MINIDUMP_TYPE kSmallDumpType = static_cast( - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithUnloadedModules); // Get unloaded modules when available. - -// Minidump with all of the above, plus memory referenced from stack. -const MINIDUMP_TYPE kLargerDumpType = static_cast( - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithUnloadedModules | // Get unloaded modules when available. - MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack. - -// Large dump with all process memory. -const MINIDUMP_TYPE kFullDumpType = static_cast( - MiniDumpWithFullMemory | // Full memory from process. - MiniDumpWithProcessThreadData | // Get PEB and TEB. - MiniDumpWithHandleData | // Get all handle information. - MiniDumpWithUnloadedModules); // Get unloaded modules when available. - -class MinidumpTest: public testing::Test { - public: - MinidumpTest() { - wchar_t temp_dir_path[ MAX_PATH ] = {0}; - ::GetTempPath(MAX_PATH, temp_dir_path); - dump_path_ = temp_dir_path; - } - - virtual void SetUp() { - // Make sure URLMon isn't loaded into our process. - ASSERT_EQ(NULL, ::GetModuleHandle(L"urlmon.dll")); - - // Then load and unload it to ensure we have something to - // stock the unloaded module list with. - HMODULE urlmon = ::LoadLibrary(L"urlmon.dll"); - ASSERT_TRUE(urlmon != NULL); - ASSERT_TRUE(::FreeLibrary(urlmon)); - } - - virtual void TearDown() { - if (!dump_file_.empty()) { - ::DeleteFile(dump_file_.c_str()); - dump_file_ = L""; - } - if (!full_dump_file_.empty()) { - ::DeleteFile(full_dump_file_.c_str()); - full_dump_file_ = L""; - } - } - - bool WriteDump(ULONG flags) { - using google_breakpad::MinidumpGenerator; - - // Fake exception is access violation on write to this. - EXCEPTION_RECORD ex_record = { - STATUS_ACCESS_VIOLATION, // ExceptionCode - 0, // ExceptionFlags - NULL, // ExceptionRecord; - reinterpret_cast(0xCAFEBABE), // ExceptionAddress; - 2, // NumberParameters; - { EXCEPTION_WRITE_FAULT, reinterpret_cast(this) } - }; - CONTEXT ctx_record = {}; - EXCEPTION_POINTERS ex_ptrs = { - &ex_record, - &ctx_record, - }; - - MinidumpGenerator generator(dump_path_, - ::GetCurrentProcess(), - ::GetCurrentProcessId(), - ::GetCurrentThreadId(), - ::GetCurrentThreadId(), - &ex_ptrs, - NULL, - static_cast(flags), - TRUE); - generator.GenerateDumpFile(&dump_file_); - generator.GenerateFullDumpFile(&full_dump_file_); - // And write a dump - bool result = generator.WriteMinidump(); - return result == TRUE; - } - - protected: - std::wstring dump_file_; - std::wstring full_dump_file_; - - std::wstring dump_path_; -}; - -// We need to be able to get file information from Windows -bool HasFileInfo(const std::wstring& file_path) { - DWORD dummy; - const wchar_t* path = file_path.c_str(); - DWORD length = ::GetFileVersionInfoSize(path, &dummy); - if (length == 0) - return NULL; - - void* data = calloc(length, 1); - if (!data) - return false; - - if (!::GetFileVersionInfo(path, dummy, length, data)) { - free(data); - return false; - } - - void* translate = NULL; - UINT page_count; - BOOL query_result = VerQueryValue( - data, - L"\\VarFileInfo\\Translation", - static_cast(&translate), - &page_count); - - free(data); - if (query_result && translate) { - return true; - } else { - return false; - } -} - -TEST_F(MinidumpTest, Version) { - // Loads DbgHelp.dll in process - ImagehlpApiVersion(); - - HMODULE dbg_help = ::GetModuleHandle(L"dbghelp.dll"); - ASSERT_TRUE(dbg_help != NULL); - - wchar_t dbg_help_file[1024] = {}; - ASSERT_TRUE(::GetModuleFileName(dbg_help, - dbg_help_file, - sizeof(dbg_help_file) / - sizeof(*dbg_help_file))); - ASSERT_TRUE(HasFileInfo(std::wstring(dbg_help_file)) != NULL); - -// LOG(INFO) << "DbgHelp.dll version: " << file_info->file_version(); -} - -TEST_F(MinidumpTest, Normal) { - EXPECT_TRUE(WriteDump(MiniDumpNormal)); - DumpAnalysis mini(dump_file_); - - // We expect threads, modules and some memory. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - - // We expect no PEB nor TEBs in this dump. - EXPECT_FALSE(mini.HasTebs()); - EXPECT_FALSE(mini.HasPeb()); - - // We expect no off-stack memory in this dump. - EXPECT_FALSE(mini.HasMemory(this)); -} - -TEST_F(MinidumpTest, SmallDump) { - ASSERT_TRUE(WriteDump(kSmallDumpType)); - DumpAnalysis mini(dump_file_); - - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs()); - EXPECT_TRUE(mini.HasPeb()); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - - // We expect no off-stack memory in this dump. - EXPECT_FALSE(mini.HasMemory(this)); -} - -TEST_F(MinidumpTest, LargerDump) { - ASSERT_TRUE(WriteDump(kLargerDumpType)); - DumpAnalysis mini(dump_file_); - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - - // We expect memory referenced by stack in this dump. - EXPECT_TRUE(mini.HasMemory(this)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs()); - EXPECT_TRUE(mini.HasPeb()); - - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(HandleDataStream)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); -} - -TEST_F(MinidumpTest, FullDump) { - ASSERT_TRUE(WriteDump(kFullDumpType)); - ASSERT_TRUE(dump_file_ != L""); - ASSERT_TRUE(full_dump_file_ != L""); - DumpAnalysis mini(dump_file_); - DumpAnalysis full(full_dump_file_); - - // Either dumps can contain part of the information. - - // The dump should have all of these streams. - EXPECT_TRUE(mini.HasStream(ThreadListStream)); - EXPECT_TRUE(full.HasStream(ThreadListStream)); - EXPECT_TRUE(mini.HasStream(ModuleListStream)); - EXPECT_TRUE(full.HasStream(ModuleListStream)); - EXPECT_TRUE(mini.HasStream(ExceptionStream)); - EXPECT_TRUE(full.HasStream(ExceptionStream)); - EXPECT_TRUE(mini.HasStream(SystemInfoStream)); - EXPECT_TRUE(full.HasStream(SystemInfoStream)); - EXPECT_TRUE(mini.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(full.HasStream(UnloadedModuleListStream)); - EXPECT_TRUE(mini.HasStream(MiscInfoStream)); - EXPECT_TRUE(full.HasStream(MiscInfoStream)); - EXPECT_TRUE(mini.HasStream(HandleDataStream)); - EXPECT_TRUE(full.HasStream(HandleDataStream)); - - // We expect memory referenced by stack in this dump. - EXPECT_FALSE(mini.HasMemory(this)); - EXPECT_TRUE(full.HasMemory(this)); - - // We expect PEB and TEBs in this dump. - EXPECT_TRUE(mini.HasTebs() || full.HasTebs()); - EXPECT_TRUE(mini.HasPeb() || full.HasPeb()); - - EXPECT_TRUE(mini.HasStream(MemoryListStream)); - EXPECT_TRUE(full.HasStream(Memory64ListStream)); - EXPECT_FALSE(mini.HasStream(Memory64ListStream)); - EXPECT_FALSE(full.HasStream(MemoryListStream)); - - // This is the only place we don't use OR because we want both not - // to have the streams. - EXPECT_FALSE(mini.HasStream(ThreadExListStream)); - EXPECT_FALSE(full.HasStream(ThreadExListStream)); - EXPECT_FALSE(mini.HasStream(CommentStreamA)); - EXPECT_FALSE(full.HasStream(CommentStreamA)); - EXPECT_FALSE(mini.HasStream(CommentStreamW)); - EXPECT_FALSE(full.HasStream(CommentStreamW)); - EXPECT_FALSE(mini.HasStream(FunctionTableStream)); - EXPECT_FALSE(full.HasStream(FunctionTableStream)); - EXPECT_FALSE(mini.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(full.HasStream(MemoryInfoListStream)); - EXPECT_FALSE(mini.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(full.HasStream(ThreadInfoListStream)); - EXPECT_FALSE(mini.HasStream(HandleOperationListStream)); - EXPECT_FALSE(full.HasStream(HandleOperationListStream)); - EXPECT_FALSE(mini.HasStream(TokenStream)); - EXPECT_FALSE(full.HasStream(TokenStream)); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp b/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp deleted file mode 100644 index 141d0ed0c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/testing.gyp +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'target_defaults': { - }, - 'targets': [ - { - 'target_name': 'gtest', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest', - '<(DEPTH)/testing/gtest/include', - ], - 'sources': [ - '<(DEPTH)/testing/gtest/src/gtest-all.cc', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest/include', - ], - # Visual C++ implements variadic templates strangely, and - # VC++2012 broke Google Test by lowering this value. See - # http://stackoverflow.com/questions/12558327/google-test-in-visual-studio-2012 - 'defines': ['_VARIADIC_MAX=10'], - }, - 'defines': ['_VARIADIC_MAX=10'], - }, - { - 'target_name': 'gmock', - 'type': 'static_library', - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/', - '<(DEPTH)/testing/gtest', - '<(DEPTH)/testing/gtest/include', - ], - 'sources': [ - '<(DEPTH)/testing/src/gmock-all.cc', - '<(DEPTH)/testing/src/gmock_main.cc', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)/testing/include', - '<(DEPTH)/testing/gtest/include', - ], - 'defines': ['_VARIADIC_MAX=10'], - }, - 'defines': ['_VARIADIC_MAX=10'], - }, - - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/Makefile.in b/toolkit/crashreporter/google-breakpad/src/common/Makefile.in deleted file mode 100644 index 44a1f79fd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/Makefile.in +++ /dev/null @@ -1,9 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/rules.mk - -# memory.h in this dir breaks things if -I$(srcdir) gets added, since memory.h -# is also a system header and the copy here winds up getting included instead. -INCLUDES := $(LOCAL_INCLUDES) -I$(DIST)/include diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S b/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S deleted file mode 100644 index fd6326adf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S +++ /dev/null @@ -1,489 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// A minimalistic implementation of getcontext() to be used by -// Google Breakpad on Android. - -#include "common/android/ucontext_constants.h" - -/* int getcontext (ucontext_t *ucp) */ - -#if defined(__arm__) - - .text - .global breakpad_getcontext - .hidden breakpad_getcontext - .type breakpad_getcontext, #function - .align 0 - .fnstart -breakpad_getcontext: - - /* First, save r4-r11 */ - add r1, r0, #(MCONTEXT_GREGS_OFFSET + 4*4) - stm r1, {r4-r11} - - /* r12 is a scratch register, don't save it */ - - /* Save sp and lr explicitly. */ - /* - sp can't be stored with stmia in Thumb-2 */ - /* - STM instructions that store sp and pc are deprecated in ARM */ - str sp, [r0, #(MCONTEXT_GREGS_OFFSET + 13*4)] - str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)] - - /* Save the caller's address in 'pc' */ - str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 15*4)] - - /* Save ucontext_t* pointer across next call */ - mov r4, r0 - - /* Call sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ - mov r0, #0 /* SIG_BLOCK */ - mov r1, #0 /* NULL */ - add r2, r4, #UCONTEXT_SIGMASK_OFFSET - bl sigprocmask(PLT) - - /* Intentionally do not save the FPU state here. This is because on - * Linux/ARM, one should instead use ptrace(PTRACE_GETFPREGS) or - * ptrace(PTRACE_GETVFPREGS) to get it. - * - * Note that a real implementation of getcontext() would need to save - * this here to allow setcontext()/swapcontext() to work correctly. - */ - - /* Restore the values of r4 and lr */ - mov r0, r4 - ldr lr, [r0, #(MCONTEXT_GREGS_OFFSET + 14*4)] - ldr r4, [r0, #(MCONTEXT_GREGS_OFFSET + 4*4)] - - /* Return 0 */ - mov r0, #0 - bx lr - - .fnend - .size breakpad_getcontext, . - breakpad_getcontext - -#elif defined(__aarch64__) - -#define _NSIG 64 -#define __NR_rt_sigprocmask 135 - - .text - .global breakpad_getcontext - .hidden breakpad_getcontext - .type breakpad_getcontext, #function - .align 4 - .cfi_startproc -breakpad_getcontext: - - /* The saved context will return to the getcontext() call point - with a return value of 0 */ - str xzr, [x0, MCONTEXT_GREGS_OFFSET + 0 * REGISTER_SIZE] - - stp x18, x19, [x0, MCONTEXT_GREGS_OFFSET + 18 * REGISTER_SIZE] - stp x20, x21, [x0, MCONTEXT_GREGS_OFFSET + 20 * REGISTER_SIZE] - stp x22, x23, [x0, MCONTEXT_GREGS_OFFSET + 22 * REGISTER_SIZE] - stp x24, x25, [x0, MCONTEXT_GREGS_OFFSET + 24 * REGISTER_SIZE] - stp x26, x27, [x0, MCONTEXT_GREGS_OFFSET + 26 * REGISTER_SIZE] - stp x28, x29, [x0, MCONTEXT_GREGS_OFFSET + 28 * REGISTER_SIZE] - str x30, [x0, MCONTEXT_GREGS_OFFSET + 30 * REGISTER_SIZE] - - /* Place LR into the saved PC, this will ensure that when - switching to this saved context with setcontext() control - will pass back to the caller of getcontext(), we have - already arranged to return the appropriate return value in x0 - above. */ - str x30, [x0, MCONTEXT_PC_OFFSET] - - /* Save the current SP */ - mov x2, sp - str x2, [x0, MCONTEXT_SP_OFFSET] - - /* Initialize the pstate. */ - str xzr, [x0, MCONTEXT_PSTATE_OFFSET] - - /* Figure out where to place the first context extension - block. */ - add x2, x0, #MCONTEXT_EXTENSION_OFFSET - - /* Write the context extension fpsimd header. */ - mov w3, #(FPSIMD_MAGIC & 0xffff) - movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 - str w3, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET] - mov w3, #FPSIMD_CONTEXT_SIZE - str w3, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET] - - /* Fill in the FP SIMD context. */ - add x3, x2, #(FPSIMD_CONTEXT_VREGS_OFFSET + 8 * SIMD_REGISTER_SIZE) - stp d8, d9, [x3], #(2 * SIMD_REGISTER_SIZE) - stp d10, d11, [x3], #(2 * SIMD_REGISTER_SIZE) - stp d12, d13, [x3], #(2 * SIMD_REGISTER_SIZE) - stp d14, d15, [x3], #(2 * SIMD_REGISTER_SIZE) - - add x3, x2, FPSIMD_CONTEXT_FPSR_OFFSET - - mrs x4, fpsr - str w4, [x3] - - mrs x4, fpcr - str w4, [x3, FPSIMD_CONTEXT_FPCR_OFFSET - FPSIMD_CONTEXT_FPSR_OFFSET] - - /* Write the termination context extension header. */ - add x2, x2, #FPSIMD_CONTEXT_SIZE - - str xzr, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET] - str xzr, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET] - - /* Grab the signal mask */ - /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ - add x2, x0, #UCONTEXT_SIGMASK_OFFSET - mov x0, #0 /* SIG_BLOCK */ - mov x1, #0 /* NULL */ - mov x3, #(_NSIG / 8) - mov x8, #__NR_rt_sigprocmask - svc 0 - - /* Return x0 for success */ - mov x0, 0 - ret - - .cfi_endproc - .size breakpad_getcontext, . - breakpad_getcontext - -#elif defined(__i386__) - - .text - .global breakpad_getcontext - .hidden breakpad_getcontext - .align 4 - .type breakpad_getcontext, @function - -breakpad_getcontext: - - movl 4(%esp), %eax /* eax = uc */ - - /* Save register values */ - movl %ecx, MCONTEXT_ECX_OFFSET(%eax) - movl %edx, MCONTEXT_EDX_OFFSET(%eax) - movl %ebx, MCONTEXT_EBX_OFFSET(%eax) - movl %edi, MCONTEXT_EDI_OFFSET(%eax) - movl %esi, MCONTEXT_ESI_OFFSET(%eax) - movl %ebp, MCONTEXT_EBP_OFFSET(%eax) - - movl (%esp), %edx /* return address */ - lea 4(%esp), %ecx /* exclude return address from stack */ - mov %edx, MCONTEXT_EIP_OFFSET(%eax) - mov %ecx, MCONTEXT_ESP_OFFSET(%eax) - - xorl %ecx, %ecx - movw %fs, %cx - mov %ecx, MCONTEXT_FS_OFFSET(%eax) - - movl $0, MCONTEXT_EAX_OFFSET(%eax) - - /* Save floating point state to fpregstate, then update - * the fpregs pointer to point to it */ - leal UCONTEXT_FPREGS_MEM_OFFSET(%eax), %ecx - fnstenv (%ecx) - fldenv (%ecx) - mov %ecx, UCONTEXT_FPREGS_OFFSET(%eax) - - /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */ - leal UCONTEXT_SIGMASK_OFFSET(%eax), %edx - xorl %ecx, %ecx - push %edx /* &uc->uc_sigmask */ - push %ecx /* NULL */ - push %ecx /* SIGBLOCK == 0 on i386 */ - call sigprocmask@PLT - addl $12, %esp - - movl $0, %eax - ret - - .size breakpad_getcontext, . - breakpad_getcontext - -#elif defined(__mips__) - -// This implementation is inspired by implementation of getcontext in glibc. -#if _MIPS_SIM == _ABIO32 -#include -#include -#include -#else -#include -#include -#endif - -// from asm/asm.h -#if _MIPS_SIM == _ABIO32 -#define ALSZ 7 -#define ALMASK ~7 -#define SZREG 4 -#else // _MIPS_SIM != _ABIO32 -#define ALSZ 15 -#define ALMASK ~15 -#define SZREG 8 -#endif - -#include // for __NR_rt_sigprocmask - -#define _NSIG8 128 / 8 -#define SIG_BLOCK 1 - - - .text -LOCALS_NUM = 1 // save gp on stack -FRAME_SIZE = ((LOCALS_NUM * SZREG) + ALSZ) & ALMASK - -GP_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG) -MCONTEXT_REG_SIZE = 8 - -#if _MIPS_SIM == _ABIO32 - -NESTED (breakpad_getcontext, FRAME_SIZE, ra) - .mask 0x00000000, 0 - .fmask 0x00000000, 0 - - .set noreorder - .cpload t9 - .set reorder - - move a2, sp -#define _SP a2 - - addiu sp, -FRAME_SIZE - .cprestore GP_FRAME_OFFSET - - sw s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw fp, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sw ra, MCONTEXT_PC_OFFSET(a0) - -#ifdef __mips_hard_float - s.d fs0, (20 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d fs1, (22 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d fs2, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d fs3, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d fs4, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d fs5, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - - cfc1 v1, fcr31 - sw v1, MCONTEXT_FPC_CSR(a0) -#endif // __mips_hard_float - - /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - addu a2, a0, UCONTEXT_SIGMASK_OFFSET - move a1, zero - li a0, SIG_BLOCK - li v0, __NR_rt_sigprocmask - syscall - - addiu sp, FRAME_SIZE - jr ra - -END (breakpad_getcontext) -#else - -#ifndef NESTED -/* - * NESTED - declare nested routine entry point - */ -#define NESTED(symbol, framesize, rpc) \ - .globl symbol; \ - .align 2; \ - .type symbol,@function; \ - .ent symbol,0; \ -symbol: .frame sp, framesize, rpc; -#endif - -/* - * END - mark end of function - */ -#ifndef END -# define END(function) \ - .end function; \ - .size function,.-function -#endif - -/* int getcontext (ucontext_t *ucp) */ - -NESTED (breakpad_getcontext, FRAME_SIZE, ra) - .mask 0x10000000, 0 - .fmask 0x00000000, 0 - - move a2, sp -#define _SP a2 - move a3, gp -#define _GP a3 - - daddiu sp, -FRAME_SIZE - .cpsetup $25, GP_FRAME_OFFSET, breakpad_getcontext - - /* Store a magic flag. */ - li v1, 1 - sd v1, (0 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) /* zero */ - - sd s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd _GP, (28 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd s8, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) - sd ra, MCONTEXT_PC_OFFSET(a0) - -#ifdef __mips_hard_float - s.d $f24, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f25, (25 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f26, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f27, (27 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f28, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f29, (29 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f30, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - s.d $f31, (31 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) - - cfc1 v1, $31 - sw v1, MCONTEXT_FPC_CSR(a0) -#endif /* __mips_hard_float */ - -/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - daddu a2, a0, UCONTEXT_SIGMASK_OFFSET - move a1, zero - li a0, SIG_BLOCK - - li v0, __NR_rt_sigprocmask - syscall - - .cpreturn - daddiu sp, FRAME_SIZE - move v0, zero - jr ra - -END (breakpad_getcontext) -#endif // _MIPS_SIM == _ABIO32 - -#elif defined(__x86_64__) -/* The x64 implementation of breakpad_getcontext was derived in part - from the implementation of libunwind which requires the following - notice. */ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - .text - .global breakpad_getcontext - .hidden breakpad_getcontext - .align 4 - .type breakpad_getcontext, @function - -breakpad_getcontext: - .cfi_startproc - - /* Callee saved: RBX, RBP, R12-R15 */ - movq %r12, MCONTEXT_GREGS_R12(%rdi) - movq %r13, MCONTEXT_GREGS_R13(%rdi) - movq %r14, MCONTEXT_GREGS_R14(%rdi) - movq %r15, MCONTEXT_GREGS_R15(%rdi) - movq %rbp, MCONTEXT_GREGS_RBP(%rdi) - movq %rbx, MCONTEXT_GREGS_RBX(%rdi) - - /* Save argument registers (not strictly needed, but setcontext - restores them, so don't restore garbage). */ - movq %r8, MCONTEXT_GREGS_R8(%rdi) - movq %r9, MCONTEXT_GREGS_R9(%rdi) - movq %rdi, MCONTEXT_GREGS_RDI(%rdi) - movq %rsi, MCONTEXT_GREGS_RSI(%rdi) - movq %rdx, MCONTEXT_GREGS_RDX(%rdi) - movq %rax, MCONTEXT_GREGS_RAX(%rdi) - movq %rcx, MCONTEXT_GREGS_RCX(%rdi) - - /* Save fp state (not needed, except for setcontext not - restoring garbage). */ - leaq MCONTEXT_FPREGS_MEM(%rdi),%r8 - movq %r8, MCONTEXT_FPREGS_PTR(%rdi) - fnstenv (%r8) - stmxcsr FPREGS_OFFSET_MXCSR(%r8) - - leaq 8(%rsp), %rax /* exclude this call. */ - movq %rax, MCONTEXT_GREGS_RSP(%rdi) - - movq 0(%rsp), %rax - movq %rax, MCONTEXT_GREGS_RIP(%rdi) - - /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */ - leaq UCONTEXT_SIGMASK_OFFSET(%rdi), %rdx // arg3 - xorq %rsi, %rsi // arg2 NULL - xorq %rdi, %rdi // arg1 SIGBLOCK == 0 - call sigprocmask@PLT - - /* Always return 0 for success, even if sigprocmask failed. */ - xorl %eax, %eax - ret - .cfi_endproc - .size breakpad_getcontext, . - breakpad_getcontext - -#else -#error "This file has not been ported for your CPU!" -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc deleted file mode 100644 index 2c550bf28..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#if defined(__x86_64__) -#include -#endif - -#include - -#include "breakpad_googletest_includes.h" -#include "common/android/ucontext_constants.h" - -template -struct CompileAssertEquals { - // a compilation error here indicates left and right are not equal. - char left_too_large[right - left]; - // a compilation error here indicates left and right are not equal. - char right_too_large[left - right]; -}; - -#define COMPILE_ASSERT_EQ(left, right, tag) \ - CompileAssertEquals tag; - -TEST(AndroidUContext, GRegsOffset) { -#if defined(__arm__) - // There is no gregs[] array on ARM, so compare to the offset of - // first register fields, since they're stored in order. - ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.arm_r0)); -#elif defined(__aarch64__) - // There is no gregs[] array on ARM, so compare to the offset of - // first register fields, since they're stored in order. - ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.regs[0])); - ASSERT_EQ(static_cast(MCONTEXT_SP_OFFSET), - offsetof(ucontext_t,uc_mcontext.sp)); - ASSERT_EQ(static_cast(MCONTEXT_PC_OFFSET), - offsetof(ucontext_t,uc_mcontext.pc)); - ASSERT_EQ(static_cast(MCONTEXT_PSTATE_OFFSET), - offsetof(ucontext_t,uc_mcontext.pstate)); - ASSERT_EQ(static_cast(MCONTEXT_EXTENSION_OFFSET), - offsetof(ucontext_t,uc_mcontext.__reserved)); -#elif defined(__i386__) - ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.gregs)); -#define CHECK_REG(x) \ - ASSERT_EQ(static_cast(MCONTEXT_##x##_OFFSET), \ - offsetof(ucontext_t,uc_mcontext.gregs[REG_##x])) - CHECK_REG(GS); - CHECK_REG(FS); - CHECK_REG(ES); - CHECK_REG(DS); - CHECK_REG(EDI); - CHECK_REG(ESI); - CHECK_REG(EBP); - CHECK_REG(ESP); - CHECK_REG(EBX); - CHECK_REG(EDX); - CHECK_REG(ECX); - CHECK_REG(EAX); - CHECK_REG(TRAPNO); - CHECK_REG(ERR); - CHECK_REG(EIP); - CHECK_REG(CS); - CHECK_REG(EFL); - CHECK_REG(UESP); - CHECK_REG(SS); - - ASSERT_EQ(static_cast(UCONTEXT_FPREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.fpregs)); - - ASSERT_EQ(static_cast(UCONTEXT_FPREGS_MEM_OFFSET), - offsetof(ucontext_t,__fpregs_mem)); -#elif defined(__mips__) - ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.gregs)); - - // PC for mips is not part of gregs. - ASSERT_EQ(static_cast(MCONTEXT_PC_OFFSET), - offsetof(ucontext_t,uc_mcontext.pc)); - - ASSERT_EQ(static_cast(MCONTEXT_FPREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.fpregs)); - - ASSERT_EQ(static_cast(MCONTEXT_FPC_CSR), - offsetof(ucontext_t,uc_mcontext.fpc_csr)); -#elif defined(__x86_64__) - - COMPILE_ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.gregs), - mcontext_gregs_offset); -#define CHECK_REG(x) \ - COMPILE_ASSERT_EQ(static_cast(MCONTEXT_GREGS_##x), \ - offsetof(ucontext_t,uc_mcontext.gregs[REG_##x]), reg_##x) - CHECK_REG(R8); - CHECK_REG(R9); - CHECK_REG(R10); - CHECK_REG(R11); - CHECK_REG(R12); - CHECK_REG(R13); - CHECK_REG(R14); - CHECK_REG(R15); - CHECK_REG(RDI); - CHECK_REG(RSI); - CHECK_REG(RBP); - CHECK_REG(RBX); - CHECK_REG(RDX); - CHECK_REG(RAX); - CHECK_REG(RCX); - CHECK_REG(RSP); - CHECK_REG(RIP); - - // sigcontext is an analog to mcontext_t. The layout should be the same. - COMPILE_ASSERT_EQ(offsetof(mcontext_t,fpregs), - offsetof(sigcontext,fpstate), sigcontext_fpstate); - // Check that _fpstate from asm/sigcontext.h is essentially the same - // as _libc_fpstate. - COMPILE_ASSERT_EQ(sizeof(_libc_fpstate), sizeof(_fpstate), - sigcontext_fpstate_size); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,cwd),offsetof(_fpstate,cwd), - sigcontext_fpstate_cwd); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,swd),offsetof(_fpstate,swd), - sigcontext_fpstate_swd); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,ftw),offsetof(_fpstate,twd), - sigcontext_fpstate_twd); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,fop),offsetof(_fpstate,fop), - sigcontext_fpstate_fop); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,rip),offsetof(_fpstate,rip), - sigcontext_fpstate_rip); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,rdp),offsetof(_fpstate,rdp), - sigcontext_fpstate_rdp); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,mxcsr),offsetof(_fpstate,mxcsr), - sigcontext_fpstate_mxcsr); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,mxcr_mask), - offsetof(_fpstate,mxcsr_mask), - sigcontext_fpstate_mxcsr_mask); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_st), offsetof(_fpstate,st_space), - sigcontext_fpstate_stspace); - COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_xmm), offsetof(_fpstate,xmm_space), - sigcontext_fpstate_xmm_space); - - COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_PTR, - offsetof(ucontext_t,uc_mcontext.fpregs), - mcontext_fpregs_ptr); - COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_MEM, offsetof(ucontext_t,__fpregs_mem), - mcontext_fpregs_mem); - COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR, offsetof(_libc_fpstate,mxcsr), - fpregs_offset_mxcsr); - COMPILE_ASSERT_EQ(UCONTEXT_SIGMASK_OFFSET, offsetof(ucontext_t, uc_sigmask), - ucontext_sigmask); -#else - ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), - offsetof(ucontext_t,uc_mcontext.gregs)); -#endif -} - -TEST(AndroidUContext, SigmakOffset) { - ASSERT_EQ(static_cast(UCONTEXT_SIGMASK_OFFSET), - offsetof(ucontext_t,uc_sigmask)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h deleted file mode 100644 index b2a28df44..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// The Android provides BSD-based definitions for the ElfXX_Nhdr -// types -// always source-compatible with the GLibc/kernel ones. To overcome this -// issue without modifying a lot of code in Breakpad, use an ugly macro -// renaming trick with #include_next - -// Avoid conflict with BSD-based definition of ElfXX_Nhdr. -// Unfortunately, their field member names do not use a 'n_' prefix. -#define Elf32_Nhdr __bsd_Elf32_Nhdr -#define Elf64_Nhdr __bsd_Elf64_Nhdr - -// In case they are defined by the NDK version -#define Elf32_auxv_t __bionic_Elf32_auxv_t -#define Elf64_auxv_t __bionic_Elf64_auxv_t - -#define Elf32_Dyn __bionic_Elf32_Dyn -#define Elf64_Dyn __bionic_Elf64_Dyn - -#include_next - -#undef Elf32_Nhdr -#undef Elf64_Nhdr - -typedef struct { - Elf32_Word n_namesz; - Elf32_Word n_descsz; - Elf32_Word n_type; -} Elf32_Nhdr; - -typedef struct { - Elf64_Word n_namesz; - Elf64_Word n_descsz; - Elf64_Word n_type; -} Elf64_Nhdr; - -#undef Elf32_auxv_t -#undef Elf64_auxv_t - -typedef struct { - uint32_t a_type; - union { - uint32_t a_val; - } a_un; -} Elf32_auxv_t; - -typedef struct { - uint64_t a_type; - union { - uint64_t a_val; - } a_un; -} Elf64_auxv_t; - -#undef Elf32_Dyn -#undef Elf64_Dyn - -typedef struct { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - -typedef struct { - Elf64_Sxword d_tag; - union { - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; -} Elf64_Dyn; - - -// __WORDSIZE is GLibc-specific and used by Google Breakpad on Linux. -#ifndef __WORDSIZE -#if defined(__i386__) || defined(__ARM_EABI__) || defined(__mips__) -#define __WORDSIZE 32 -#elif defined(__x86_64__) || defined(__aarch64__) -#define __WORDSIZE 64 -#else -#error "Unsupported Android CPU ABI" -#endif -#endif - -// The Android headers don't always define this constant. -#ifndef EM_X86_64 -#define EM_X86_64 62 -#endif - -#ifndef EM_PPC64 -#define EM_PPC64 21 -#endif - -#ifndef EM_S390 -#define EM_S390 22 -#endif - -#if !defined(AT_SYSINFO_EHDR) -#define AT_SYSINFO_EHDR 33 -#endif - -#if !defined(NT_PRSTATUS) -#define NT_PRSTATUS 1 -#endif - -#if !defined(NT_PRPSINFO) -#define NT_PRPSINFO 3 -#endif - -#if !defined(NT_AUXV) -#define NT_AUXV 6 -#endif - -#if !defined(NT_PRXFPREG) -#define NT_PRXFPREG 0x46e62b7f -#endif - -#if !defined(NT_FPREGSET) -#define NT_FPREGSET 2 -#endif - -#if !defined(SHT_MIPS_DWARF) -#define SHT_MIPS_DWARF 0x7000001e -#endif - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_ELF_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/link.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/link.h deleted file mode 100644 index 0f7d98e75..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/link.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H -#define GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H - -/* Android doesn't provide all the data-structures required in its . - Provide custom version here. */ -#include_next - -// TODO(rmcilroy): Remove this file once the ndk is updated for other -// architectures - crbug.com/358831 -#if !defined(__aarch64__) && !defined(__x86_64__) && \ - !(defined(__mips__) && _MIPS_SIM == _ABI64) - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#if defined(ANDROID) && ANDROID_VERSION <= 20 -struct r_debug { - int r_version; - struct link_map* r_map; - ElfW(Addr) r_brk; - enum { - RT_CONSISTENT, - RT_ADD, - RT_DELETE } r_state; - ElfW(Addr) r_ldbase; -}; - -struct link_map { - ElfW(Addr) l_addr; - char* l_name; - ElfW(Dyn)* l_ld; - struct link_map* l_next; - struct link_map* l_prev; -}; -#endif - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // !defined(__aarch64__) && !defined(__x86_64__) - -#endif /* GOOGLE_BREAKPAD_ANDROID_INCLUDE_LINK_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/sgidefs.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/sgidefs.h deleted file mode 100644 index 33796dcf7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/sgidefs.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H -#define GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H - -#ifdef __mips__ - -// Android doesn't contain sgidefs.h, but does have which -// contains what we need. -#include - -#endif // __mips__ - -#endif // GOOGLE_BREAKPAD_ANDROID_INCLUDE_SGIDEFS_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/stab.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/stab.h deleted file mode 100644 index cd9290215..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/stab.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H - -#include - -#ifdef __BIONIC_HAVE_STAB_H -#include -#else - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#define _STAB_CODE_LIST \ - _STAB_CODE_DEF(UNDF,0x00) \ - _STAB_CODE_DEF(GSYM,0x20) \ - _STAB_CODE_DEF(FNAME,0x22) \ - _STAB_CODE_DEF(FUN,0x24) \ - _STAB_CODE_DEF(STSYM,0x26) \ - _STAB_CODE_DEF(LCSYM,0x28) \ - _STAB_CODE_DEF(MAIN,0x2a) \ - _STAB_CODE_DEF(PC,0x30) \ - _STAB_CODE_DEF(NSYMS,0x32) \ - _STAB_CODE_DEF(NOMAP,0x34) \ - _STAB_CODE_DEF(OBJ,0x38) \ - _STAB_CODE_DEF(OPT,0x3c) \ - _STAB_CODE_DEF(RSYM,0x40) \ - _STAB_CODE_DEF(M2C,0x42) \ - _STAB_CODE_DEF(SLINE,0x44) \ - _STAB_CODE_DEF(DSLINE,0x46) \ - _STAB_CODE_DEF(BSLINE,0x48) \ - _STAB_CODE_DEF(BROWS,0x48) \ - _STAB_CODE_DEF(DEFD,0x4a) \ - _STAB_CODE_DEF(EHDECL,0x50) \ - _STAB_CODE_DEF(MOD2,0x50) \ - _STAB_CODE_DEF(CATCH,0x54) \ - _STAB_CODE_DEF(SSYM,0x60) \ - _STAB_CODE_DEF(SO,0x64) \ - _STAB_CODE_DEF(LSYM,0x80) \ - _STAB_CODE_DEF(BINCL,0x82) \ - _STAB_CODE_DEF(SOL,0x84) \ - _STAB_CODE_DEF(PSYM,0xa0) \ - _STAB_CODE_DEF(EINCL,0xa2) \ - _STAB_CODE_DEF(ENTRY,0xa4) \ - _STAB_CODE_DEF(LBRAC,0xc0) \ - _STAB_CODE_DEF(EXCL,0xc2) \ - _STAB_CODE_DEF(SCOPE,0xc4) \ - _STAB_CODE_DEF(RBRAC,0xe0) \ - _STAB_CODE_DEF(BCOMM,0xe2) \ - _STAB_CODE_DEF(ECOMM,0xe4) \ - _STAB_CODE_DEF(ECOML,0xe8) \ - _STAB_CODE_DEF(NBTEXT,0xf0) \ - _STAB_CODE_DEF(NBDATA,0xf2) \ - _STAB_CODE_DEF(NBBSS,0xf4) \ - _STAB_CODE_DEF(NBSTS,0xf6) \ - _STAB_CODE_DEF(NBLCS,0xf8) \ - _STAB_CODE_DEF(LENG,0xfe) - -enum __stab_debug_code { -#define _STAB_CODE_DEF(x,y) N_##x = y, -_STAB_CODE_LIST -#undef _STAB_CODE_DEF -}; - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // __BIONIC_HAVE_STAB_H - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_STAB_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/procfs.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/procfs.h deleted file mode 100644 index 185124364..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/procfs.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H - -#ifdef __BIONIC_HAVE_SYS_PROCFS_H - -#include_next - -#else - -#include -#include -#if defined (__mips__) -#include -#endif -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#if defined(__x86_64__) || defined(__aarch64__) -typedef unsigned long long elf_greg_t; -#else -typedef unsigned long elf_greg_t; -#endif - -#ifdef __arm__ -#define ELF_NGREG (sizeof(struct user_regs) / sizeof(elf_greg_t)) -#elif defined(__aarch64__) -#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t)) -#elif defined(__mips__) -#define ELF_NGREG 45 -#else -#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) -#endif - -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -struct elf_siginfo { - int si_signo; - int si_code; - int si_errno; -}; - -struct elf_prstatus { - struct elf_siginfo pr_info; - short pr_cursig; - unsigned long pr_sigpend; - unsigned long pr_sighold; - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pd_sid; - struct timeval pr_utime; - struct timeval pr_stime; - struct timeval pr_cutime; - struct timeval pr_cstime; - elf_gregset_t pr_reg; - int pr_fpvalid; -}; - -#define ELF_PRARGSZ 80 - -struct elf_prpsinfo { - char pr_state; - char pr_sname; - char pr_zomb; - char pr_nice; - unsigned long pr_flags; -#ifdef __x86_64__ - unsigned int pr_uid; - unsigned int pr_gid; -#elif defined(__mips__) - __kernel_uid_t pr_uid; - __kernel_gid_t pr_gid; -#else - unsigned short pr_uid; - unsigned short pr_gid; -#endif - int pr_pid; - int pr_ppid; - int pr_pgrp; - int pr_sid; - char pr_fname[16]; - char pr_psargs[ELF_PRARGSZ]; -}; - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // __BIONIC_HAVE_SYS_PROCFS_H - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_SYS_PROCFS_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/signal.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/signal.h deleted file mode 100644 index 20c81e937..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/signal.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H - -#include - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_SIGNAL_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h deleted file mode 100644 index 1eb02a57d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H - -// The purpose of this file is to glue the mismatching headers (Android NDK vs -// glibc) and therefore avoid doing otherwise awkward #ifdefs in the code. -// The following quirks are currently handled by this file: -// - i386: Use the Android NDK but alias user_fxsr_struct > user_fpxregs_struct. -// - aarch64: -// - NDK r10: Add missing user_regs_struct and user_fpsimd_struct structs. -// - NDK r11+: Add missing include -// - Other platforms: Just use the Android NDK unchanged. - -// TODO(primiano): remove these changes after Chromium has stably rolled to -// an NDK with the appropriate fixes. - -#if defined(ANDROID_NDK_MAJOR_VERSION) && ANDROID_NDK_MAJOR_VERSION > 10 -#ifdef __aarch64__ -#include -#endif // __aarch64__ -#endif // defined(ANDROID_NDK_MAJOR_VERSION) && ANDROID_NDK_MAJOR_VERSION > 10 - -#include_next - -#ifdef __i386__ -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus -typedef struct user_fxsr_struct user_fpxregs_struct; -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus -#endif // __i386__ - -#if !defined(ANDROID_NDK_MAJOR_VERSION) || ANDROID_NDK_MAJOR_VERSION == 10 -#ifdef __aarch64__ -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus -struct user_regs_struct { - __u64 regs[31]; - __u64 sp; - __u64 pc; - __u64 pstate; -}; -struct user_fpsimd_struct { - __uint128_t vregs[32]; - __u32 fpsr; - __u32 fpcr; -}; -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus -#endif // __aarch64__ -#endif // defined(ANDROID_NDK_VERSION) && ANDROID_NDK_MAJOR_VERSION == 10 - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/include/ucontext.h b/toolkit/crashreporter/google-breakpad/src/common/android/include/ucontext.h deleted file mode 100644 index 29db8adee..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/include/ucontext.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H - -#include - -#ifdef __BIONIC_UCONTEXT_H -#include -#else - -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// Provided by src/android/common/breakpad_getcontext.S -int breakpad_getcontext(ucontext_t* ucp); - -#define getcontext(x) breakpad_getcontext(x) - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // __BIONIC_UCONTEXT_H - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/testing/include/wchar.h b/toolkit/crashreporter/google-breakpad/src/common/android/testing/include/wchar.h deleted file mode 100644 index 85373fd2a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/testing/include/wchar.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Android doesn't provide wcscasecmp(), so provide an alternative here. -// -// Note that this header is not needed when Breakpad is compiled against -// a recent version of Googletest. It shall be considered for removal once -// src/testing/ is updated to an appropriate revision in the future. - -#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H -#define GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H - -#include_next - -#if !defined(__aarch64__) && !defined(__x86_64__) && \ - !(defined(__mips__) && _MIPS_SIM == _ABI64) - -// This needs to be in an extern "C" namespace, or Googletest will not -// compile against it. -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -static wchar_t inline wcstolower(wchar_t ch) { - if (ch >= L'a' && ch <= L'A') - ch -= L'a' - L'A'; - return ch; -} - -static int inline wcscasecmp(const wchar_t* s1, const wchar_t* s2) { - for (;;) { - wchar_t c1 = wcstolower(*s1); - wchar_t c2 = wcstolower(*s2); - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - if (c1 == L'0') - return 0; - s1++; - s2++; - } -} - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus -#endif - -#endif // GOOGLEBREAKPAD_COMMON_ANDROID_INCLUDE_WCHAR_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/testing/mkdtemp.h b/toolkit/crashreporter/google-breakpad/src/common/android/testing/mkdtemp.h deleted file mode 100644 index b86e2cd78..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/testing/mkdtemp.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// mkdtemp() wasn't declared in until NDK r9b due to a simple -// packaging bug (the function has always been implemented in all versions -// of the C library). This header is provided to build Breakpad with earlier -// NDK revisions (e.g. the one used by Chromium). It may be removed in the -// future once all major projects upgrade to use a more recent NDK. -// -// The reason this is inlined here is to avoid linking a new object file -// into each unit test program (i.e. keep build files simple). - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H - -#include -#include -#include -#include -#include -#include - -// Using a macro renaming trick here is necessary when building against -// NDK r9b. Otherwise the compiler will complain that calls to mkdtemp() -// are ambiguous. -#define mkdtemp breakpad_mkdtemp - -namespace { - -char* breakpad_mkdtemp(char* path) { - if (path == NULL) { - errno = EINVAL; - return NULL; - } - - // 'path' must be terminated with six 'X' - const char kSuffix[] = "XXXXXX"; - const size_t kSuffixLen = strlen(kSuffix); - char* path_end = path + strlen(path); - - if (static_cast(path_end - path) < kSuffixLen || - memcmp(path_end - kSuffixLen, kSuffix, kSuffixLen) != 0) { - errno = EINVAL; - return NULL; - } - - // If 'path' contains a directory separator, check that it exists to - // avoid looping later. - char* sep = strrchr(path, '/'); - if (sep != NULL) { - struct stat st; - int ret; - *sep = '\0'; // temporarily zero-terminate the dirname. - ret = stat(path, &st); - *sep = '/'; // restore full path. - if (ret < 0) - return NULL; - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return NULL; - } - } - - // Loop. On each iteration, replace the XXXXXX suffix with a random - // number. - int tries; - for (tries = 128; tries > 0; tries--) { - int random = rand() % 1000000; - - snprintf(path_end - kSuffixLen, kSuffixLen + 1, "%0d", random); - if (mkdir(path, 0700) == 0) - return path; // Success - - if (errno != EEXIST) - return NULL; - } - - assert(errno == EEXIST); - return NULL; -} - -} // namespace - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_MKDTEMP_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/testing/pthread_fixes.h b/toolkit/crashreporter/google-breakpad/src/common/android/testing/pthread_fixes.h deleted file mode 100644 index 15c6309ec..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/testing/pthread_fixes.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This contains Pthread-related functions not provided by the Android NDK -// but required by the Breakpad unit test. The functions are inlined here -// in a C++ anonymous namespace in order to keep the build files simples. - -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H - -#include - -namespace { - -// Android doesn't provide pthread_barrier_t for now. -#ifndef PTHREAD_BARRIER_SERIAL_THREAD - -// Anything except 0 will do here. -#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345 - -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - unsigned count; -} pthread_barrier_t; - -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* /* barrier_attr */, - unsigned count) { - barrier->count = count; - pthread_mutex_init(&barrier->mutex, NULL); - pthread_cond_init(&barrier->cond, NULL); - return 0; -} - -int pthread_barrier_wait(pthread_barrier_t* barrier) { - // Lock the mutex - pthread_mutex_lock(&barrier->mutex); - // Decrement the count. If this is the first thread to reach 0, wake up - // waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD. - if (--barrier->count == 0) { - // First thread to reach the barrier - pthread_cond_broadcast(&barrier->cond); - pthread_mutex_unlock(&barrier->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - // Otherwise, wait for other threads until the count reaches 0, then - // return 0 to indicate this is not the first thread. - do { - pthread_cond_wait(&barrier->cond, &barrier->mutex); - } while (barrier->count > 0); - - pthread_mutex_unlock(&barrier->mutex); - return 0; -} - -int pthread_barrier_destroy(pthread_barrier_t *barrier) { - barrier->count = 0; - pthread_cond_destroy(&barrier->cond); - pthread_mutex_destroy(&barrier->mutex); - return 0; -} - -#endif // defined(PTHREAD_BARRIER_SERIAL_THREAD) - -int pthread_yield(void) { - sched_yield(); - return 0; -} - -} // namespace - -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h b/toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h deleted file mode 100644 index 1932d5739..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This header can be included either from a C, C++ or Assembly file. -// Its purpose is to contain constants that must match the offsets of -// various fields in ucontext_t. -// -// They should match the definitions from -// src/common/android/include/sys/ucontext.h -// -// Used by src/common/android/breakpad_getcontext.S -// Tested by src/common/android/testing/breakpad_getcontext_unittest.cc - -#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H -#define GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H - -#if defined(__arm__) - -#define MCONTEXT_GREGS_OFFSET 32 -#define UCONTEXT_SIGMASK_OFFSET 104 - -#elif defined(__aarch64__) - -#define UCONTEXT_SIGMASK_OFFSET 40 - -#define MCONTEXT_GREGS_OFFSET 184 -#define MCONTEXT_SP_OFFSET 432 -#define MCONTEXT_PC_OFFSET 440 -#define MCONTEXT_PSTATE_OFFSET 448 -#define MCONTEXT_EXTENSION_OFFSET 464 - -#define FPSIMD_MAGIC 0x46508001 - -#define FPSIMD_CONTEXT_MAGIC_OFFSET 0 -#define FPSIMD_CONTEXT_SIZE_OFFSET 4 -#define FPSIMD_CONTEXT_FPSR_OFFSET 8 -#define FPSIMD_CONTEXT_FPCR_OFFSET 12 -#define FPSIMD_CONTEXT_VREGS_OFFSET 16 -#define FPSIMD_CONTEXT_SIZE 528 - -#define REGISTER_SIZE 8 -#define SIMD_REGISTER_SIZE 16 - -#elif defined(__i386__) - -#define MCONTEXT_GREGS_OFFSET 20 -#define MCONTEXT_GS_OFFSET (MCONTEXT_GREGS_OFFSET + 0*4) -#define MCONTEXT_FS_OFFSET (MCONTEXT_GREGS_OFFSET + 1*4) -#define MCONTEXT_ES_OFFSET (MCONTEXT_GREGS_OFFSET + 2*4) -#define MCONTEXT_DS_OFFSET (MCONTEXT_GREGS_OFFSET + 3*4) -#define MCONTEXT_EDI_OFFSET (MCONTEXT_GREGS_OFFSET + 4*4) -#define MCONTEXT_ESI_OFFSET (MCONTEXT_GREGS_OFFSET + 5*4) -#define MCONTEXT_EBP_OFFSET (MCONTEXT_GREGS_OFFSET + 6*4) -#define MCONTEXT_ESP_OFFSET (MCONTEXT_GREGS_OFFSET + 7*4) -#define MCONTEXT_EBX_OFFSET (MCONTEXT_GREGS_OFFSET + 8*4) -#define MCONTEXT_EDX_OFFSET (MCONTEXT_GREGS_OFFSET + 9*4) -#define MCONTEXT_ECX_OFFSET (MCONTEXT_GREGS_OFFSET + 10*4) -#define MCONTEXT_EAX_OFFSET (MCONTEXT_GREGS_OFFSET + 11*4) -#define MCONTEXT_TRAPNO_OFFSET (MCONTEXT_GREGS_OFFSET + 12*4) -#define MCONTEXT_ERR_OFFSET (MCONTEXT_GREGS_OFFSET + 13*4) -#define MCONTEXT_EIP_OFFSET (MCONTEXT_GREGS_OFFSET + 14*4) -#define MCONTEXT_CS_OFFSET (MCONTEXT_GREGS_OFFSET + 15*4) -#define MCONTEXT_EFL_OFFSET (MCONTEXT_GREGS_OFFSET + 16*4) -#define MCONTEXT_UESP_OFFSET (MCONTEXT_GREGS_OFFSET + 17*4) -#define MCONTEXT_SS_OFFSET (MCONTEXT_GREGS_OFFSET + 18*4) - -#define UCONTEXT_SIGMASK_OFFSET 108 - -#define UCONTEXT_FPREGS_OFFSET 96 -#define UCONTEXT_FPREGS_MEM_OFFSET 116 - -#elif defined(__mips__) - -#if _MIPS_SIM == _ABIO32 -#define MCONTEXT_PC_OFFSET 32 -#define MCONTEXT_GREGS_OFFSET 40 -#define MCONTEXT_FPREGS_OFFSET 296 -#define MCONTEXT_FPC_CSR 556 -#define UCONTEXT_SIGMASK_OFFSET 616 -#else -#define MCONTEXT_GREGS_OFFSET 40 -#define MCONTEXT_FPREGS_OFFSET 296 -#define MCONTEXT_PC_OFFSET 616 -#define MCONTEXT_FPC_CSR 624 -#define UCONTEXT_SIGMASK_OFFSET 640 -#endif - -#elif defined(__x86_64__) - -#define MCONTEXT_GREGS_OFFSET 40 -#define UCONTEXT_SIGMASK_OFFSET 296 - -#define MCONTEXT_GREGS_R8 40 -#define MCONTEXT_GREGS_R9 48 -#define MCONTEXT_GREGS_R10 56 -#define MCONTEXT_GREGS_R11 64 -#define MCONTEXT_GREGS_R12 72 -#define MCONTEXT_GREGS_R13 80 -#define MCONTEXT_GREGS_R14 88 -#define MCONTEXT_GREGS_R15 96 -#define MCONTEXT_GREGS_RDI 104 -#define MCONTEXT_GREGS_RSI 112 -#define MCONTEXT_GREGS_RBP 120 -#define MCONTEXT_GREGS_RBX 128 -#define MCONTEXT_GREGS_RDX 136 -#define MCONTEXT_GREGS_RAX 144 -#define MCONTEXT_GREGS_RCX 152 -#define MCONTEXT_GREGS_RSP 160 -#define MCONTEXT_GREGS_RIP 168 -#define MCONTEXT_FPREGS_PTR 224 -#define MCONTEXT_FPREGS_MEM 304 -#define FPREGS_OFFSET_MXCSR 24 - -#else -#error "This header has not been ported for your CPU" -#endif - -#endif // GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.cc deleted file mode 100644 index 2d1ed983d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.cc +++ /dev/null @@ -1,487 +0,0 @@ - -/* libunwind - a platform-independent unwind library - Copyright 2011 Linaro Limited - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Derived from libunwind, with extensive modifications. - - -#include "common/arm_ex_reader.h" - -#include -#include - -// This file, in conjunction with arm_ex_to_module.cc, translates -// EXIDX unwind information into the same format that Breakpad uses -// for CFI information. Hence Breakpad's CFI unwinding abilities -// also become usable for EXIDX. -// -// See: "Exception Handling ABI for the ARM Architecture", ARM IHI 0038A -// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf - -// EXIDX data is presented in two parts: -// -// * an index table. This contains two words per routine, -// the first of which identifies the routine, and the second -// of which is a reference to the unwind bytecode. If the -// bytecode is very compact -- 3 bytes or less -- it can be -// stored directly in the second word. -// -// * an area containing the unwind bytecodes. - -// General flow is: ExceptionTableInfo::Start iterates over all -// of the index table entries (pairs). For each entry, it: -// -// * calls ExceptionTableInfo::ExtabEntryExtract to copy the bytecode -// out into an intermediate buffer. - -// * uses ExceptionTableInfo::ExtabEntryDecode to parse the intermediate -// buffer. Each bytecode instruction is bundled into a -// arm_ex_to_module::extab_data structure, and handed to .. -// -// * .. ARMExToModule::ImproveStackFrame, which in turn hands it to -// ARMExToModule::TranslateCmd, and that generates the pseudo-CFI -// records that Breakpad stores. - -#define ARM_EXIDX_CANT_UNWIND 0x00000001 -#define ARM_EXIDX_COMPACT 0x80000000 -#define ARM_EXTBL_OP_FINISH 0xb0 -#define ARM_EXIDX_TABLE_LIMIT (255*4) - -namespace arm_ex_reader { - -using arm_ex_to_module::ARM_EXIDX_CMD_FINISH; -using arm_ex_to_module::ARM_EXIDX_CMD_SUB_FROM_VSP; -using arm_ex_to_module::ARM_EXIDX_CMD_ADD_TO_VSP; -using arm_ex_to_module::ARM_EXIDX_CMD_REG_POP; -using arm_ex_to_module::ARM_EXIDX_CMD_REG_TO_SP; -using arm_ex_to_module::ARM_EXIDX_CMD_VFP_POP; -using arm_ex_to_module::ARM_EXIDX_CMD_WREG_POP; -using arm_ex_to_module::ARM_EXIDX_CMD_WCGR_POP; -using arm_ex_to_module::ARM_EXIDX_CMD_RESERVED; -using arm_ex_to_module::ARM_EXIDX_CMD_REFUSED; -using arm_ex_to_module::exidx_entry; -using arm_ex_to_module::ARM_EXIDX_VFP_SHIFT_16; -using arm_ex_to_module::ARM_EXIDX_VFP_FSTMD; -using google_breakpad::MemoryRange; - - -static void* Prel31ToAddr(const void* addr) { - uint32_t offset32 = *reinterpret_cast(addr); - // sign extend offset32[30:0] to 64 bits -- copy bit 30 to positions - // 63:31 inclusive. - uint64_t offset64 = offset32; - if (offset64 & (1ULL << 30)) - offset64 |= 0xFFFFFFFF80000000ULL; - else - offset64 &= 0x000000007FFFFFFFULL; - return ((char*)addr) + (uintptr_t)offset64; -} - - -// Extract unwind bytecode for the function denoted by |entry| into |buf|, -// and return the number of bytes of |buf| written, along with a code -// indicating the outcome. - -ExceptionTableInfo::ExExtractResult ExceptionTableInfo::ExtabEntryExtract( - const struct exidx_entry* entry, - uint8_t* buf, size_t buf_size, - size_t* buf_used) { - MemoryRange mr_out(buf, buf_size); - - *buf_used = 0; - -# define PUT_BUF_U8(_byte) \ - do { if (!mr_out.Covers(*buf_used, 1)) return ExOutBufOverflow; \ - buf[(*buf_used)++] = (_byte); } while (0) - -# define GET_EX_U32(_lval, _addr, _sec_mr) \ - do { if (!(_sec_mr).Covers(reinterpret_cast(_addr) \ - - (_sec_mr).data(), 4)) \ - return ExInBufOverflow; \ - (_lval) = *(reinterpret_cast(_addr)); } while (0) - -# define GET_EXIDX_U32(_lval, _addr) \ - GET_EX_U32(_lval, _addr, mr_exidx_) -# define GET_EXTAB_U32(_lval, _addr) \ - GET_EX_U32(_lval, _addr, mr_extab_) - - uint32_t data; - GET_EXIDX_U32(data, &entry->data); - - // A function can be marked CANT_UNWIND if (eg) it is known to be - // at the bottom of the stack. - if (data == ARM_EXIDX_CANT_UNWIND) - return ExCantUnwind; - - uint32_t pers; // personality number - uint32_t extra; // number of extra data words required - uint32_t extra_allowed; // number of extra data words allowed - uint32_t* extbl_data; // the handler entry, if not inlined - - if (data & ARM_EXIDX_COMPACT) { - // The handler table entry has been inlined into the index table entry. - // In this case it can only be an ARM-defined compact model, since - // bit 31 is 1. Only personalities 0, 1 and 2 are defined for the - // ARM compact model, but 1 and 2 are "Long format" and may require - // extra data words. Hence the allowable personalities here are: - // personality 0, in which case 'extra' has no meaning - // personality 1, with zero extra words - // personality 2, with zero extra words - extbl_data = NULL; - pers = (data >> 24) & 0x0F; - extra = (data >> 16) & 0xFF; - extra_allowed = 0; - } - else { - // The index table entry is a pointer to the handler entry. Note - // that Prel31ToAddr will read the given address, but we already - // range-checked above. - extbl_data = reinterpret_cast(Prel31ToAddr(&entry->data)); - GET_EXTAB_U32(data, extbl_data); - if (!(data & ARM_EXIDX_COMPACT)) { - // This denotes a "generic model" handler. That will involve - // executing arbitary machine code, which is something we - // can't represent here; hence reject it. - return ExCantRepresent; - } - // So we have a compact model representation. Again, 3 possible - // personalities, but this time up to 255 allowable extra words. - pers = (data >> 24) & 0x0F; - extra = (data >> 16) & 0xFF; - extra_allowed = 255; - extbl_data++; - } - - // Now look at the the handler table entry. The first word is - // |data| and subsequent words start at |*extbl_data|. The number - // of extra words to use is |extra|, provided that the personality - // allows extra words. Even if it does, none may be available -- - // extra_allowed is the maximum number of extra words allowed. */ - if (pers == 0) { - // "Su16" in the documentation -- 3 unwinding insn bytes - // |extra| has no meaning here; instead that byte is an unwind-info byte - PUT_BUF_U8(data >> 16); - PUT_BUF_U8(data >> 8); - PUT_BUF_U8(data); - } - else if ((pers == 1 || pers == 2) && extra <= extra_allowed) { - // "Lu16" or "Lu32" respectively -- 2 unwinding insn bytes, - // and up to 255 extra words. - PUT_BUF_U8(data >> 8); - PUT_BUF_U8(data); - for (uint32_t j = 0; j < extra; j++) { - GET_EXTAB_U32(data, extbl_data); - extbl_data++; - PUT_BUF_U8(data >> 24); - PUT_BUF_U8(data >> 16); - PUT_BUF_U8(data >> 8); - PUT_BUF_U8(data >> 0); - } - } - else { - // The entry is invalid. - return ExInvalid; - } - - // Make sure the entry is terminated with "FINISH" - if (*buf_used > 0 && buf[(*buf_used) - 1] != ARM_EXTBL_OP_FINISH) - PUT_BUF_U8(ARM_EXTBL_OP_FINISH); - - return ExSuccess; - -# undef GET_EXTAB_U32 -# undef GET_EXIDX_U32 -# undef GET_U32 -# undef PUT_BUF_U8 -} - - -// Take the unwind information extracted by ExtabEntryExtract -// and parse it into frame-unwind instructions. These are as -// specified in "Table 4, ARM-defined frame-unwinding instructions" -// in the specification document detailed in comments at the top -// of this file. -// -// This reads from |buf[0, +data_size)|. It checks for overruns of -// the input buffer and returns a negative value if that happens, or -// for any other failure cases. It returns zero in case of success. -int ExceptionTableInfo::ExtabEntryDecode(const uint8_t* buf, size_t buf_size) { - if (buf == NULL || buf_size == 0) - return -1; - - MemoryRange mr_in(buf, buf_size); - const uint8_t* buf_initially = buf; - -# define GET_BUF_U8(_lval) \ - do { if (!mr_in.Covers(buf - buf_initially, 1)) return -1; \ - (_lval) = *(buf++); } while (0) - - const uint8_t* end = buf + buf_size; - - while (buf < end) { - struct arm_ex_to_module::extab_data edata; - memset(&edata, 0, sizeof(edata)); - - uint8_t op; - GET_BUF_U8(op); - if ((op & 0xc0) == 0x00) { - // vsp = vsp + (xxxxxx << 2) + 4 - edata.cmd = ARM_EXIDX_CMD_ADD_TO_VSP; - edata.data = (((int)op & 0x3f) << 2) + 4; - } else if ((op & 0xc0) == 0x40) { - // vsp = vsp - (xxxxxx << 2) - 4 - edata.cmd = ARM_EXIDX_CMD_SUB_FROM_VSP; - edata.data = (((int)op & 0x3f) << 2) + 4; - } else if ((op & 0xf0) == 0x80) { - uint8_t op2; - GET_BUF_U8(op2); - if (op == 0x80 && op2 == 0x00) { - // Refuse to unwind - edata.cmd = ARM_EXIDX_CMD_REFUSED; - } else { - // Pop up to 12 integer registers under masks {r15-r12},{r11-r4} - edata.cmd = ARM_EXIDX_CMD_REG_POP; - edata.data = ((op & 0xf) << 8) | op2; - edata.data = edata.data << 4; - } - } else if ((op & 0xf0) == 0x90) { - if (op == 0x9d || op == 0x9f) { - // 9d: Reserved as prefix for ARM register to register moves - // 9f: Reserved as perfix for Intel Wireless MMX reg to reg moves - edata.cmd = ARM_EXIDX_CMD_RESERVED; - } else { - // Set vsp = r[nnnn] - edata.cmd = ARM_EXIDX_CMD_REG_TO_SP; - edata.data = op & 0x0f; - } - } else if ((op & 0xf0) == 0xa0) { - // Pop r4 to r[4+nnn], or - // Pop r4 to r[4+nnn] and r14 or - unsigned end = (op & 0x07); - edata.data = (1 << (end + 1)) - 1; - edata.data = edata.data << 4; - if (op & 0x08) edata.data |= 1 << 14; - edata.cmd = ARM_EXIDX_CMD_REG_POP; - } else if (op == ARM_EXTBL_OP_FINISH) { - // Finish - edata.cmd = ARM_EXIDX_CMD_FINISH; - buf = end; - } else if (op == 0xb1) { - uint8_t op2; - GET_BUF_U8(op2); - if (op2 == 0 || (op2 & 0xf0)) { - // Spare - edata.cmd = ARM_EXIDX_CMD_RESERVED; - } else { - // Pop integer registers under mask {r3,r2,r1,r0} - edata.cmd = ARM_EXIDX_CMD_REG_POP; - edata.data = op2 & 0x0f; - } - } else if (op == 0xb2) { - // vsp = vsp + 0x204 + (uleb128 << 2) - uint64_t offset = 0; - uint8_t byte, shift = 0; - do { - GET_BUF_U8(byte); - offset |= (byte & 0x7f) << shift; - shift += 7; - } while ((byte & 0x80) && buf < end); - edata.data = offset * 4 + 0x204; - edata.cmd = ARM_EXIDX_CMD_ADD_TO_VSP; - } else if (op == 0xb3 || op == 0xc8 || op == 0xc9) { - // b3: Pop VFP regs D[ssss] to D[ssss+cccc], FSTMFDX-ishly - // c8: Pop VFP regs D[16+ssss] to D[16+ssss+cccc], FSTMFDD-ishly - // c9: Pop VFP regs D[ssss] to D[ssss+cccc], FSTMFDD-ishly - edata.cmd = ARM_EXIDX_CMD_VFP_POP; - GET_BUF_U8(edata.data); - if (op == 0xc8) edata.data |= ARM_EXIDX_VFP_SHIFT_16; - if (op != 0xb3) edata.data |= ARM_EXIDX_VFP_FSTMD; - } else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) { - // b8: Pop VFP regs D[8] to D[8+nnn], FSTMFDX-ishly - // d0: Pop VFP regs D[8] to D[8+nnn], FSTMFDD-ishly - edata.cmd = ARM_EXIDX_CMD_VFP_POP; - edata.data = 0x80 | (op & 0x07); - if ((op & 0xf8) == 0xd0) edata.data |= ARM_EXIDX_VFP_FSTMD; - } else if (op >= 0xc0 && op <= 0xc5) { - // Intel Wireless MMX pop wR[10]-wr[10+nnn], nnn != 6,7 - edata.cmd = ARM_EXIDX_CMD_WREG_POP; - edata.data = 0xa0 | (op & 0x07); - } else if (op == 0xc6) { - // Intel Wireless MMX pop wR[ssss] to wR[ssss+cccc] - edata.cmd = ARM_EXIDX_CMD_WREG_POP; - GET_BUF_U8(edata.data); - } else if (op == 0xc7) { - uint8_t op2; - GET_BUF_U8(op2); - if (op2 == 0 || (op2 & 0xf0)) { - // Spare - edata.cmd = ARM_EXIDX_CMD_RESERVED; - } else { - // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0} - edata.cmd = ARM_EXIDX_CMD_WCGR_POP; - edata.data = op2 & 0x0f; - } - } else { - // Spare - edata.cmd = ARM_EXIDX_CMD_RESERVED; - } - - int ret = handler_->ImproveStackFrame(&edata); - if (ret < 0) - return ret; - } - return 0; - -# undef GET_BUF_U8 -} - -void ExceptionTableInfo::Start() { - const struct exidx_entry* start - = reinterpret_cast(mr_exidx_.data()); - const struct exidx_entry* end - = reinterpret_cast(mr_exidx_.data() - + mr_exidx_.length()); - - // Iterate over each of the EXIDX entries (pairs of 32-bit words). - // These occupy the entire .exidx section. - for (const struct exidx_entry* entry = start; entry < end; ++entry) { - // Figure out the code address range that this table entry is - // associated with. - uint32_t addr = (reinterpret_cast(Prel31ToAddr(&entry->addr)) - - mapping_addr_ + loading_addr_) & 0x7fffffff; - uint32_t next_addr; - if (entry < end - 1) { - next_addr = (reinterpret_cast(Prel31ToAddr(&((entry + 1)->addr))) - - mapping_addr_ + loading_addr_) & 0x7fffffff; - } else { - // This is the last EXIDX entry in the sequence, so we don't - // have an address for the start of the next function, to limit - // this one. Instead use the address of the last byte of the - // text section associated with this .exidx section, that we - // have been given. So as to avoid junking up the CFI unwind - // tables with absurdly large address ranges in the case where - // text_last_svma_ is wrong, only use the value if it is nonzero - // and within one page of |addr|. Otherwise assume a length of 1. - // - // In some cases, gcc has been observed to finish the exidx - // section with an entry of length 1 marked CANT_UNWIND, - // presumably exactly for the purpose of giving a definite - // length for the last real entry, without having to look at - // text segment boundaries. - bool plausible = false; - next_addr = addr + 1; - if (text_last_svma_ != 0) { - uint32_t maybe_next_addr = text_last_svma_ + 1; - if (maybe_next_addr > addr && maybe_next_addr - addr <= 4096) { - next_addr = maybe_next_addr; - plausible = true; - } - } - if (!plausible) { - fprintf(stderr, "ExceptionTableInfo: implausible EXIDX last entry size " - "%d, using 1 instead.", (int32_t)(text_last_svma_ - addr)); - } - } - - // Extract the unwind info into |buf|. This might fail for - // various reasons. It involves reading both the .exidx and - // .extab sections. All accesses to those sections are - // bounds-checked. - uint8_t buf[ARM_EXIDX_TABLE_LIMIT]; - size_t buf_used = 0; - ExExtractResult res = ExtabEntryExtract(entry, buf, sizeof(buf), &buf_used); - if (res != ExSuccess) { - // Couldn't extract the unwind info, for some reason. Move on. - switch (res) { - case ExInBufOverflow: - fprintf(stderr, "ExtabEntryExtract: .exidx/.extab section overrun"); - break; - case ExOutBufOverflow: - fprintf(stderr, "ExtabEntryExtract: bytecode buffer overflow"); - break; - case ExCantUnwind: - fprintf(stderr, "ExtabEntryExtract: function is marked CANT_UNWIND"); - break; - case ExCantRepresent: - fprintf(stderr, "ExtabEntryExtract: bytecode can't be represented"); - break; - case ExInvalid: - fprintf(stderr, "ExtabEntryExtract: index table entry is invalid"); - break; - default: - fprintf(stderr, "ExtabEntryExtract: unknown error: %d", (int)res); - break; - } - continue; - } - - // Finally, work through the unwind instructions in |buf| and - // create CFI entries that Breakpad can use. This can also fail. - // First, add a new stack frame entry, into which ExtabEntryDecode - // will write the CFI entries. - if (!handler_->HasStackFrame(addr, next_addr - addr)) { - handler_->AddStackFrame(addr, next_addr - addr); - int ret = ExtabEntryDecode(buf, buf_used); - if (ret < 0) { - handler_->DeleteStackFrame(); - fprintf(stderr, "ExtabEntryDecode: failed with error code: %d", ret); - continue; - } - handler_->SubmitStackFrame(); - } - - } /* iterating over .exidx */ -} - -} // namespace arm_ex_reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.h b/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.h deleted file mode 100644 index 9b54e8a0b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_reader.h +++ /dev/null @@ -1,114 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright 2011 Linaro Limited - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Derived from libunwind, with extensive modifications. - -#ifndef COMMON_ARM_EX_READER_H__ -#define COMMON_ARM_EX_READER_H__ - -#include "common/arm_ex_to_module.h" -#include "common/memory_range.h" - -namespace arm_ex_reader { - -// This class is a reader for ARM unwind information -// from .ARM.exidx and .ARM.extab sections. -class ExceptionTableInfo { - public: - ExceptionTableInfo(const char* exidx, size_t exidx_size, - const char* extab, size_t extab_size, - uint32_t text_last_svma, - arm_ex_to_module::ARMExToModule* handler, - const char* mapping_addr, - uint32_t loading_addr) - : mr_exidx_(google_breakpad::MemoryRange(exidx, exidx_size)), - mr_extab_(google_breakpad::MemoryRange(extab, extab_size)), - text_last_svma_(text_last_svma), - handler_(handler), mapping_addr_(mapping_addr), - loading_addr_(loading_addr) { } - - ~ExceptionTableInfo() { } - - // Parses the entries in .ARM.exidx and possibly - // in .ARM.extab tables, reports what we find to - // arm_ex_to_module::ARMExToModule. - void Start(); - - private: - google_breakpad::MemoryRange mr_exidx_; - google_breakpad::MemoryRange mr_extab_; - uint32_t text_last_svma_; - arm_ex_to_module::ARMExToModule* handler_; - const char* mapping_addr_; - uint32_t loading_addr_; - - enum ExExtractResult { - ExSuccess, // success - ExInBufOverflow, // out-of-range while reading .exidx - ExOutBufOverflow, // output buffer is too small - ExCantUnwind, // this function is marked CANT_UNWIND - ExCantRepresent, // entry valid, but we can't represent it - ExInvalid // entry is invalid - }; - ExExtractResult - ExtabEntryExtract(const struct arm_ex_to_module::exidx_entry* entry, - uint8_t* buf, size_t buf_size, - size_t* buf_used); - - int ExtabEntryDecode(const uint8_t* buf, size_t buf_size); -}; - -} // namespace arm_ex_reader - -#endif // COMMON_ARM_EX_READER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc deleted file mode 100644 index c326744f6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc +++ /dev/null @@ -1,209 +0,0 @@ - -/* libunwind - a platform-independent unwind library - Copyright 2011 Linaro Limited - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Derived from libunwind, with extensive modifications. - -#include "common/arm_ex_to_module.h" - -#include -#include - -// For big-picture comments on how the EXIDX reader works, -// see arm_ex_reader.cc. - -#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f) -#define ARM_EXBUF_COUNT(x) ((x) & 0x0f) -#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x)) - -using google_breakpad::Module; - -namespace arm_ex_to_module { - -static const char* const regnames[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "fps", "cpsr" -}; - -// Translate command from extab_data to command for Module. -int ARMExToModule::TranslateCmd(const struct extab_data* edata, - Module::StackFrameEntry* entry, string& vsp) { - int ret = 0; - switch (edata->cmd) { - case ARM_EXIDX_CMD_FINISH: - /* Copy LR to PC if there isn't currently a rule for PC in force. */ - if (entry->initial_rules.find("pc") - == entry->initial_rules.end()) { - if (entry->initial_rules.find("lr") - == entry->initial_rules.end()) { - entry->initial_rules["pc"] = "lr"; - } else { - entry->initial_rules["pc"] = entry->initial_rules["lr"]; - } - } - break; - case ARM_EXIDX_CMD_SUB_FROM_VSP: - { - char c[16]; - sprintf(c, " %d -", edata->data); - vsp += c; - } - break; - case ARM_EXIDX_CMD_ADD_TO_VSP: - { - char c[16]; - sprintf(c, " %d +", edata->data); - vsp += c; - } - break; - case ARM_EXIDX_CMD_REG_POP: - for (unsigned int i = 0; i < 16; i++) { - if (edata->data & (1 << i)) { - entry->initial_rules[regnames[i]] - = vsp + " ^"; - vsp += " 4 +"; - } - } - /* Set cfa in case the SP got popped. */ - if (edata->data & (1 << 13)) { - vsp = entry->initial_rules["sp"]; - } - break; - case ARM_EXIDX_CMD_REG_TO_SP: { - assert (edata->data < 16); - const char* const regname = regnames[edata->data]; - if (entry->initial_rules.find(regname) == entry->initial_rules.end()) { - entry->initial_rules["sp"] = regname; - } else { - entry->initial_rules["sp"] = entry->initial_rules[regname]; - } - vsp = entry->initial_rules["sp"]; - break; - } - case ARM_EXIDX_CMD_VFP_POP: - /* Don't recover VFP registers, but be sure to adjust the stack - pointer. */ - for (unsigned int i = ARM_EXBUF_START(edata->data); - i <= ARM_EXBUF_END(edata->data); i++) { - vsp += " 8 +"; - } - if (!(edata->data & ARM_EXIDX_VFP_FSTMD)) { - vsp += " 4 +"; - } - break; - case ARM_EXIDX_CMD_WREG_POP: - for (unsigned int i = ARM_EXBUF_START(edata->data); - i <= ARM_EXBUF_END(edata->data); i++) { - vsp += " 8 +"; - } - break; - case ARM_EXIDX_CMD_WCGR_POP: - // Pop wCGR registers under mask {wCGR3,2,1,0}, hence "i < 4" - for (unsigned int i = 0; i < 4; i++) { - if (edata->data & (1 << i)) { - vsp += " 4 +"; - } - } - break; - case ARM_EXIDX_CMD_REFUSED: - case ARM_EXIDX_CMD_RESERVED: - ret = -1; - break; - } - return ret; -} - -bool ARMExToModule::HasStackFrame(uintptr_t addr, size_t size) { - // Invariant: the range [addr,covered) is covered by existing stack - // frame entries. - uintptr_t covered = addr; - while (covered < addr + size) { - const Module::StackFrameEntry *old_entry = - module_->FindStackFrameEntryByAddress(covered); - if (!old_entry) { - return false; - } - covered = old_entry->address + old_entry->size; - } - return true; -} - -void ARMExToModule::AddStackFrame(uintptr_t addr, size_t size) { - stack_frame_entry_ = new Module::StackFrameEntry; - stack_frame_entry_->address = addr; - stack_frame_entry_->size = size; - stack_frame_entry_->initial_rules[".cfa"] = "sp"; - vsp_ = "sp"; -} - -int ARMExToModule::ImproveStackFrame(const struct extab_data* edata) { - return TranslateCmd(edata, stack_frame_entry_, vsp_) ; -} - -void ARMExToModule::DeleteStackFrame() { - delete stack_frame_entry_; -} - -void ARMExToModule::SubmitStackFrame() { - // return address always winds up in pc - stack_frame_entry_->initial_rules[".ra"] - = stack_frame_entry_->initial_rules["pc"]; - // the final value of vsp is the new value of sp - stack_frame_entry_->initial_rules["sp"] = vsp_; - module_->AddStackFrameEntry(stack_frame_entry_); -} - -} // namespace arm_ex_to_module diff --git a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.h deleted file mode 100644 index f413a16a9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.h +++ /dev/null @@ -1,119 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright 2011 Linaro Limited - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Derived from libunwind, with extensive modifications. - -#ifndef COMMON_ARM_EX_TO_MODULE__ -#define COMMON_ARM_EX_TO_MODULE__ - -#include "common/module.h" - -#include - -namespace arm_ex_to_module { - -using google_breakpad::Module; - -typedef enum extab_cmd { - ARM_EXIDX_CMD_FINISH, - ARM_EXIDX_CMD_SUB_FROM_VSP, - ARM_EXIDX_CMD_ADD_TO_VSP, - ARM_EXIDX_CMD_REG_POP, - ARM_EXIDX_CMD_REG_TO_SP, - ARM_EXIDX_CMD_VFP_POP, - ARM_EXIDX_CMD_WREG_POP, - ARM_EXIDX_CMD_WCGR_POP, - ARM_EXIDX_CMD_RESERVED, - ARM_EXIDX_CMD_REFUSED, -} extab_cmd_t; - -struct exidx_entry { - uint32_t addr; - uint32_t data; -}; - -struct extab_data { - extab_cmd_t cmd; - uint32_t data; -}; - -enum extab_cmd_flags { - ARM_EXIDX_VFP_SHIFT_16 = 1 << 16, - ARM_EXIDX_VFP_FSTMD = 1 << 17, // distinguishes FSTMxxD from FSTMxxX -}; - -// Receives information from arm_ex_reader::ExceptionTableInfo -// and adds it to the Module object -class ARMExToModule { - public: - ARMExToModule(Module* module) - : module_(module) { } - ~ARMExToModule() { } - bool HasStackFrame(uintptr_t addr, size_t size); - void AddStackFrame(uintptr_t addr, size_t size); - int ImproveStackFrame(const struct extab_data* edata); - void DeleteStackFrame(); - void SubmitStackFrame(); - private: - Module* module_; - Module::StackFrameEntry* stack_frame_entry_; - string vsp_; - int TranslateCmd(const struct extab_data* edata, - Module::StackFrameEntry* entry, - string& vsp); -}; - -} // namespace arm_ex_to_module - -#endif // COMMON_ARM_EX_TO_MODULE__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/basictypes.h b/toolkit/crashreporter/google-breakpad/src/common/basictypes.h deleted file mode 100644 index 9426c1f6c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/basictypes.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_BASICTYPES_H_ -#define COMMON_BASICTYPES_H_ - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif // DISALLOW_COPY_AND_ASSIGN - -namespace google_breakpad { - -// Used to explicitly mark the return value of a function as unused. If you are -// really sure you don't want to do anything with the return value of a function -// that has been marked with __attribute__((warn_unused_result)), wrap it with -// this. Example: -// -// scoped_ptr my_var = ...; -// if (TakeOwnership(my_var.get()) == SUCCESS) -// ignore_result(my_var.release()); -// -template -inline void ignore_result(const T&) { -} - -} // namespace google_breakpad - -#endif // COMMON_BASICTYPES_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/byte_cursor.h b/toolkit/crashreporter/google-breakpad/src/common/byte_cursor.h deleted file mode 100644 index accd54e0a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/byte_cursor.h +++ /dev/null @@ -1,265 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// byte_cursor.h: Classes for parsing values from a buffer of bytes. -// The ByteCursor class provides a convenient interface for reading -// fixed-size integers of arbitrary endianness, being thorough about -// checking for buffer overruns. - -#ifndef COMMON_BYTE_CURSOR_H_ -#define COMMON_BYTE_CURSOR_H_ - -#include -#include -#include -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -// A buffer holding a series of bytes. -struct ByteBuffer { - ByteBuffer() : start(0), end(0) { } - ByteBuffer(const uint8_t *set_start, size_t set_size) - : start(set_start), end(set_start + set_size) { } - ~ByteBuffer() { }; - - // Equality operators. Useful in unit tests, and when we're using - // ByteBuffers to refer to regions of a larger buffer. - bool operator==(const ByteBuffer &that) const { - return start == that.start && end == that.end; - } - bool operator!=(const ByteBuffer &that) const { - return start != that.start || end != that.end; - } - - // Not C++ style guide compliant, but this definitely belongs here. - size_t Size() const { - assert(start <= end); - return end - start; - } - - const uint8_t *start, *end; -}; - -// A cursor pointing into a ByteBuffer that can parse numbers of various -// widths and representations, strings, and data blocks, advancing through -// the buffer as it goes. All ByteCursor operations check that accesses -// haven't gone beyond the end of the enclosing ByteBuffer. -class ByteCursor { - public: - // Create a cursor reading bytes from the start of BUFFER. By default, the - // cursor reads multi-byte values in little-endian form. - ByteCursor(const ByteBuffer *buffer, bool big_endian = false) - : buffer_(buffer), here_(buffer->start), - big_endian_(big_endian), complete_(true) { } - - // Accessor and setter for this cursor's endianness flag. - bool big_endian() const { return big_endian_; } - void set_big_endian(bool big_endian) { big_endian_ = big_endian; } - - // Accessor and setter for this cursor's current position. The setter - // returns a reference to this cursor. - const uint8_t *here() const { return here_; } - ByteCursor &set_here(const uint8_t *here) { - assert(buffer_->start <= here && here <= buffer_->end); - here_ = here; - return *this; - } - - // Return the number of bytes available to read at the cursor. - size_t Available() const { return size_t(buffer_->end - here_); } - - // Return true if this cursor is at the end of its buffer. - bool AtEnd() const { return Available() == 0; } - - // When used as a boolean value this cursor converts to true if all - // prior reads have been completed, or false if we ran off the end - // of the buffer. - operator bool() const { return complete_; } - - // Read a SIZE-byte integer at this cursor, signed if IS_SIGNED is true, - // unsigned otherwise, using the cursor's established endianness, and set - // *RESULT to the number. If we read off the end of our buffer, clear - // this cursor's complete_ flag, and store a dummy value in *RESULT. - // Return a reference to this cursor. - template - ByteCursor &Read(size_t size, bool is_signed, T *result) { - if (CheckAvailable(size)) { - T v = 0; - if (big_endian_) { - for (size_t i = 0; i < size; i++) - v = (v << 8) + here_[i]; - } else { - // This loop condition looks weird, but size_t is unsigned, so - // decrementing i after it is zero yields the largest size_t value. - for (size_t i = size - 1; i < size; i--) - v = (v << 8) + here_[i]; - } - if (is_signed && size < sizeof(T)) { - size_t sign_bit = (T)1 << (size * 8 - 1); - v = (v ^ sign_bit) - sign_bit; - } - here_ += size; - *result = v; - } else { - *result = (T) 0xdeadbeef; - } - return *this; - } - - // Read an integer, using the cursor's established endianness and - // *RESULT's size and signedness, and set *RESULT to the number. If we - // read off the end of our buffer, clear this cursor's complete_ flag. - // Return a reference to this cursor. - template - ByteCursor &operator>>(T &result) { - bool T_is_signed = (T)-1 < 0; - return Read(sizeof(T), T_is_signed, &result); - } - - // Copy the SIZE bytes at the cursor to BUFFER, and advance this - // cursor to the end of them. If we read off the end of our buffer, - // clear this cursor's complete_ flag, and set *POINTER to NULL. - // Return a reference to this cursor. - ByteCursor &Read(uint8_t *buffer, size_t size) { - if (CheckAvailable(size)) { - memcpy(buffer, here_, size); - here_ += size; - } - return *this; - } - - // Set STR to a copy of the '\0'-terminated string at the cursor. If the - // byte buffer does not contain a terminating zero, clear this cursor's - // complete_ flag, and set STR to the empty string. Return a reference to - // this cursor. - ByteCursor &CString(string *str) { - const uint8_t *end - = static_cast(memchr(here_, '\0', Available())); - if (end) { - str->assign(reinterpret_cast(here_), end - here_); - here_ = end + 1; - } else { - str->clear(); - here_ = buffer_->end; - complete_ = false; - } - return *this; - } - - // Like CString(STR), but extract the string from a fixed-width buffer - // LIMIT bytes long, which may or may not contain a terminating '\0' - // byte. Specifically: - // - // - If there are not LIMIT bytes available at the cursor, clear the - // cursor's complete_ flag and set STR to the empty string. - // - // - Otherwise, if the LIMIT bytes at the cursor contain any '\0' - // characters, set *STR to a copy of the bytes before the first '\0', - // and advance the cursor by LIMIT bytes. - // - // - Otherwise, set *STR to a copy of those LIMIT bytes, and advance the - // cursor by LIMIT bytes. - ByteCursor &CString(string *str, size_t limit) { - if (CheckAvailable(limit)) { - const uint8_t *end - = static_cast(memchr(here_, '\0', limit)); - if (end) - str->assign(reinterpret_cast(here_), end - here_); - else - str->assign(reinterpret_cast(here_), limit); - here_ += limit; - } else { - str->clear(); - } - return *this; - } - - // Set *POINTER to point to the SIZE bytes at the cursor, and advance - // this cursor to the end of them. If SIZE is omitted, don't move the - // cursor. If we read off the end of our buffer, clear this cursor's - // complete_ flag, and set *POINTER to NULL. Return a reference to this - // cursor. - ByteCursor &PointTo(const uint8_t **pointer, size_t size = 0) { - if (CheckAvailable(size)) { - *pointer = here_; - here_ += size; - } else { - *pointer = NULL; - } - return *this; - } - - // Skip SIZE bytes at the cursor. If doing so would advance us off - // the end of our buffer, clear this cursor's complete_ flag, and - // set *POINTER to NULL. Return a reference to this cursor. - ByteCursor &Skip(size_t size) { - if (CheckAvailable(size)) - here_ += size; - return *this; - } - - private: - // If there are at least SIZE bytes available to read from the buffer, - // return true. Otherwise, set here_ to the end of the buffer, set - // complete_ to false, and return false. - bool CheckAvailable(size_t size) { - if (Available() >= size) { - return true; - } else { - here_ = buffer_->end; - complete_ = false; - return false; - } - } - - // The buffer we're reading bytes from. - const ByteBuffer *buffer_; - - // The next byte within buffer_ that we'll read. - const uint8_t *here_; - - // True if we should read numbers in big-endian form; false if we - // should read in little-endian form. - bool big_endian_; - - // True if we've been able to read all we've been asked to. - bool complete_; -}; - -} // namespace google_breakpad - -#endif // COMMON_BYTE_CURSOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/byte_cursor_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/byte_cursor_unittest.cc deleted file mode 100644 index 06bfd89d7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/byte_cursor_unittest.cc +++ /dev/null @@ -1,776 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// byte_cursor_unittest.cc: Unit tests for google_breakpad::ByteBuffer -// and google_breakpad::ByteCursor. - -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/byte_cursor.h" -#include "common/using_std_string.h" - -using google_breakpad::ByteBuffer; -using google_breakpad::ByteCursor; - -TEST(Buffer, SizeOfNothing) { - uint8_t data[1]; - ByteBuffer buffer(data, 0); - EXPECT_EQ(0U, buffer.Size()); -} - -TEST(Buffer, SizeOfSomething) { - uint8_t data[10]; - ByteBuffer buffer(data, sizeof(data)); - EXPECT_EQ(10U, buffer.Size()); -} - -TEST(Extent, AvailableEmpty) { - uint8_t data[1]; - ByteBuffer buffer(data, 0); - ByteCursor cursor(&buffer); - EXPECT_EQ(0U, cursor.Available()); -} - -TEST(Extent, AtEndEmpty) { - uint8_t data[1]; - ByteBuffer buffer(data, 0); - ByteCursor cursor(&buffer); - EXPECT_TRUE(cursor.AtEnd()); -} - -TEST(Extent, AsBoolEmpty) { - uint8_t data[1]; - ByteBuffer buffer(data, 0); - ByteCursor cursor(&buffer); - EXPECT_TRUE(cursor); -} - -TEST(Extent, AvailableSome) { - uint8_t data[10]; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - EXPECT_EQ(10U, cursor.Available()); -} - -TEST(Extent, AtEndSome) { - uint8_t data[10]; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - EXPECT_FALSE(cursor.AtEnd()); - EXPECT_TRUE(cursor.Skip(sizeof(data)).AtEnd()); -} - -TEST(Extent, AsBoolSome) { - uint8_t data[10]; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - EXPECT_TRUE(cursor); - EXPECT_TRUE(cursor.Skip(sizeof(data))); - EXPECT_FALSE(cursor.Skip(1)); -} - -TEST(Extent, Cursor) { - uint8_t data[] = { 0xf7, - 0x9f, 0xbe, - 0x67, 0xfb, 0xd3, 0x58, - 0x6f, 0x36, 0xde, 0xd1, - 0x2a, 0x2a, 0x2a }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - - uint8_t a; - uint16_t b; - uint32_t c; - uint32_t d; - uint8_t stars[3]; - - EXPECT_EQ(data + 0U, cursor.here()); - - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(data + 1U, cursor.here()); - - EXPECT_TRUE(cursor >> b); - EXPECT_EQ(data + 3U, cursor.here()); - - EXPECT_TRUE(cursor >> c); - EXPECT_EQ(data + 7U, cursor.here()); - - EXPECT_TRUE(cursor.Skip(4)); - EXPECT_EQ(data + 11U, cursor.here()); - - EXPECT_TRUE(cursor.Read(stars, 3)); - EXPECT_EQ(data + 14U, cursor.here()); - - EXPECT_FALSE(cursor >> d); - EXPECT_EQ(data + 14U, cursor.here()); -} - -TEST(Extent, SetOffset) { - uint8_t data[] = { 0x5c, 0x79, 0x8c, 0xd5 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - - uint8_t a, b, c, d, e; - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(0x5cU, a); - EXPECT_EQ(data + 1U, cursor.here()); - EXPECT_TRUE(((cursor >> b).set_here(data + 3) >> c).set_here(data + 1) - >> d >> e); - EXPECT_EQ(0x79U, b); - EXPECT_EQ(0xd5U, c); - EXPECT_EQ(0x79U, d); - EXPECT_EQ(0x8cU, e); - EXPECT_EQ(data + 3U, cursor.here()); -} - -TEST(BigEndian, Signed1) { - uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - cursor.set_big_endian(true); - int a, b, c, d, e; - ASSERT_TRUE(cursor - .Read(1, true, &a) - .Read(1, true, &b) - .Read(1, true, &c) - .Read(1, true, &d)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7f, b); - EXPECT_EQ(-0x80, c); - EXPECT_EQ(-1, d); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(1, true, &e)); -} - -TEST(BigEndian, Signed2) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x80, 0x7f, 0xff, - 0x80, 0x00, 0x80, 0x80, 0xff, 0xff, - 0x39, 0xf1, 0x8a, 0xbc, 0x5a, 0xec }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, true); - int a, b, c, d, e, f, g, h, i, j; - ASSERT_TRUE(cursor - .Read(2, true, &a) - .Read(2, true, &b) - .Read(2, true, &c) - .Read(2, true, &d) - .Read(2, true, &e) - .Read(2, true, &f) - .Read(2, true, &g) - .Read(2, true, &h) - .Read(2, true, &i)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x80, b); - EXPECT_EQ(0x7fff, c); - EXPECT_EQ(-0x8000, d); - EXPECT_EQ(-0x7f80, e); - EXPECT_EQ(-1, f); - EXPECT_EQ(0x39f1, g); - EXPECT_EQ(-0x7544, h); - EXPECT_EQ(0x5aec, i); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(2, true, &j)); -} - -TEST(BigEndian, Signed4) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, - 0xb6, 0xb1, 0xff, 0xef, - 0x19, 0x6a, 0xca, 0x46 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - cursor.set_big_endian(true); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(4, true, &a) - .Read(4, true, &b) - .Read(4, true, &c) - .Read(4, true, &d) - .Read(4, true, &e) - .Read(4, true, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffff, b); - EXPECT_EQ(-0x80000000LL, c); - EXPECT_EQ(-1, d); - EXPECT_EQ((int32_t) 0xb6b1ffef, e); - EXPECT_EQ(0x196aca46, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(4, true, &g)); -} - -TEST(BigEndian, Signed8) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x93, 0x20, 0xd5, 0xe9, 0xd2, 0xd5, 0x87, 0x9c, - 0x4e, 0x42, 0x49, 0xd2, 0x7f, 0x84, 0x14, 0xa4 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, true); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(8, true, &a) - .Read(8, true, &b) - .Read(8, true, &c) - .Read(8, true, &d) - .Read(8, true, &e) - .Read(8, true, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffffffffffffLL, b); - EXPECT_EQ(-0x7fffffffffffffffLL - 1, c); - EXPECT_EQ(-1, d); - EXPECT_EQ((int64_t) 0x9320d5e9d2d5879cULL, e); - EXPECT_EQ(0x4e4249d27f8414a4LL, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(8, true, &g)); -} - -TEST(BigEndian, Unsigned1) { - uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - cursor.set_big_endian(true); - int32_t a, b, c, d, e; - ASSERT_TRUE(cursor - .Read(1, false, &a) - .Read(1, false, &b) - .Read(1, false, &c) - .Read(1, false, &d)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7f, b); - EXPECT_EQ(0x80, c); - EXPECT_EQ(0xff, d); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(1, false, &e)); -} - -TEST(BigEndian, Unsigned2) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x80, 0x7f, 0xff, - 0x80, 0x00, 0x80, 0x80, 0xff, 0xff, - 0x39, 0xf1, 0x8a, 0xbc, 0x5a, 0xec }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, true); - int64_t a, b, c, d, e, f, g, h, i, j; - ASSERT_TRUE(cursor - .Read(2, false, &a) - .Read(2, false, &b) - .Read(2, false, &c) - .Read(2, false, &d) - .Read(2, false, &e) - .Read(2, false, &f) - .Read(2, false, &g) - .Read(2, false, &h) - .Read(2, false, &i)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x80, b); - EXPECT_EQ(0x7fff, c); - EXPECT_EQ(0x8000, d); - EXPECT_EQ(0x8080, e); - EXPECT_EQ(0xffff, f); - EXPECT_EQ(0x39f1, g); - EXPECT_EQ(0x8abc, h); - EXPECT_EQ(0x5aec, i); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(2, false, &j)); -} - -TEST(BigEndian, Unsigned4) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, - 0xb6, 0xb1, 0xff, 0xef, - 0x19, 0x6a, 0xca, 0x46 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - cursor.set_big_endian(true); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(4, false, &a) - .Read(4, false, &b) - .Read(4, false, &c) - .Read(4, false, &d) - .Read(4, false, &e) - .Read(4, false, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffff, b); - EXPECT_EQ(0x80000000, c); - EXPECT_EQ(0xffffffff, d); - EXPECT_EQ(0xb6b1ffef, e); - EXPECT_EQ(0x196aca46, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(4, false, &g)); -} - -TEST(BigEndian, Unsigned8) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x93, 0x20, 0xd5, 0xe9, 0xd2, 0xd5, 0x87, 0x9c, - 0x4e, 0x42, 0x49, 0xd2, 0x7f, 0x84, 0x14, 0xa4 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, true); - uint64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(8, false, &a) - .Read(8, false, &b) - .Read(8, false, &c) - .Read(8, false, &d) - .Read(8, false, &e) - .Read(8, false, &f)); - EXPECT_EQ(0U, a); - EXPECT_EQ(0x7fffffffffffffffULL, b); - EXPECT_EQ(0x8000000000000000ULL, c); - EXPECT_EQ(0xffffffffffffffffULL, d); - EXPECT_EQ(0x9320d5e9d2d5879cULL, e); - EXPECT_EQ(0x4e4249d27f8414a4ULL, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(8, false, &g)); -} - -TEST(LittleEndian, Signed1) { - uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int32_t a, b, c, d, e; - ASSERT_TRUE(cursor - .Read(1, true, &a) - .Read(1, true, &b) - .Read(1, true, &c) - .Read(1, true, &d)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7f, b); - EXPECT_EQ(-0x80, c); - EXPECT_EQ(-1, d); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(1, true, &e)); -} - -TEST(LittleEndian, Signed2) { - uint8_t data[] = { 0x00, 0x00, 0x80, 0x00, 0xff, 0x7f, - 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, - 0xf1, 0x39, 0xbc, 0x8a, 0xec, 0x5a }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, false); - int32_t a, b, c, d, e, f, g, h, i, j; - ASSERT_TRUE(cursor - .Read(2, true, &a) - .Read(2, true, &b) - .Read(2, true, &c) - .Read(2, true, &d) - .Read(2, true, &e) - .Read(2, true, &f) - .Read(2, true, &g) - .Read(2, true, &h) - .Read(2, true, &i)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x80, b); - EXPECT_EQ(0x7fff, c); - EXPECT_EQ(-0x8000, d); - EXPECT_EQ(-0x7f80, e); - EXPECT_EQ(-1, f); - EXPECT_EQ(0x39f1, g); - EXPECT_EQ(-0x7544, h); - EXPECT_EQ(0x5aec, i); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(2, true, &j)); -} - -TEST(LittleEndian, Signed4) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x7f, - 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, - 0xef, 0xff, 0xb1, 0xb6, - 0x46, 0xca, 0x6a, 0x19 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(4, true, &a) - .Read(4, true, &b) - .Read(4, true, &c) - .Read(4, true, &d) - .Read(4, true, &e) - .Read(4, true, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffff, b); - EXPECT_EQ(-0x80000000LL, c); - EXPECT_EQ(-1, d); - EXPECT_EQ((int32_t) 0xb6b1ffef, e); - EXPECT_EQ(0x196aca46, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(4, true, &g)); -} - -TEST(LittleEndian, Signed8) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x9c, 0x87, 0xd5, 0xd2, 0xe9, 0xd5, 0x20, 0x93, - 0xa4, 0x14, 0x84, 0x7f, 0xd2, 0x49, 0x42, 0x4e }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer, false); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(8, true, &a) - .Read(8, true, &b) - .Read(8, true, &c) - .Read(8, true, &d) - .Read(8, true, &e) - .Read(8, true, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffffffffffffLL, b); - EXPECT_EQ(-0x7fffffffffffffffLL - 1, c); - EXPECT_EQ(-1, d); - EXPECT_EQ((int64_t) 0x9320d5e9d2d5879cULL, e); - EXPECT_EQ(0x4e4249d27f8414a4LL, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(8, true, &g)); -} - -TEST(LittleEndian, Unsigned1) { - uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int32_t a, b, c, d, e; - ASSERT_TRUE(cursor - .Read(1, false, &a) - .Read(1, false, &b) - .Read(1, false, &c) - .Read(1, false, &d)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7f, b); - EXPECT_EQ(0x80, c); - EXPECT_EQ(0xff, d); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(1, false, &e)); -} - -TEST(LittleEndian, Unsigned2) { - uint8_t data[] = { 0x00, 0x00, 0x80, 0x00, 0xff, 0x7f, - 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, - 0xf1, 0x39, 0xbc, 0x8a, 0xec, 0x5a }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int32_t a, b, c, d, e, f, g, h, i, j; - ASSERT_TRUE(cursor - .Read(2, false, &a) - .Read(2, false, &b) - .Read(2, false, &c) - .Read(2, false, &d) - .Read(2, false, &e) - .Read(2, false, &f) - .Read(2, false, &g) - .Read(2, false, &h) - .Read(2, false, &i)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x80, b); - EXPECT_EQ(0x7fff, c); - EXPECT_EQ(0x8000, d); - EXPECT_EQ(0x8080, e); - EXPECT_EQ(0xffff, f); - EXPECT_EQ(0x39f1, g); - EXPECT_EQ(0x8abc, h); - EXPECT_EQ(0x5aec, i); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(2, false, &j)); -} - -TEST(LittleEndian, Unsigned4) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x7f, - 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, - 0xef, 0xff, 0xb1, 0xb6, - 0x46, 0xca, 0x6a, 0x19 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(4, false, &a) - .Read(4, false, &b) - .Read(4, false, &c) - .Read(4, false, &d) - .Read(4, false, &e) - .Read(4, false, &f)); - EXPECT_EQ(0, a); - EXPECT_EQ(0x7fffffff, b); - EXPECT_EQ(0x80000000, c); - EXPECT_EQ(0xffffffff, d); - EXPECT_EQ(0xb6b1ffef, e); - EXPECT_EQ(0x196aca46, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(4, false, &g)); -} - -TEST(LittleEndian, Unsigned8) { - uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x9c, 0x87, 0xd5, 0xd2, 0xe9, 0xd5, 0x20, 0x93, - 0xa4, 0x14, 0x84, 0x7f, 0xd2, 0x49, 0x42, 0x4e }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - uint64_t a, b, c, d, e, f, g; - ASSERT_TRUE(cursor - .Read(8, false, &a) - .Read(8, false, &b) - .Read(8, false, &c) - .Read(8, false, &d) - .Read(8, false, &e) - .Read(8, false, &f)); - EXPECT_EQ(0U, a); - EXPECT_EQ(0x7fffffffffffffffULL, b); - EXPECT_EQ(0x8000000000000000ULL, c); - EXPECT_EQ(0xffffffffffffffffULL, d); - EXPECT_EQ(0x9320d5e9d2d5879cULL, e); - EXPECT_EQ(0x4e4249d27f8414a4ULL, f); - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor.Read(8, false, &g)); -} - -TEST(Extractor, Signed1) { - uint8_t data[] = { 0xfd }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int8_t a; - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(-3, a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Signed2) { - uint8_t data[] = { 0x13, 0xcd }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int16_t a; - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(-13037, a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Signed4) { - uint8_t data[] = { 0xd2, 0xe4, 0x53, 0xe9 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - int32_t a; - // For some reason, G++ 4.4.1 complains: - // warning: array subscript is above array bounds - // in ByteCursor::Read(size_t, bool, T *) as it inlines this call, but - // I'm not able to see how such a reference would occur. - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(-380377902, a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Unsigned1) { - uint8_t data[] = { 0xfd }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - uint8_t a; - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(0xfd, a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Unsigned2) { - uint8_t data[] = { 0x13, 0xcd }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - uint16_t a; - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(0xcd13, a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Unsigned4) { - uint8_t data[] = { 0xd2, 0xe4, 0x53, 0xe9 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - uint32_t a; - // For some reason, G++ 4.4.1 complains: - // warning: array subscript is above array bounds - // in ByteCursor::Read(size_t, bool, T *) as it inlines this call, but - // I'm not able to see how such a reference would occur. - EXPECT_TRUE(cursor >> a); - EXPECT_EQ(0xe953e4d2, a); - EXPECT_FALSE(cursor >> a); - EXPECT_FALSE(cursor >> a); -} - -TEST(Extractor, Mixed) { - uint8_t data[] = { 0x42, - 0x25, 0x0b, - 0x3d, 0x25, 0xed, 0x2a, - 0xec, 0x16, 0x9e, 0x14, 0x61, 0x5b, 0x2c, 0xcf, - 0xd8, - 0x22, 0xa5, - 0x3a, 0x02, 0x6a, 0xd7, - 0x93, 0x2a, 0x2d, 0x8d, 0xb4, 0x95, 0xe0, 0xc6 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - cursor.set_big_endian(true); - - uint8_t a; - uint16_t b; - uint32_t c; - uint64_t d; - int8_t e; - int16_t f; - int32_t g; - int64_t h; - int z; - EXPECT_FALSE(cursor.AtEnd()); - EXPECT_TRUE(cursor >> a >> b >> c >> d >> e >> f >> g >> h); - EXPECT_EQ(0x42U, a); - EXPECT_EQ(0x250bU, b); - EXPECT_EQ(0x3d25ed2aU, c); - EXPECT_EQ(0xec169e14615b2ccfULL, d); - EXPECT_EQ(-40, e); - EXPECT_EQ(0x22a5, f); - EXPECT_EQ(0x3a026ad7, g); - EXPECT_EQ(-7842405714468937530LL, h); - - EXPECT_TRUE(cursor.AtEnd()); - EXPECT_FALSE(cursor >> z); -} - -TEST(Strings, Zero) { - uint8_t data[] = { 0xa6 }; - ByteBuffer buffer(data, 0); - ByteCursor cursor(&buffer); - - uint8_t received[1]; - received[0] = 0xc2; - EXPECT_TRUE(cursor.Read(received, 0)); - EXPECT_EQ(0xc2U, received[0]); -} - -TEST(Strings, Some) { - uint8_t data[] = { 0x5d, 0x31, 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xbb }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - - uint8_t received[7] = { 0xa7, 0xf7, 0x43, 0x0c, 0x27, 0xea, 0xed }; - EXPECT_TRUE(cursor.Skip(2).Read(received, 5)); - uint8_t expected[7] = { 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xea, 0xed }; - EXPECT_TRUE(memcmp(received, expected, 7) == 0); -} - -TEST(Strings, TooMuch) { - uint8_t data[] = { 0x5d, 0x31, 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xbb }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - - uint8_t received1[3]; - uint8_t received2[3]; - uint8_t received3[3]; - EXPECT_FALSE(cursor - .Read(received1, 3) - .Read(received2, 3) - .Read(received3, 3)); - uint8_t expected1[3] = { 0x5d, 0x31, 0x09 }; - uint8_t expected2[3] = { 0xa6, 0x2e, 0x2c }; - - EXPECT_TRUE(memcmp(received1, expected1, 3) == 0); - EXPECT_TRUE(memcmp(received2, expected2, 3) == 0); -} - -TEST(Strings, PointTo) { - uint8_t data[] = { 0x83, 0x80, 0xb4, 0x38, 0x00, 0x2c, 0x0a, 0x27 }; - ByteBuffer buffer(data, sizeof(data)); - ByteCursor cursor(&buffer); - - const uint8_t *received1; - const uint8_t *received2; - const uint8_t *received3; - const uint8_t *received4; - EXPECT_FALSE(cursor - .PointTo(&received1, 3) - .PointTo(&received2, 3) - .PointTo(&received3) - .PointTo(&received4, 3)); - EXPECT_EQ(data + 0, received1); - EXPECT_EQ(data + 3, received2); - EXPECT_EQ(data + 6, received3); - EXPECT_EQ(NULL, received4); -} - -TEST(Strings, CString) { - uint8_t data[] = "abc\0\0foo"; - ByteBuffer buffer(data, sizeof(data) - 1); // don't include terminating '\0' - ByteCursor cursor(&buffer); - - string a, b, c; - EXPECT_TRUE(cursor.CString(&a).CString(&b)); - EXPECT_EQ("abc", a); - EXPECT_EQ("", b); - EXPECT_FALSE(cursor.CString(&c)); - EXPECT_EQ("", c); - EXPECT_TRUE(cursor.AtEnd()); -} - -TEST(Strings, CStringLimit) { - uint8_t data[] = "abcdef\0\0foobar"; - ByteBuffer buffer(data, sizeof(data) - 1); // don't include terminating '\0' - ByteCursor cursor(&buffer); - - string a, b, c, d, e; - - EXPECT_TRUE(cursor.CString(&a, 3)); - EXPECT_EQ("abc", a); - - EXPECT_TRUE(cursor.CString(&b, 0)); - EXPECT_EQ("", b); - - EXPECT_TRUE(cursor.CString(&c, 6)); - EXPECT_EQ("def", c); - - EXPECT_TRUE(cursor.CString(&d, 4)); - EXPECT_EQ("ooba", d); - - EXPECT_FALSE(cursor.CString(&e, 4)); - EXPECT_EQ("", e); - - EXPECT_TRUE(cursor.AtEnd()); -} - -// uint8_t data[] = { 0xa6, 0x54, 0xdf, 0x67, 0x51, 0x43, 0xac, 0xf1 }; -// ByteBuffer buffer(data, sizeof(data)); diff --git a/toolkit/crashreporter/google-breakpad/src/common/common.gyp b/toolkit/crashreporter/google-breakpad/src/common/common.gyp deleted file mode 100644 index 08772bf75..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/common.gyp +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'target_defaults': { - 'target_conditions': [ - ['OS=="mac"', { - 'defines': ['HAVE_MACH_O_NLIST_H'], - }], - ['OS=="linux"', { - 'defines': ['HAVE_A_OUT_H'], - }], - ['OS!="android"', {'sources/': [['exclude', '(^|/)android/']]}], - ['OS!="linux"', {'sources/': [['exclude', '(^|/)linux/']]}], - ['OS!="mac"', {'sources/': [['exclude', '(^|/)mac/']]}], - ['OS!="solaris"', {'sources/': [['exclude', '(^|/)solaris/']]}], - ['OS!="win"', {'sources/': [['exclude', '(^|/)windows/']]}], - ], - }, - 'targets': [ - { - 'target_name': 'common', - 'type': 'static_library', - 'sources': [ - 'android/breakpad_getcontext.S', - 'android/include/elf.h', - 'android/include/link.h', - 'android/include/sgidefs.h', - 'android/include/stab.h', - 'android/include/sys/procfs.h', - 'android/include/sys/signal.h', - 'android/include/sys/user.h', - 'android/include/ucontext.h', - 'android/testing/include/wchar.h', - 'android/testing/mkdtemp.h', - 'android/testing/pthread_fixes.h', - 'android/ucontext_constants.h', - 'basictypes.h', - 'byte_cursor.h', - 'convert_UTF.c', - 'convert_UTF.h', - 'dwarf/bytereader-inl.h', - 'dwarf/bytereader.cc', - 'dwarf/bytereader.h', - 'dwarf/cfi_assembler.cc', - 'dwarf/cfi_assembler.h', - 'dwarf/dwarf2diehandler.cc', - 'dwarf/dwarf2diehandler.h', - 'dwarf/dwarf2enums.h', - 'dwarf/dwarf2reader.cc', - 'dwarf/dwarf2reader.h', - 'dwarf/dwarf2reader_test_common.h', - 'dwarf/elf_reader.cc', - 'dwarf/elf_reader.h', - 'dwarf/functioninfo.cc', - 'dwarf/functioninfo.h', - 'dwarf/line_state_machine.h', - 'dwarf/types.h', - 'dwarf_cfi_to_module.cc', - 'dwarf_cfi_to_module.h', - 'dwarf_cu_to_module.cc', - 'dwarf_cu_to_module.h', - 'dwarf_line_to_module.cc', - 'dwarf_line_to_module.h', - 'language.cc', - 'language.h', - 'linux/crc32.cc', - 'linux/crc32.h', - 'linux/dump_symbols.cc', - 'linux/dump_symbols.h', - 'linux/eintr_wrapper.h', - 'linux/elf_core_dump.cc', - 'linux/elf_core_dump.h', - 'linux/elf_gnu_compat.h', - 'linux/elf_symbols_to_module.cc', - 'linux/elf_symbols_to_module.h', - 'linux/elfutils-inl.h', - 'linux/elfutils.cc', - 'linux/elfutils.h', - 'linux/file_id.cc', - 'linux/file_id.h', - 'linux/google_crashdump_uploader.cc', - 'linux/google_crashdump_uploader.h', - 'linux/guid_creator.cc', - 'linux/guid_creator.h', - 'linux/http_upload.cc', - 'linux/http_upload.h', - 'linux/ignore_ret.h', - 'linux/libcurl_wrapper.cc', - 'linux/libcurl_wrapper.h', - 'linux/linux_libc_support.cc', - 'linux/linux_libc_support.h', - 'linux/memory_mapped_file.cc', - 'linux/memory_mapped_file.h', - 'linux/safe_readlink.cc', - 'linux/safe_readlink.h', - 'linux/synth_elf.cc', - 'linux/synth_elf.h', - 'mac/arch_utilities.cc', - 'mac/arch_utilities.h', - 'mac/bootstrap_compat.cc', - 'mac/bootstrap_compat.h', - 'mac/byteswap.h', - 'mac/dump_syms.h', - 'mac/dump_syms.cc', - 'mac/file_id.cc', - 'mac/file_id.h', - 'mac/GTMDefines.h', - 'mac/GTMLogger.h', - 'mac/GTMLogger.m', - 'mac/HTTPMultipartUpload.h', - 'mac/HTTPMultipartUpload.m', - 'mac/MachIPC.h', - 'mac/MachIPC.mm', - 'mac/macho_id.cc', - 'mac/macho_id.h', - 'mac/macho_reader.cc', - 'mac/macho_reader.h', - 'mac/macho_utilities.cc', - 'mac/macho_utilities.h', - 'mac/macho_walker.cc', - 'mac/macho_walker.h', - 'mac/scoped_task_suspend-inl.h', - 'mac/string_utilities.cc', - 'mac/string_utilities.h', - 'mac/super_fat_arch.h', - 'md5.cc', - 'md5.h', - 'memory.h', - 'memory_range.h', - 'module.cc', - 'module.h', - 'scoped_ptr.h', - 'simple_string_dictionary.cc', - 'simple_string_dictionary.h', - 'solaris/dump_symbols.cc', - 'solaris/dump_symbols.h', - 'solaris/file_id.cc', - 'solaris/file_id.h', - 'solaris/guid_creator.cc', - 'solaris/guid_creator.h', - 'solaris/message_output.h', - 'stabs_reader.cc', - 'stabs_reader.h', - 'stabs_to_module.cc', - 'stabs_to_module.h', - 'string_conversion.cc', - 'string_conversion.h', - 'symbol_data.h', - 'test_assembler.cc', - 'test_assembler.h', - 'unordered.h', - 'using_std_string.h', - 'windows/common_windows.gyp', - 'windows/dia_util.cc', - 'windows/dia_util.h', - 'windows/guid_string.cc', - 'windows/guid_string.h', - 'windows/http_upload.cc', - 'windows/http_upload.h', - 'windows/omap.cc', - 'windows/omap.h', - 'windows/omap_internal.h', - 'windows/pdb_source_line_writer.cc', - 'windows/pdb_source_line_writer.h', - 'windows/string_utils-inl.h', - 'windows/string_utils.cc', - ], - 'include_dirs': [ - '..', - ], - }, - { - 'target_name': 'common_unittests', - 'type': 'executable', - 'sources': [ - 'android/breakpad_getcontext_unittest.cc', - 'byte_cursor_unittest.cc', - 'dwarf/bytereader_unittest.cc', - 'dwarf/dwarf2diehandler_unittest.cc', - 'dwarf/dwarf2reader_cfi_unittest.cc', - 'dwarf/dwarf2reader_die_unittest.cc', - 'dwarf_cfi_to_module_unittest.cc', - 'dwarf_cu_to_module_unittest.cc', - 'dwarf_line_to_module_unittest.cc', - 'linux/dump_symbols_unittest.cc', - 'linux/elf_core_dump_unittest.cc', - 'linux/elf_symbols_to_module_unittest.cc', - 'linux/file_id_unittest.cc', - 'linux/google_crashdump_uploader_test.cc', - 'linux/linux_libc_support_unittest.cc', - 'linux/memory_mapped_file_unittest.cc', - 'linux/safe_readlink_unittest.cc', - 'linux/synth_elf_unittest.cc', - 'linux/tests/auto_testfile.h', - 'linux/tests/crash_generator.cc', - 'linux/tests/crash_generator.h', - 'mac/macho_reader_unittest.cc', - 'memory_range_unittest.cc', - 'memory_unittest.cc', - 'module_unittest.cc', - 'simple_string_dictionary_unittest.cc', - 'stabs_reader_unittest.cc', - 'stabs_to_module_unittest.cc', - 'test_assembler_unittest.cc', - 'tests/auto_tempdir.h', - 'tests/file_utils.cc', - 'tests/file_utils.h', - 'windows/omap_unittest.cc', - ], - 'include_dirs': [ - '..', - ], - 'dependencies': [ - 'common', - '../build/testing.gypi:gmock_main', - '../build/testing.gypi:gmock', - '../build/testing.gypi:gtest', - ], - 'libraries': [ - '-ldl', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.c b/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.c deleted file mode 100644 index 12a3c8917..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright © 1991-2015 Unicode, Inc. All rights reserved. - * Distributed under the Terms of Use in - * http://www.unicode.org/copyright.html. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of the Unicode data files and any associated documentation - * (the "Data Files") or Unicode software and any associated documentation - * (the "Software") to deal in the Data Files or Software - * without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, and/or sell copies of - * the Data Files or Software, and to permit persons to whom the Data Files - * or Software are furnished to do so, provided that - * (a) this copyright and permission notice appear with all copies - * of the Data Files or Software, - * (b) this copyright and permission notice appear in associated - * documentation, and - * (c) there is clear notice in each modified Data File or in the Software - * as well as in the documentation associated with the Data File(s) or - * Software that the data or software has been modified. - * - * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL - * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THE DATA FILES OR SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in these Data Files or Software without prior - * written authorization of the copyright holder. - */ - -/* --------------------------------------------------------------------- - -Conversions between UTF32, UTF-16, and UTF-8. Source code file. -Author: Mark E. Davis, 1994. -Rev History: Rick McGowan, fixes & updates May 2001. -Sept 2001: fixed const & error conditions per -mods suggested by S. Parent & A. Lillich. -June 2002: Tim Dodd added detection and handling of incomplete -source sequences, enhanced error detection, added casts -to eliminate compiler warnings. -July 2003: slight mods to back out aggressive FFFE detection. -Jan 2004: updated switches in from-UTF8 conversions. -Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - -See the header file "ConvertUTF.h" for complete documentation. - ------------------------------------------------------------------------- */ - - -#include "convert_UTF.h" -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF - -#ifndef false -#define false 0 -#endif -#ifndef true -#define true 1 -#endif - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 (const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } -*sourceStart = source; -*targetStart = target; -return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 (const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG - if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); - } -#endif - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. -* Constants have been gathered. Loops & conditionals have been removed as -* much as possible for efficiency, in favor of drop-through switches. -* (See "Note A" at the bottom of the file for equivalent code.) -* If your compiler supports it, the "isLegalUTF8" call can be turned -* into an inline function. -*/ - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF8 (const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } -*sourceStart = source; -*targetStart = target; -return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (source+length > sourceEnd) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 (const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } -*sourceStart = source; -*targetStart = target; -return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 (const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } -*sourceStart = source; -*targetStart = target; -return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 (const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - -Note A. -The fall-through switches in UTF-8 reading code save a -temp variable, some decrements & conditionals. The switches -are equivalent to the following loop: -{ - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); -} -In UTF-8 writing code, the switches on "bytesToWrite" are -similarly unrolled loops. - ---------------------------------------------------------------------- */ diff --git a/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.h b/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.h deleted file mode 100644 index 644d09950..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright © 1991-2015 Unicode, Inc. All rights reserved. - * Distributed under the Terms of Use in - * http://www.unicode.org/copyright.html. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of the Unicode data files and any associated documentation - * (the "Data Files") or Unicode software and any associated documentation - * (the "Software") to deal in the Data Files or Software - * without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, and/or sell copies of - * the Data Files or Software, and to permit persons to whom the Data Files - * or Software are furnished to do so, provided that - * (a) this copyright and permission notice appear with all copies - * of the Data Files or Software, - * (b) this copyright and permission notice appear in associated - * documentation, and - * (c) there is clear notice in each modified Data File or in the Software - * as well as in the documentation associated with the Data File(s) or - * Software that the data or software has been modified. - * - * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL - * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THE DATA FILES OR SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in these Data Files or Software without prior - * written authorization of the copyright holder. - */ - -#ifndef COMMON_CONVERT_UTF_H_ -#define COMMON_CONVERT_UTF_H_ - -/* --------------------------------------------------------------------- - -Conversions between UTF32, UTF-16, and UTF-8. Header file. - -Several funtions are included here, forming a complete set of -conversions between the three formats. UTF-7 is not included -here, but is handled in a separate source file. - -Each of these routines takes pointers to input buffers and output -buffers. The input buffers are const. - -Each routine converts the text between *sourceStart and sourceEnd, -putting the result into the buffer between *targetStart and -targetEnd. Note: the end pointers are *after* the last item: e.g. -*(sourceEnd - 1) is the last item. - -The return result indicates whether the conversion was successful, -and if not, whether the problem was in the source or target buffers. -(Only the first encountered problem is indicated.) - -After the conversion, *sourceStart and *targetStart are both -updated to point to the end of last text successfully converted in -the respective buffers. - -Input parameters: -sourceStart - pointer to a pointer to the source buffer. -The contents of this are modified on return so that -it points at the next thing to be converted. -targetStart - similarly, pointer to pointer to the target buffer. -sourceEnd, targetEnd - respectively pointers to the ends of the -two buffers, for overflow checking only. - -These conversion functions take a ConversionFlags argument. When this -flag is set to strict, both irregular sequences and isolated surrogates -will cause an error. When the flag is set to lenient, both irregular -sequences and isolated surrogates are converted. - -Whether the flag is strict or lenient, all illegal sequences will cause -an error return. This includes sequences such as: , , -or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code -must check for illegal sequences. - -When the flag is set to lenient, characters over 0x10FFFF are converted -to the replacement character; otherwise (when the flag is set to strict) -they constitute an error. - -Output parameters: -The value "sourceIllegal" is returned from some routines if the input -sequence is malformed. When "sourceIllegal" is returned, the source -value will point to the illegal value that caused the problem. E.g., -in UTF-8 when a sequence is malformed, it points to the start of the -malformed sequence. - -Author: Mark E. Davis, 1994. -Rev History: Rick McGowan, fixes & updates May 2001. -Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------- -The following 4 definitions are compiler-specific. -The C standard does not guarantee that wchar_t has at least -16 bits, so wchar_t is no less portable than unsigned short! -All should be unsigned values to avoid sign extension during -bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned long UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult ConvertUTF8toUTF16 (const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF8 (const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF8toUTF32 (const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF8 (const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF32 (const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF16 (const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -#ifdef __cplusplus -} -#endif - -/* --------------------------------------------------------------------- */ - -#endif // COMMON_CONVERT_UTF_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader-inl.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader-inl.h deleted file mode 100644 index 42c92f943..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader-inl.h +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2006 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__ -#define UTIL_DEBUGINFO_BYTEREADER_INL_H__ - -#include "common/dwarf/bytereader.h" - -#include -#include - -namespace dwarf2reader { - -inline uint8 ByteReader::ReadOneByte(const uint8_t *buffer) const { - return buffer[0]; -} - -inline uint16 ByteReader::ReadTwoBytes(const uint8_t *buffer) const { - const uint16 buffer0 = buffer[0]; - const uint16 buffer1 = buffer[1]; - if (endian_ == ENDIANNESS_LITTLE) { - return buffer0 | buffer1 << 8; - } else { - return buffer1 | buffer0 << 8; - } -} - -inline uint64 ByteReader::ReadFourBytes(const uint8_t *buffer) const { - const uint32 buffer0 = buffer[0]; - const uint32 buffer1 = buffer[1]; - const uint32 buffer2 = buffer[2]; - const uint32 buffer3 = buffer[3]; - if (endian_ == ENDIANNESS_LITTLE) { - return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24; - } else { - return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24; - } -} - -inline uint64 ByteReader::ReadEightBytes(const uint8_t *buffer) const { - const uint64 buffer0 = buffer[0]; - const uint64 buffer1 = buffer[1]; - const uint64 buffer2 = buffer[2]; - const uint64 buffer3 = buffer[3]; - const uint64 buffer4 = buffer[4]; - const uint64 buffer5 = buffer[5]; - const uint64 buffer6 = buffer[6]; - const uint64 buffer7 = buffer[7]; - if (endian_ == ENDIANNESS_LITTLE) { - return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 | - buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56; - } else { - return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 | - buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56; - } -} - -// Read an unsigned LEB128 number. Each byte contains 7 bits of -// information, plus one bit saying whether the number continues or -// not. - -inline uint64 ByteReader::ReadUnsignedLEB128(const uint8_t *buffer, - size_t* len) const { - uint64 result = 0; - size_t num_read = 0; - unsigned int shift = 0; - uint8_t byte; - - do { - byte = *buffer++; - num_read++; - - result |= (static_cast(byte & 0x7f)) << shift; - - shift += 7; - - } while (byte & 0x80); - - *len = num_read; - - return result; -} - -// Read a signed LEB128 number. These are like regular LEB128 -// numbers, except the last byte may have a sign bit set. - -inline int64 ByteReader::ReadSignedLEB128(const uint8_t *buffer, - size_t* len) const { - int64 result = 0; - unsigned int shift = 0; - size_t num_read = 0; - uint8_t byte; - - do { - byte = *buffer++; - num_read++; - result |= (static_cast(byte & 0x7f) << shift); - shift += 7; - } while (byte & 0x80); - - if ((shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -((static_cast(1)) << shift); - *len = num_read; - return result; -} - -inline uint64 ByteReader::ReadOffset(const uint8_t *buffer) const { - assert(this->offset_reader_); - return (this->*offset_reader_)(buffer); -} - -inline uint64 ByteReader::ReadAddress(const uint8_t *buffer) const { - assert(this->address_reader_); - return (this->*address_reader_)(buffer); -} - -inline void ByteReader::SetCFIDataBase(uint64 section_base, - const uint8_t *buffer_base) { - section_base_ = section_base; - buffer_base_ = buffer_base; - have_section_base_ = true; -} - -inline void ByteReader::SetTextBase(uint64 text_base) { - text_base_ = text_base; - have_text_base_ = true; -} - -inline void ByteReader::SetDataBase(uint64 data_base) { - data_base_ = data_base; - have_data_base_ = true; -} - -inline void ByteReader::SetFunctionBase(uint64 function_base) { - function_base_ = function_base; - have_function_base_ = true; -} - -inline void ByteReader::ClearFunctionBase() { - have_function_base_ = false; -} - -} // namespace dwarf2reader - -#endif // UTIL_DEBUGINFO_BYTEREADER_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.cc deleted file mode 100644 index 14b43adb8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.cc +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/bytereader.h" - -namespace dwarf2reader { - -ByteReader::ByteReader(enum Endianness endian) - :offset_reader_(NULL), address_reader_(NULL), endian_(endian), - address_size_(0), offset_size_(0), - have_section_base_(), have_text_base_(), have_data_base_(), - have_function_base_() { } - -ByteReader::~ByteReader() { } - -void ByteReader::SetOffsetSize(uint8 size) { - offset_size_ = size; - assert(size == 4 || size == 8); - if (size == 4) { - this->offset_reader_ = &ByteReader::ReadFourBytes; - } else { - this->offset_reader_ = &ByteReader::ReadEightBytes; - } -} - -void ByteReader::SetAddressSize(uint8 size) { - address_size_ = size; - assert(size == 4 || size == 8); - if (size == 4) { - this->address_reader_ = &ByteReader::ReadFourBytes; - } else { - this->address_reader_ = &ByteReader::ReadEightBytes; - } -} - -uint64 ByteReader::ReadInitialLength(const uint8_t *start, size_t* len) { - const uint64 initial_length = ReadFourBytes(start); - start += 4; - - // In DWARF2/3, if the initial length is all 1 bits, then the offset - // size is 8 and we need to read the next 8 bytes for the real length. - if (initial_length == 0xffffffff) { - SetOffsetSize(8); - *len = 12; - return ReadOffset(start); - } else { - SetOffsetSize(4); - *len = 4; - } - return initial_length; -} - -bool ByteReader::ValidEncoding(DwarfPointerEncoding encoding) const { - if (encoding == DW_EH_PE_omit) return true; - if (encoding == DW_EH_PE_aligned) return true; - if ((encoding & 0x7) > DW_EH_PE_udata8) - return false; - if ((encoding & 0x70) > DW_EH_PE_funcrel) - return false; - return true; -} - -bool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const { - switch (encoding & 0x70) { - case DW_EH_PE_absptr: return true; - case DW_EH_PE_pcrel: return have_section_base_; - case DW_EH_PE_textrel: return have_text_base_; - case DW_EH_PE_datarel: return have_data_base_; - case DW_EH_PE_funcrel: return have_function_base_; - default: return false; - } -} - -uint64 ByteReader::ReadEncodedPointer(const uint8_t *buffer, - DwarfPointerEncoding encoding, - size_t *len) const { - // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't - // see it here. - assert(encoding != DW_EH_PE_omit); - - // The Linux Standards Base 4.0 does not make this clear, but the - // GNU tools (gcc/unwind-pe.h; readelf/dwarf.c; gdb/dwarf2-frame.c) - // agree that aligned pointers are always absolute, machine-sized, - // machine-signed pointers. - if (encoding == DW_EH_PE_aligned) { - assert(have_section_base_); - - // We don't need to align BUFFER in *our* address space. Rather, we - // need to find the next position in our buffer that would be aligned - // when the .eh_frame section the buffer contains is loaded into the - // program's memory. So align assuming that buffer_base_ gets loaded at - // address section_base_, where section_base_ itself may or may not be - // aligned. - - // First, find the offset to START from the closest prior aligned - // address. - uint64 skew = section_base_ & (AddressSize() - 1); - // Now find the offset from that aligned address to buffer. - uint64 offset = skew + (buffer - buffer_base_); - // Round up to the next boundary. - uint64 aligned = (offset + AddressSize() - 1) & -AddressSize(); - // Convert back to a pointer. - const uint8_t *aligned_buffer = buffer_base_ + (aligned - skew); - // Finally, store the length and actually fetch the pointer. - *len = aligned_buffer - buffer + AddressSize(); - return ReadAddress(aligned_buffer); - } - - // Extract the value first, ignoring whether it's a pointer or an - // offset relative to some base. - uint64 offset; - switch (encoding & 0x0f) { - case DW_EH_PE_absptr: - // DW_EH_PE_absptr is weird, as it is used as a meaningful value for - // both the high and low nybble of encoding bytes. When it appears in - // the high nybble, it means that the pointer is absolute, not an - // offset from some base address. When it appears in the low nybble, - // as here, it means that the pointer is stored as a normal - // machine-sized and machine-signed address. A low nybble of - // DW_EH_PE_absptr does not imply that the pointer is absolute; it is - // correct for us to treat the value as an offset from a base address - // if the upper nybble is not DW_EH_PE_absptr. - offset = ReadAddress(buffer); - *len = AddressSize(); - break; - - case DW_EH_PE_uleb128: - offset = ReadUnsignedLEB128(buffer, len); - break; - - case DW_EH_PE_udata2: - offset = ReadTwoBytes(buffer); - *len = 2; - break; - - case DW_EH_PE_udata4: - offset = ReadFourBytes(buffer); - *len = 4; - break; - - case DW_EH_PE_udata8: - offset = ReadEightBytes(buffer); - *len = 8; - break; - - case DW_EH_PE_sleb128: - offset = ReadSignedLEB128(buffer, len); - break; - - case DW_EH_PE_sdata2: - offset = ReadTwoBytes(buffer); - // Sign-extend from 16 bits. - offset = (offset ^ 0x8000) - 0x8000; - *len = 2; - break; - - case DW_EH_PE_sdata4: - offset = ReadFourBytes(buffer); - // Sign-extend from 32 bits. - offset = (offset ^ 0x80000000ULL) - 0x80000000ULL; - *len = 4; - break; - - case DW_EH_PE_sdata8: - // No need to sign-extend; this is the full width of our type. - offset = ReadEightBytes(buffer); - *len = 8; - break; - - default: - abort(); - } - - // Find the appropriate base address. - uint64 base; - switch (encoding & 0x70) { - case DW_EH_PE_absptr: - base = 0; - break; - - case DW_EH_PE_pcrel: - assert(have_section_base_); - base = section_base_ + (buffer - buffer_base_); - break; - - case DW_EH_PE_textrel: - assert(have_text_base_); - base = text_base_; - break; - - case DW_EH_PE_datarel: - assert(have_data_base_); - base = data_base_; - break; - - case DW_EH_PE_funcrel: - assert(have_function_base_); - base = function_base_; - break; - - default: - abort(); - } - - uint64 pointer = base + offset; - - // Remove inappropriate upper bits. - if (AddressSize() == 4) - pointer = pointer & 0xffffffff; - else - assert(AddressSize() == sizeof(uint64)); - - return pointer; -} - -Endianness ByteReader::GetEndianness() const { - return endian_; -} - -} // namespace dwarf2reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.h deleted file mode 100644 index 59d430348..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader.h +++ /dev/null @@ -1,315 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_DWARF_BYTEREADER_H__ -#define COMMON_DWARF_BYTEREADER_H__ - -#include - -#include - -#include "common/dwarf/types.h" -#include "common/dwarf/dwarf2enums.h" - -namespace dwarf2reader { - -// We can't use the obvious name of LITTLE_ENDIAN and BIG_ENDIAN -// because it conflicts with a macro -enum Endianness { - ENDIANNESS_BIG, - ENDIANNESS_LITTLE -}; - -// A ByteReader knows how to read single- and multi-byte values of -// various endiannesses, sizes, and encodings, as used in DWARF -// debugging information and Linux C++ exception handling data. -class ByteReader { - public: - // Construct a ByteReader capable of reading one-, two-, four-, and - // eight-byte values according to ENDIANNESS, absolute machine-sized - // addresses, DWARF-style "initial length" values, signed and - // unsigned LEB128 numbers, and Linux C++ exception handling data's - // encoded pointers. - explicit ByteReader(enum Endianness endianness); - virtual ~ByteReader(); - - // Read a single byte from BUFFER and return it as an unsigned 8 bit - // number. - uint8 ReadOneByte(const uint8_t *buffer) const; - - // Read two bytes from BUFFER and return them as an unsigned 16 bit - // number, using this ByteReader's endianness. - uint16 ReadTwoBytes(const uint8_t *buffer) const; - - // Read four bytes from BUFFER and return them as an unsigned 32 bit - // number, using this ByteReader's endianness. This function returns - // a uint64 so that it is compatible with ReadAddress and - // ReadOffset. The number it returns will never be outside the range - // of an unsigned 32 bit integer. - uint64 ReadFourBytes(const uint8_t *buffer) const; - - // Read eight bytes from BUFFER and return them as an unsigned 64 - // bit number, using this ByteReader's endianness. - uint64 ReadEightBytes(const uint8_t *buffer) const; - - // Read an unsigned LEB128 (Little Endian Base 128) number from - // BUFFER and return it as an unsigned 64 bit integer. Set LEN to - // the number of bytes read. - // - // The unsigned LEB128 representation of an integer N is a variable - // number of bytes: - // - // - If N is between 0 and 0x7f, then its unsigned LEB128 - // representation is a single byte whose value is N. - // - // - Otherwise, its unsigned LEB128 representation is (N & 0x7f) | - // 0x80, followed by the unsigned LEB128 representation of N / - // 128, rounded towards negative infinity. - // - // In other words, we break VALUE into groups of seven bits, put - // them in little-endian order, and then write them as eight-bit - // bytes with the high bit on all but the last. - uint64 ReadUnsignedLEB128(const uint8_t *buffer, size_t *len) const; - - // Read a signed LEB128 number from BUFFER and return it as an - // signed 64 bit integer. Set LEN to the number of bytes read. - // - // The signed LEB128 representation of an integer N is a variable - // number of bytes: - // - // - If N is between -0x40 and 0x3f, then its signed LEB128 - // representation is a single byte whose value is N in two's - // complement. - // - // - Otherwise, its signed LEB128 representation is (N & 0x7f) | - // 0x80, followed by the signed LEB128 representation of N / 128, - // rounded towards negative infinity. - // - // In other words, we break VALUE into groups of seven bits, put - // them in little-endian order, and then write them as eight-bit - // bytes with the high bit on all but the last. - int64 ReadSignedLEB128(const uint8_t *buffer, size_t *len) const; - - // Indicate that addresses on this architecture are SIZE bytes long. SIZE - // must be either 4 or 8. (DWARF allows addresses to be any number of - // bytes in length from 1 to 255, but we only support 32- and 64-bit - // addresses at the moment.) You must call this before using the - // ReadAddress member function. - // - // For data in a .debug_info section, or something that .debug_info - // refers to like line number or macro data, the compilation unit - // header's address_size field indicates the address size to use. Call - // frame information doesn't indicate its address size (a shortcoming of - // the spec); you must supply the appropriate size based on the - // architecture of the target machine. - void SetAddressSize(uint8 size); - - // Return the current address size, in bytes. This is either 4, - // indicating 32-bit addresses, or 8, indicating 64-bit addresses. - uint8 AddressSize() const { return address_size_; } - - // Read an address from BUFFER and return it as an unsigned 64 bit - // integer, respecting this ByteReader's endianness and address size. You - // must call SetAddressSize before calling this function. - uint64 ReadAddress(const uint8_t *buffer) const; - - // DWARF actually defines two slightly different formats: 32-bit DWARF - // and 64-bit DWARF. This is *not* related to the size of registers or - // addresses on the target machine; it refers only to the size of section - // offsets and data lengths appearing in the DWARF data. One only needs - // 64-bit DWARF when the debugging data itself is larger than 4GiB. - // 32-bit DWARF can handle x86_64 or PPC64 code just fine, unless the - // debugging data itself is very large. - // - // DWARF information identifies itself as 32-bit or 64-bit DWARF: each - // compilation unit and call frame information entry begins with an - // "initial length" field, which, in addition to giving the length of the - // data, also indicates the size of section offsets and lengths appearing - // in that data. The ReadInitialLength member function, below, reads an - // initial length and sets the ByteReader's offset size as a side effect. - // Thus, in the normal process of reading DWARF data, the appropriate - // offset size is set automatically. So, you should only need to call - // SetOffsetSize if you are using the same ByteReader to jump from the - // midst of one block of DWARF data into another. - - // Read a DWARF "initial length" field from START, and return it as - // an unsigned 64 bit integer, respecting this ByteReader's - // endianness. Set *LEN to the length of the initial length in - // bytes, either four or twelve. As a side effect, set this - // ByteReader's offset size to either 4 (if we see a 32-bit DWARF - // initial length) or 8 (if we see a 64-bit DWARF initial length). - // - // A DWARF initial length is either: - // - // - a byte count stored as an unsigned 32-bit value less than - // 0xffffff00, indicating that the data whose length is being - // measured uses the 32-bit DWARF format, or - // - // - The 32-bit value 0xffffffff, followed by a 64-bit byte count, - // indicating that the data whose length is being measured uses - // the 64-bit DWARF format. - uint64 ReadInitialLength(const uint8_t *start, size_t *len); - - // Read an offset from BUFFER and return it as an unsigned 64 bit - // integer, respecting the ByteReader's endianness. In 32-bit DWARF, the - // offset is 4 bytes long; in 64-bit DWARF, the offset is eight bytes - // long. You must call ReadInitialLength or SetOffsetSize before calling - // this function; see the comments above for details. - uint64 ReadOffset(const uint8_t *buffer) const; - - // Return the current offset size, in bytes. - // A return value of 4 indicates that we are reading 32-bit DWARF. - // A return value of 8 indicates that we are reading 64-bit DWARF. - uint8 OffsetSize() const { return offset_size_; } - - // Indicate that section offsets and lengths are SIZE bytes long. SIZE - // must be either 4 (meaning 32-bit DWARF) or 8 (meaning 64-bit DWARF). - // Usually, you should not call this function yourself; instead, let a - // call to ReadInitialLength establish the data's offset size - // automatically. - void SetOffsetSize(uint8 size); - - // The Linux C++ ABI uses a variant of DWARF call frame information - // for exception handling. This data is included in the program's - // address space as the ".eh_frame" section, and intepreted at - // runtime to walk the stack, find exception handlers, and run - // cleanup code. The format is mostly the same as DWARF CFI, with - // some adjustments made to provide the additional - // exception-handling data, and to make the data easier to work with - // in memory --- for example, to allow it to be placed in read-only - // memory even when describing position-independent code. - // - // In particular, exception handling data can select a number of - // different encodings for pointers that appear in the data, as - // described by the DwarfPointerEncoding enum. There are actually - // four axes(!) to the encoding: - // - // - The pointer size: pointers can be 2, 4, or 8 bytes long, or use - // the DWARF LEB128 encoding. - // - // - The pointer's signedness: pointers can be signed or unsigned. - // - // - The pointer's base address: the data stored in the exception - // handling data can be the actual address (that is, an absolute - // pointer), or relative to one of a number of different base - // addreses --- including that of the encoded pointer itself, for - // a form of "pc-relative" addressing. - // - // - The pointer may be indirect: it may be the address where the - // true pointer is stored. (This is used to refer to things via - // global offset table entries, program linkage table entries, or - // other tricks used in position-independent code.) - // - // There are also two options that fall outside that matrix - // altogether: the pointer may be omitted, or it may have padding to - // align it on an appropriate address boundary. (That last option - // may seem like it should be just another axis, but it is not.) - - // Indicate that the exception handling data is loaded starting at - // SECTION_BASE, and that the start of its buffer in our own memory - // is BUFFER_BASE. This allows us to find the address that a given - // byte in our buffer would have when loaded into the program the - // data describes. We need this to resolve DW_EH_PE_pcrel pointers. - void SetCFIDataBase(uint64 section_base, const uint8_t *buffer_base); - - // Indicate that the base address of the program's ".text" section - // is TEXT_BASE. We need this to resolve DW_EH_PE_textrel pointers. - void SetTextBase(uint64 text_base); - - // Indicate that the base address for DW_EH_PE_datarel pointers is - // DATA_BASE. The proper value depends on the ABI; it is usually the - // address of the global offset table, held in a designated register in - // position-independent code. You will need to look at the startup code - // for the target system to be sure. I tried; my eyes bled. - void SetDataBase(uint64 data_base); - - // Indicate that the base address for the FDE we are processing is - // FUNCTION_BASE. This is the start address of DW_EH_PE_funcrel - // pointers. (This encoding does not seem to be used by the GNU - // toolchain.) - void SetFunctionBase(uint64 function_base); - - // Indicate that we are no longer processing any FDE, so any use of - // a DW_EH_PE_funcrel encoding is an error. - void ClearFunctionBase(); - - // Return true if ENCODING is a valid pointer encoding. - bool ValidEncoding(DwarfPointerEncoding encoding) const; - - // Return true if we have all the information we need to read a - // pointer that uses ENCODING. This checks that the appropriate - // SetFooBase function for ENCODING has been called. - bool UsableEncoding(DwarfPointerEncoding encoding) const; - - // Read an encoded pointer from BUFFER using ENCODING; return the - // absolute address it represents, and set *LEN to the pointer's - // length in bytes, including any padding for aligned pointers. - // - // This function calls 'abort' if ENCODING is invalid or refers to a - // base address this reader hasn't been given, so you should check - // with ValidEncoding and UsableEncoding first if you would rather - // die in a more helpful way. - uint64 ReadEncodedPointer(const uint8_t *buffer, - DwarfPointerEncoding encoding, - size_t *len) const; - - Endianness GetEndianness() const; - private: - - // Function pointer type for our address and offset readers. - typedef uint64 (ByteReader::*AddressReader)(const uint8_t *) const; - - // Read an offset from BUFFER and return it as an unsigned 64 bit - // integer. DWARF2/3 define offsets as either 4 or 8 bytes, - // generally depending on the amount of DWARF2/3 info present. - // This function pointer gets set by SetOffsetSize. - AddressReader offset_reader_; - - // Read an address from BUFFER and return it as an unsigned 64 bit - // integer. DWARF2/3 allow addresses to be any size from 0-255 - // bytes currently. Internally we support 4 and 8 byte addresses, - // and will CHECK on anything else. - // This function pointer gets set by SetAddressSize. - AddressReader address_reader_; - - Endianness endian_; - uint8 address_size_; - uint8 offset_size_; - - // Base addresses for Linux C++ exception handling data's encoded pointers. - bool have_section_base_, have_text_base_, have_data_base_; - bool have_function_base_; - uint64 section_base_, text_base_, data_base_, function_base_; - const uint8_t *buffer_base_; -}; - -} // namespace dwarf2reader - -#endif // COMMON_DWARF_BYTEREADER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader_unittest.cc deleted file mode 100644 index e66062d1f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader_unittest.cc +++ /dev/null @@ -1,707 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// bytereader_unittest.cc: Unit tests for dwarf2reader::ByteReader - -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/dwarf/bytereader.h" -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/cfi_assembler.h" -#include "common/using_std_string.h" - -using dwarf2reader::ByteReader; -using dwarf2reader::DwarfPointerEncoding; -using dwarf2reader::ENDIANNESS_BIG; -using dwarf2reader::ENDIANNESS_LITTLE; -using google_breakpad::CFISection; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Section; -using testing::Test; - -struct ReaderFixture { - string contents; - size_t pointer_size; -}; - -class Reader: public ReaderFixture, public Test { }; -class ReaderDeathTest: public ReaderFixture, public Test { }; - -TEST_F(Reader, SimpleConstructor) { - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - CFISection section(kBigEndian, 4); - section - .D8(0xc0) - .D16(0xcf0d) - .D32(0x96fdd219) - .D64(0xbbf55fef0825f117ULL) - .ULEB128(0xa0927048ba8121afULL) - .LEB128(-0x4f337badf4483f83LL) - .D32(0xfec319c9); - ASSERT_TRUE(section.GetContents(&contents)); - const uint8_t *data = reinterpret_cast(contents.data()); - EXPECT_EQ(0xc0U, reader.ReadOneByte(data)); - EXPECT_EQ(0xcf0dU, reader.ReadTwoBytes(data + 1)); - EXPECT_EQ(0x96fdd219U, reader.ReadFourBytes(data + 3)); - EXPECT_EQ(0xbbf55fef0825f117ULL, reader.ReadEightBytes(data + 7)); - size_t leb128_size; - EXPECT_EQ(0xa0927048ba8121afULL, - reader.ReadUnsignedLEB128(data + 15, &leb128_size)); - EXPECT_EQ(10U, leb128_size); - EXPECT_EQ(-0x4f337badf4483f83LL, - reader.ReadSignedLEB128(data + 25, &leb128_size)); - EXPECT_EQ(10U, leb128_size); - EXPECT_EQ(0xfec319c9, reader.ReadAddress(data + 35)); -} - -TEST_F(Reader, ValidEncodings) { - ByteReader reader(ENDIANNESS_LITTLE); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_absptr))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_omit))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_aligned))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_uleb128))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata2))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata4))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata8))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sleb128))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata2))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata4))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata8))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_pcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_textrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_datarel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_absptr | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_uleb128 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata2 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata4 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_udata8 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sleb128 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata2 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata4 | - dwarf2reader::DW_EH_PE_funcrel))); - EXPECT_TRUE(reader.ValidEncoding( - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect | - dwarf2reader::DW_EH_PE_sdata8 | - dwarf2reader::DW_EH_PE_funcrel))); - - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x05))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x07))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x0d))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x0f))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x51))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x60))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0x70))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0xf0))); - EXPECT_FALSE(reader.ValidEncoding(DwarfPointerEncoding(0xd0))); -} - -TEST_F(ReaderDeathTest, DW_EH_PE_omit) { - static const uint8_t data[] = { 42 }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - EXPECT_DEATH(reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_omit, - &pointer_size), - "encoding != DW_EH_PE_omit"); -} - -TEST_F(Reader, DW_EH_PE_absptr4) { - static const uint8_t data[] = { 0x27, 0x57, 0xea, 0x40 }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(4); - EXPECT_EQ(0x40ea5727U, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_absptr, - &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_absptr8) { - static const uint8_t data[] = { - 0x60, 0x27, 0x57, 0xea, 0x40, 0xc2, 0x98, 0x05, 0x01, 0x50 - }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(8); - EXPECT_EQ(0x010598c240ea5727ULL, - reader.ReadEncodedPointer(data + 1, dwarf2reader::DW_EH_PE_absptr, - &pointer_size)); - EXPECT_EQ(8U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_uleb128) { - static const uint8_t data[] = { 0x81, 0x84, 0x4c }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(4); - EXPECT_EQ(0x130201U, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_uleb128, - &pointer_size)); - EXPECT_EQ(3U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_udata2) { - static const uint8_t data[] = { 0xf4, 0x8d }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - EXPECT_EQ(0xf48dU, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_udata2, - &pointer_size)); - EXPECT_EQ(2U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_udata4) { - static const uint8_t data[] = { 0xb2, 0x68, 0xa5, 0x62, 0x8f, 0x8b }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(8); - EXPECT_EQ(0xa5628f8b, - reader.ReadEncodedPointer(data + 2, dwarf2reader::DW_EH_PE_udata4, - &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_udata8Addr8) { - static const uint8_t data[] = { - 0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe - }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(8); - EXPECT_EQ(0x8fed199f69047304ULL, - reader.ReadEncodedPointer(data + 1, dwarf2reader::DW_EH_PE_udata8, - &pointer_size)); - EXPECT_EQ(8U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_udata8Addr4) { - static const uint8_t data[] = { - 0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe - }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(4); - EXPECT_EQ(0x69047304ULL, - reader.ReadEncodedPointer(data + 1, dwarf2reader::DW_EH_PE_udata8, - &pointer_size)); - EXPECT_EQ(8U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_sleb128) { - static const uint8_t data[] = { 0x42, 0xff, 0xfb, 0x73 }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - EXPECT_EQ(-0x030201U & 0xffffffff, - reader.ReadEncodedPointer(data + 1, dwarf2reader::DW_EH_PE_sleb128, - &pointer_size)); - EXPECT_EQ(3U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_sdata2) { - static const uint8_t data[] = { 0xb9, 0xbf }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(8); - EXPECT_EQ(0xffffffffffffbfb9ULL, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_sdata2, - &pointer_size)); - EXPECT_EQ(2U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_sdata4) { - static const uint8_t data[] = { 0xa0, 0xca, 0xf2, 0xb8, 0xc2, 0xad }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(8); - EXPECT_EQ(0xffffffffadc2b8f2ULL, - reader.ReadEncodedPointer(data + 2, dwarf2reader::DW_EH_PE_sdata4, - &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_sdata8) { - static const uint8_t data[] = { - 0xf6, 0x66, 0x57, 0x79, 0xe0, 0x0c, 0x9b, 0x26, 0x87 - }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(8); - EXPECT_EQ(0x87269b0ce0795766ULL, - reader.ReadEncodedPointer(data + 1, dwarf2reader::DW_EH_PE_sdata8, - &pointer_size)); - EXPECT_EQ(8U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_pcrel) { - static const uint8_t data[] = { - 0x4a, 0x8b, 0x1b, 0x14, 0xc8, 0xc4, 0x02, 0xce - }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - DwarfPointerEncoding encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_pcrel - | dwarf2reader::DW_EH_PE_absptr); - reader.SetCFIDataBase(0x89951377, data); - EXPECT_EQ(0x89951377 + 3 + 0x14c8c402, - reader.ReadEncodedPointer(data + 3, encoding, &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_textrel) { - static const uint8_t data[] = { - 0xd9, 0x0d, 0x05, 0x17, 0xc9, 0x7a, 0x42, 0x1e - }; - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(4); - reader.SetTextBase(0xb91beaf0); - DwarfPointerEncoding encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_textrel - | dwarf2reader::DW_EH_PE_sdata2); - EXPECT_EQ((0xb91beaf0 + 0xffffc917) & 0xffffffff, - reader.ReadEncodedPointer(data + 3, encoding, &pointer_size)); - EXPECT_EQ(2U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_datarel) { - static const uint8_t data[] = { - 0x16, 0xf2, 0xbb, 0x82, 0x68, 0xa7, 0xbc, 0x39 - }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(8); - reader.SetDataBase(0xbef308bd25ce74f0ULL); - DwarfPointerEncoding encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_datarel - | dwarf2reader::DW_EH_PE_sleb128); - EXPECT_EQ(0xbef308bd25ce74f0ULL + 0xfffffffffffa013bULL, - reader.ReadEncodedPointer(data + 2, encoding, &pointer_size)); - EXPECT_EQ(3U, pointer_size); -} - -TEST_F(Reader, DW_EH_PE_funcrel) { - static const uint8_t data[] = { - 0x84, 0xf8, 0x14, 0x01, 0x61, 0xd1, 0x48, 0xc9 - }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetAddressSize(4); - reader.SetFunctionBase(0x823c3520); - DwarfPointerEncoding encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_funcrel - | dwarf2reader::DW_EH_PE_udata2); - EXPECT_EQ(0x823c3520 + 0xd148, - reader.ReadEncodedPointer(data + 5, encoding, &pointer_size)); - EXPECT_EQ(2U, pointer_size); -} - -TEST(UsableBase, CFI) { - static const uint8_t data[] = { 0x42 }; - ByteReader reader(ENDIANNESS_BIG); - reader.SetCFIDataBase(0xb31cbd20, data); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_pcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_textrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_datarel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_funcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_omit)); - EXPECT_FALSE(reader.UsableEncoding(DwarfPointerEncoding(0x60))); -} - -TEST(UsableBase, Text) { - ByteReader reader(ENDIANNESS_BIG); - reader.SetTextBase(0xa899ccb9); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_pcrel)); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_textrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_datarel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_funcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_omit)); - EXPECT_FALSE(reader.UsableEncoding(DwarfPointerEncoding(0x60))); -} - -TEST(UsableBase, Data) { - ByteReader reader(ENDIANNESS_BIG); - reader.SetDataBase(0xf7b10bcd); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_pcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_textrel)); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_datarel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_funcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_omit)); - EXPECT_FALSE(reader.UsableEncoding(DwarfPointerEncoding(0x60))); -} - -TEST(UsableBase, Function) { - ByteReader reader(ENDIANNESS_BIG); - reader.SetFunctionBase(0xc2c0ed81); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_pcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_textrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_datarel)); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_funcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_omit)); - EXPECT_FALSE(reader.UsableEncoding(DwarfPointerEncoding(0x60))); -} - -TEST(UsableBase, ClearFunction) { - ByteReader reader(ENDIANNESS_BIG); - reader.SetFunctionBase(0xc2c0ed81); - reader.ClearFunctionBase(); - EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_pcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_textrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_datarel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_funcrel)); - EXPECT_FALSE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_omit)); - EXPECT_FALSE(reader.UsableEncoding(DwarfPointerEncoding(0x60))); -} - -struct AlignedFixture { - AlignedFixture() : reader(ENDIANNESS_BIG) { reader.SetAddressSize(4); } - static const uint8_t data[10]; - ByteReader reader; - size_t pointer_size; -}; - -const uint8_t AlignedFixture::data[10] = { - 0xfe, 0x6e, 0x93, 0xd8, 0x34, 0xd5, 0x1c, 0xd3, 0xac, 0x2b -}; - -class Aligned: public AlignedFixture, public Test { }; - -TEST_F(Aligned, DW_EH_PE_aligned0) { - reader.SetCFIDataBase(0xb440305c, data); - EXPECT_EQ(0xfe6e93d8U, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned1) { - reader.SetCFIDataBase(0xb440305d, data); - EXPECT_EQ(0xd834d51cU, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(7U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned2) { - reader.SetCFIDataBase(0xb440305e, data); - EXPECT_EQ(0x93d834d5U, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(6U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned3) { - reader.SetCFIDataBase(0xb440305f, data); - EXPECT_EQ(0x6e93d834U, - reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(5U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned11) { - reader.SetCFIDataBase(0xb4403061, data); - EXPECT_EQ(0xd834d51cU, - reader.ReadEncodedPointer(data + 1, - dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(6U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned30) { - reader.SetCFIDataBase(0xb4403063, data); - EXPECT_EQ(0x6e93d834U, - reader.ReadEncodedPointer(data + 1, - dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(4U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned23) { - reader.SetCFIDataBase(0xb4403062, data); - EXPECT_EQ(0x1cd3ac2bU, - reader.ReadEncodedPointer(data + 3, - dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(7U, pointer_size); -} - -TEST_F(Aligned, DW_EH_PE_aligned03) { - reader.SetCFIDataBase(0xb4403064, data); - EXPECT_EQ(0x34d51cd3U, - reader.ReadEncodedPointer(data + 3, - dwarf2reader::DW_EH_PE_aligned, - &pointer_size)); - EXPECT_EQ(5U, pointer_size); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.cc deleted file mode 100644 index dbc2efae6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.cc +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_assembler.cc: Implementation of google_breakpad::CFISection class. -// See cfi_assembler.h for details. - -#include "common/dwarf/cfi_assembler.h" - -#include -#include - -namespace google_breakpad { - -using dwarf2reader::DwarfPointerEncoding; - -CFISection &CFISection::CIEHeader(uint64_t code_alignment_factor, - int data_alignment_factor, - unsigned return_address_register, - uint8_t version, - const string &augmentation, - bool dwarf64) { - assert(!entry_length_); - entry_length_ = new PendingLength(); - in_fde_ = false; - - if (dwarf64) { - D32(kDwarf64InitialLengthMarker); - D64(entry_length_->length); - entry_length_->start = Here(); - D64(eh_frame_ ? kEHFrame64CIEIdentifier : kDwarf64CIEIdentifier); - } else { - D32(entry_length_->length); - entry_length_->start = Here(); - D32(eh_frame_ ? kEHFrame32CIEIdentifier : kDwarf32CIEIdentifier); - } - D8(version); - AppendCString(augmentation); - ULEB128(code_alignment_factor); - LEB128(data_alignment_factor); - if (version == 1) - D8(return_address_register); - else - ULEB128(return_address_register); - return *this; -} - -CFISection &CFISection::FDEHeader(Label cie_pointer, - uint64_t initial_location, - uint64_t address_range, - bool dwarf64) { - assert(!entry_length_); - entry_length_ = new PendingLength(); - in_fde_ = true; - fde_start_address_ = initial_location; - - if (dwarf64) { - D32(0xffffffff); - D64(entry_length_->length); - entry_length_->start = Here(); - if (eh_frame_) - D64(Here() - cie_pointer); - else - D64(cie_pointer); - } else { - D32(entry_length_->length); - entry_length_->start = Here(); - if (eh_frame_) - D32(Here() - cie_pointer); - else - D32(cie_pointer); - } - EncodedPointer(initial_location); - // The FDE length in an .eh_frame section uses the same encoding as the - // initial location, but ignores the base address (selected by the upper - // nybble of the encoding), as it's a length, not an address that can be - // made relative. - EncodedPointer(address_range, - DwarfPointerEncoding(pointer_encoding_ & 0x0f)); - return *this; -} - -CFISection &CFISection::FinishEntry() { - assert(entry_length_); - Align(address_size_, dwarf2reader::DW_CFA_nop); - entry_length_->length = Here() - entry_length_->start; - delete entry_length_; - entry_length_ = NULL; - in_fde_ = false; - return *this; -} - -CFISection &CFISection::EncodedPointer(uint64_t address, - DwarfPointerEncoding encoding, - const EncodedPointerBases &bases) { - // Omitted data is extremely easy to emit. - if (encoding == dwarf2reader::DW_EH_PE_omit) - return *this; - - // If (encoding & dwarf2reader::DW_EH_PE_indirect) != 0, then we assume - // that ADDRESS is the address at which the pointer is stored --- in - // other words, that bit has no effect on how we write the pointer. - encoding = DwarfPointerEncoding(encoding & ~dwarf2reader::DW_EH_PE_indirect); - - // Find the base address to which this pointer is relative. The upper - // nybble of the encoding specifies this. - uint64_t base; - switch (encoding & 0xf0) { - case dwarf2reader::DW_EH_PE_absptr: base = 0; break; - case dwarf2reader::DW_EH_PE_pcrel: base = bases.cfi + Size(); break; - case dwarf2reader::DW_EH_PE_textrel: base = bases.text; break; - case dwarf2reader::DW_EH_PE_datarel: base = bases.data; break; - case dwarf2reader::DW_EH_PE_funcrel: base = fde_start_address_; break; - case dwarf2reader::DW_EH_PE_aligned: base = 0; break; - default: abort(); - }; - - // Make ADDRESS relative. Yes, this is appropriate even for "absptr" - // values; see gcc/unwind-pe.h. - address -= base; - - // Align the pointer, if required. - if ((encoding & 0xf0) == dwarf2reader::DW_EH_PE_aligned) - Align(AddressSize()); - - // Append ADDRESS to this section in the appropriate form. For the - // fixed-width forms, we don't need to differentiate between signed and - // unsigned encodings, because ADDRESS has already been extended to 64 - // bits before it was passed to us. - switch (encoding & 0x0f) { - case dwarf2reader::DW_EH_PE_absptr: - Address(address); - break; - - case dwarf2reader::DW_EH_PE_uleb128: - ULEB128(address); - break; - - case dwarf2reader::DW_EH_PE_sleb128: - LEB128(address); - break; - - case dwarf2reader::DW_EH_PE_udata2: - case dwarf2reader::DW_EH_PE_sdata2: - D16(address); - break; - - case dwarf2reader::DW_EH_PE_udata4: - case dwarf2reader::DW_EH_PE_sdata4: - D32(address); - break; - - case dwarf2reader::DW_EH_PE_udata8: - case dwarf2reader::DW_EH_PE_sdata8: - D64(address); - break; - - default: - abort(); - } - - return *this; -}; - -const uint32_t CFISection::kDwarf64InitialLengthMarker; -const uint32_t CFISection::kDwarf32CIEIdentifier; -const uint64_t CFISection::kDwarf64CIEIdentifier; -const uint32_t CFISection::kEHFrame32CIEIdentifier; -const uint64_t CFISection::kEHFrame64CIEIdentifier; - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.h deleted file mode 100644 index 227812b58..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.h +++ /dev/null @@ -1,269 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_assembler.h: Define CFISection, a class for creating properly -// (and improperly) formatted DWARF CFI data for unit tests. - -#ifndef PROCESSOR_CFI_ASSEMBLER_H_ -#define PROCESSOR_CFI_ASSEMBLER_H_ - -#include - -#include "common/dwarf/dwarf2enums.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -using dwarf2reader::DwarfPointerEncoding; -using google_breakpad::test_assembler::Endianness; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; - -class CFISection: public Section { - public: - - // CFI augmentation strings beginning with 'z', defined by the - // Linux/IA-64 C++ ABI, can specify interesting encodings for - // addresses appearing in FDE headers and call frame instructions (and - // for additional fields whose presence the augmentation string - // specifies). In particular, pointers can be specified to be relative - // to various base address: the start of the .text section, the - // location holding the address itself, and so on. These allow the - // frame data to be position-independent even when they live in - // write-protected pages. These variants are specified at the - // following two URLs: - // - // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html - // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html - // - // CFISection leaves the production of well-formed 'z'-augmented CIEs and - // FDEs to the user, but does provide EncodedPointer, to emit - // properly-encoded addresses for a given pointer encoding. - // EncodedPointer uses an instance of this structure to find the base - // addresses it should use; you can establish a default for all encoded - // pointers appended to this section with SetEncodedPointerBases. - struct EncodedPointerBases { - EncodedPointerBases() : cfi(), text(), data() { } - - // The starting address of this CFI section in memory, for - // DW_EH_PE_pcrel. DW_EH_PE_pcrel pointers may only be used in data - // that has is loaded into the program's address space. - uint64_t cfi; - - // The starting address of this file's .text section, for DW_EH_PE_textrel. - uint64_t text; - - // The starting address of this file's .got or .eh_frame_hdr section, - // for DW_EH_PE_datarel. - uint64_t data; - }; - - // Create a CFISection whose endianness is ENDIANNESS, and where - // machine addresses are ADDRESS_SIZE bytes long. If EH_FRAME is - // true, use the .eh_frame format, as described by the Linux - // Standards Base Core Specification, instead of the DWARF CFI - // format. - CFISection(Endianness endianness, size_t address_size, - bool eh_frame = false) - : Section(endianness), address_size_(address_size), eh_frame_(eh_frame), - pointer_encoding_(dwarf2reader::DW_EH_PE_absptr), - encoded_pointer_bases_(), entry_length_(NULL), in_fde_(false) { - // The 'start', 'Here', and 'Mark' members of a CFISection all refer - // to section offsets. - start() = 0; - } - - // Return this CFISection's address size. - size_t AddressSize() const { return address_size_; } - - // Return true if this CFISection uses the .eh_frame format, or - // false if it contains ordinary DWARF CFI data. - bool ContainsEHFrame() const { return eh_frame_; } - - // Use ENCODING for pointers in calls to FDEHeader and EncodedPointer. - void SetPointerEncoding(DwarfPointerEncoding encoding) { - pointer_encoding_ = encoding; - } - - // Use the addresses in BASES as the base addresses for encoded - // pointers in subsequent calls to FDEHeader or EncodedPointer. - // This function makes a copy of BASES. - void SetEncodedPointerBases(const EncodedPointerBases &bases) { - encoded_pointer_bases_ = bases; - } - - // Append a Common Information Entry header to this section with the - // given values. If dwarf64 is true, use the 64-bit DWARF initial - // length format for the CIE's initial length. Return a reference to - // this section. You should call FinishEntry after writing the last - // instruction for the CIE. - // - // Before calling this function, you will typically want to use Mark - // or Here to make a label to pass to FDEHeader that refers to this - // CIE's position in the section. - CFISection &CIEHeader(uint64_t code_alignment_factor, - int data_alignment_factor, - unsigned return_address_register, - uint8_t version = 3, - const string &augmentation = "", - bool dwarf64 = false); - - // Append a Frame Description Entry header to this section with the - // given values. If dwarf64 is true, use the 64-bit DWARF initial - // length format for the CIE's initial length. Return a reference to - // this section. You should call FinishEntry after writing the last - // instruction for the CIE. - // - // This function doesn't support entries that are longer than - // 0xffffff00 bytes. (The "initial length" is always a 32-bit - // value.) Nor does it support .debug_frame sections longer than - // 0xffffff00 bytes. - CFISection &FDEHeader(Label cie_pointer, - uint64_t initial_location, - uint64_t address_range, - bool dwarf64 = false); - - // Note the current position as the end of the last CIE or FDE we - // started, after padding with DW_CFA_nops for alignment. This - // defines the label representing the entry's length, cited in the - // entry's header. Return a reference to this section. - CFISection &FinishEntry(); - - // Append the contents of BLOCK as a DW_FORM_block value: an - // unsigned LEB128 length, followed by that many bytes of data. - CFISection &Block(const string &block) { - ULEB128(block.size()); - Append(block); - return *this; - } - - // Append ADDRESS to this section, in the appropriate size and - // endianness. Return a reference to this section. - CFISection &Address(uint64_t address) { - Section::Append(endianness(), address_size_, address); - return *this; - } - CFISection &Address(Label address) { - Section::Append(endianness(), address_size_, address); - return *this; - } - - // Append ADDRESS to this section, using ENCODING and BASES. ENCODING - // defaults to this section's default encoding, established by - // SetPointerEncoding. BASES defaults to this section's bases, set by - // SetEncodedPointerBases. If the DW_EH_PE_indirect bit is set in the - // encoding, assume that ADDRESS is where the true address is stored. - // Return a reference to this section. - // - // (C++ doesn't let me use default arguments here, because I want to - // refer to members of *this in the default argument expression.) - CFISection &EncodedPointer(uint64_t address) { - return EncodedPointer(address, pointer_encoding_, encoded_pointer_bases_); - } - CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding) { - return EncodedPointer(address, encoding, encoded_pointer_bases_); - } - CFISection &EncodedPointer(uint64_t address, DwarfPointerEncoding encoding, - const EncodedPointerBases &bases); - - // Restate some member functions, to keep chaining working nicely. - CFISection &Mark(Label *label) { Section::Mark(label); return *this; } - CFISection &D8(uint8_t v) { Section::D8(v); return *this; } - CFISection &D16(uint16_t v) { Section::D16(v); return *this; } - CFISection &D16(Label v) { Section::D16(v); return *this; } - CFISection &D32(uint32_t v) { Section::D32(v); return *this; } - CFISection &D32(const Label &v) { Section::D32(v); return *this; } - CFISection &D64(uint64_t v) { Section::D64(v); return *this; } - CFISection &D64(const Label &v) { Section::D64(v); return *this; } - CFISection &LEB128(long long v) { Section::LEB128(v); return *this; } - CFISection &ULEB128(uint64_t v) { Section::ULEB128(v); return *this; } - - private: - // A length value that we've appended to the section, but is not yet - // known. LENGTH is the appended value; START is a label referring - // to the start of the data whose length was cited. - struct PendingLength { - Label length; - Label start; - }; - - // Constants used in CFI/.eh_frame data: - - // If the first four bytes of an "initial length" are this constant, then - // the data uses the 64-bit DWARF format, and the length itself is the - // subsequent eight bytes. - static const uint32_t kDwarf64InitialLengthMarker = 0xffffffffU; - - // The CIE identifier for 32- and 64-bit DWARF CFI and .eh_frame data. - static const uint32_t kDwarf32CIEIdentifier = ~(uint32_t)0; - static const uint64_t kDwarf64CIEIdentifier = ~(uint64_t)0; - static const uint32_t kEHFrame32CIEIdentifier = 0; - static const uint64_t kEHFrame64CIEIdentifier = 0; - - // The size of a machine address for the data in this section. - size_t address_size_; - - // If true, we are generating a Linux .eh_frame section, instead of - // a standard DWARF .debug_frame section. - bool eh_frame_; - - // The encoding to use for FDE pointers. - DwarfPointerEncoding pointer_encoding_; - - // The base addresses to use when emitting encoded pointers. - EncodedPointerBases encoded_pointer_bases_; - - // The length value for the current entry. - // - // Oddly, this must be dynamically allocated. Labels never get new - // values; they only acquire constraints on the value they already - // have, or assert if you assign them something incompatible. So - // each header needs truly fresh Label objects to cite in their - // headers and track their positions. The alternative is explicit - // destructor invocation and a placement new. Ick. - PendingLength *entry_length_; - - // True if we are currently emitting an FDE --- that is, we have - // called FDEHeader but have not yet called FinishEntry. - bool in_fde_; - - // If in_fde_ is true, this is its starting address. We use this for - // emitting DW_EH_PE_funcrel pointers. - uint64_t fde_start_address_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_CFI_ASSEMBLER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.cc deleted file mode 100644 index 94542b5ea..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.cc +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2diehandler.cc: Implement the dwarf2reader::DieDispatcher class. -// See dwarf2diehandler.h for details. - -#include -#include - -#include - -#include "common/dwarf/dwarf2diehandler.h" -#include "common/using_std_string.h" - -namespace dwarf2reader { - -DIEDispatcher::~DIEDispatcher() { - while (!die_handlers_.empty()) { - HandlerStack &entry = die_handlers_.top(); - if (entry.handler_ != root_handler_) - delete entry.handler_; - die_handlers_.pop(); - } -} - -bool DIEDispatcher::StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version) { - return root_handler_->StartCompilationUnit(offset, address_size, - offset_size, cu_length, - dwarf_version); -} - -bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag) { - // The stack entry for the parent of this DIE, if there is one. - HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top(); - - // Does this call indicate that we're done receiving the parent's - // attributes' values? If so, call its EndAttributes member function. - if (parent && parent->handler_ && !parent->reported_attributes_end_) { - parent->reported_attributes_end_ = true; - if (!parent->handler_->EndAttributes()) { - // Finish off this handler now. and edit *PARENT to indicate that - // we don't want to visit any of the children. - parent->handler_->Finish(); - if (parent->handler_ != root_handler_) - delete parent->handler_; - parent->handler_ = NULL; - return false; - } - } - - // Find a handler for this DIE. - DIEHandler *handler; - if (parent) { - if (parent->handler_) - // Ask the parent to find a handler. - handler = parent->handler_->FindChildHandler(offset, tag); - else - // No parent handler means we're not interested in any of our - // children. - handler = NULL; - } else { - // This is the root DIE. For a non-root DIE, the parent's handler - // decides whether to visit it, but the root DIE has no parent - // handler, so we have a special method on the root DIE handler - // itself to decide. - if (root_handler_->StartRootDIE(offset, tag)) - handler = root_handler_; - else - handler = NULL; - } - - // Push a handler stack entry for this new handler. As an - // optimization, we don't push NULL-handler entries on top of other - // NULL-handler entries; we just let the oldest such entry stand for - // the whole subtree. - if (handler || !parent || parent->handler_) { - HandlerStack entry; - entry.offset_ = offset; - entry.handler_ = handler; - entry.reported_attributes_end_ = false; - die_handlers_.push(entry); - } - - return handler != NULL; -} - -void DIEDispatcher::EndDIE(uint64 offset) { - assert(!die_handlers_.empty()); - HandlerStack *entry = &die_handlers_.top(); - if (entry->handler_) { - // This entry had better be the handler for this DIE. - assert(entry->offset_ == offset); - // If a DIE has no children, this EndDIE call indicates that we're - // done receiving its attributes' values. - if (!entry->reported_attributes_end_) - entry->handler_->EndAttributes(); // Ignore return value: no children. - entry->handler_->Finish(); - if (entry->handler_ != root_handler_) - delete entry->handler_; - } else { - // If this DIE is within a tree we're ignoring, then don't pop the - // handler stack: that entry stands for the whole tree. - if (entry->offset_ != offset) - return; - } - die_handlers_.pop(); -} - -void DIEDispatcher::ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeUnsigned(attr, form, data); -} - -void DIEDispatcher::ProcessAttributeSigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeSigned(attr, form, data); -} - -void DIEDispatcher::ProcessAttributeReference(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeReference(attr, form, data); -} - -void DIEDispatcher::ProcessAttributeBuffer(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t *data, - uint64 len) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeBuffer(attr, form, data, len); -} - -void DIEDispatcher::ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string& data) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeString(attr, form, data); -} - -void DIEDispatcher::ProcessAttributeSignature(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 signature) { - HandlerStack ¤t = die_handlers_.top(); - // This had better be an attribute of the DIE we were meant to handle. - assert(offset == current.offset_); - current.handler_->ProcessAttributeSignature(attr, form, signature); -} - -} // namespace dwarf2reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.h deleted file mode 100644 index a1e589a86..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.h +++ /dev/null @@ -1,365 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2reader::CompilationUnit is a simple and direct parser for -// DWARF data, but its handler interface is not convenient to use. In -// particular: -// -// - CompilationUnit calls Dwarf2Handler's member functions to report -// every attribute's value, regardless of what sort of DIE it is. -// As a result, the ProcessAttributeX functions end up looking like -// this: -// -// switch (parent_die_tag) { -// case DW_TAG_x: -// switch (attribute_name) { -// case DW_AT_y: -// handle attribute y of DIE type x -// ... -// } break; -// ... -// } -// -// In C++ it's much nicer to use virtual function dispatch to find -// the right code for a given case than to switch on the DIE tag -// like this. -// -// - Processing different kinds of DIEs requires different sets of -// data: lexical block DIEs have start and end addresses, but struct -// type DIEs don't. It would be nice to be able to have separate -// handler classes for separate kinds of DIEs, each with the members -// appropriate to its role, instead of having one handler class that -// needs to hold data for every DIE type. -// -// - There should be a separate instance of the appropriate handler -// class for each DIE, instead of a single object with tables -// tracking all the dies in the compilation unit. -// -// - It's not convenient to take some action after all a DIE's -// attributes have been seen, but before visiting any of its -// children. The only indication you have that a DIE's attribute -// list is complete is that you get either a StartDIE or an EndDIE -// call. -// -// - It's not convenient to make use of the tree structure of the -// DIEs. Skipping all the children of a given die requires -// maintaining state and returning false from StartDIE until we get -// an EndDIE call with the appropriate offset. -// -// This interface tries to take care of all that. (You're shocked, I'm sure.) -// -// Using the classes here, you provide an initial handler for the root -// DIE of the compilation unit. Each handler receives its DIE's -// attributes, and provides fresh handler objects for children of -// interest, if any. The three classes are: -// -// - DIEHandler: the base class for your DIE-type-specific handler -// classes. -// -// - RootDIEHandler: derived from DIEHandler, the base class for your -// root DIE handler class. -// -// - DIEDispatcher: derived from Dwarf2Handler, an instance of this -// invokes your DIE-type-specific handler objects. -// -// In detail: -// -// - Define handler classes specialized for the DIE types you're -// interested in. These handler classes must inherit from -// DIEHandler. Thus: -// -// class My_DW_TAG_X_Handler: public DIEHandler { ... }; -// class My_DW_TAG_Y_Handler: public DIEHandler { ... }; -// -// DIEHandler subclasses needn't correspond exactly to single DIE -// types, as shown here; the point is that you can have several -// different classes appropriate to different kinds of DIEs. -// -// - In particular, define a handler class for the compilation -// unit's root DIE, that inherits from RootDIEHandler: -// -// class My_DW_TAG_compile_unit_Handler: public RootDIEHandler { ... }; -// -// RootDIEHandler inherits from DIEHandler, adding a few additional -// member functions for examining the compilation unit as a whole, -// and other quirks of rootness. -// -// - Then, create a DIEDispatcher instance, passing it an instance of -// your root DIE handler class, and use that DIEDispatcher as the -// dwarf2reader::CompilationUnit's handler: -// -// My_DW_TAG_compile_unit_Handler root_die_handler(...); -// DIEDispatcher die_dispatcher(&root_die_handler); -// CompilationUnit reader(sections, offset, bytereader, &die_dispatcher); -// -// Here, 'die_dispatcher' acts as a shim between 'reader' and the -// various DIE-specific handlers you have defined. -// -// - When you call reader.Start(), die_dispatcher behaves as follows, -// starting with your root die handler and the compilation unit's -// root DIE: -// -// - It calls the handler's ProcessAttributeX member functions for -// each of the DIE's attributes. -// -// - It calls the handler's EndAttributes member function. This -// should return true if any of the DIE's children should be -// visited, in which case: -// -// - For each of the DIE's children, die_dispatcher calls the -// DIE's handler's FindChildHandler member function. If that -// returns a pointer to a DIEHandler instance, then -// die_dispatcher uses that handler to process the child, using -// this procedure recursively. Alternatively, if -// FindChildHandler returns NULL, die_dispatcher ignores that -// child and its descendants. -// -// - When die_dispatcher has finished processing all the DIE's -// children, it invokes the handler's Finish() member function, -// and destroys the handler. (As a special case, it doesn't -// destroy the root DIE handler.) -// -// This allows the code for handling a particular kind of DIE to be -// gathered together in a single class, makes it easy to skip all the -// children or individual children of a particular DIE, and provides -// appropriate parental context for each die. - -#ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__ -#define COMMON_DWARF_DWARF2DIEHANDLER_H__ - -#include - -#include -#include - -#include "common/dwarf/types.h" -#include "common/dwarf/dwarf2enums.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" - -namespace dwarf2reader { - -// A base class for handlers for specific DIE types. The series of -// calls made on a DIE handler is as follows: -// -// - for each attribute of the DIE: -// - ProcessAttributeX() -// - EndAttributes() -// - if that returned true, then for each child: -// - FindChildHandler() -// - if that returns a non-NULL pointer to a new handler: -// - recurse, with the new handler and the child die -// - Finish() -// - destruction -class DIEHandler { - public: - DIEHandler() { } - virtual ~DIEHandler() { } - - // When we visit a DIE, we first use these member functions to - // report the DIE's attributes and their values. These have the - // same restrictions as the corresponding member functions of - // dwarf2reader::Dwarf2Handler. - // - // Since DWARF does not specify in what order attributes must - // appear, avoid making decisions in these functions that would be - // affected by the presence of other attributes. The EndAttributes - // function is a more appropriate place for such work, as all the - // DIE's attributes have been seen at that point. - // - // The default definitions ignore the values they are passed. - virtual void ProcessAttributeUnsigned(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { } - virtual void ProcessAttributeSigned(enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { } - virtual void ProcessAttributeReference(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { } - virtual void ProcessAttributeBuffer(enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t *data, - uint64 len) { } - virtual void ProcessAttributeString(enum DwarfAttribute attr, - enum DwarfForm form, - const string& data) { } - virtual void ProcessAttributeSignature(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 signture) { } - - // Once we have reported all the DIE's attributes' values, we call - // this member function. If it returns false, we skip all the DIE's - // children. If it returns true, we call FindChildHandler on each - // child. If that returns a handler object, we use that to visit - // the child; otherwise, we skip the child. - // - // This is a good place to make decisions that depend on more than - // one attribute. DWARF does not specify in what order attributes - // must appear, so only when the EndAttributes function is called - // does the handler have a complete picture of the DIE's attributes. - // - // The default definition elects to ignore the DIE's children. - // You'll need to override this if you override FindChildHandler, - // but at least the default behavior isn't to pass the children to - // FindChildHandler, which then ignores them all. - virtual bool EndAttributes() { return false; } - - // If EndAttributes returns true to indicate that some of the DIE's - // children might be of interest, then we apply this function to - // each of the DIE's children. If it returns a handler object, then - // we use that to visit the child DIE. If it returns NULL, we skip - // that child DIE (and all its descendants). - // - // OFFSET is the offset of the child; TAG indicates what kind of DIE - // it is. - // - // The default definition skips all children. - virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag) { - return NULL; - } - - // When we are done processing a DIE, we call this member function. - // This happens after the EndAttributes call, all FindChildHandler - // calls (if any), and all operations on the children themselves (if - // any). We call Finish on every handler --- even if EndAttributes - // returns false. - virtual void Finish() { }; -}; - -// A subclass of DIEHandler, with additional kludges for handling the -// compilation unit's root die. -class RootDIEHandler: public DIEHandler { - public: - RootDIEHandler() { } - virtual ~RootDIEHandler() { } - - // We pass the values reported via Dwarf2Handler::StartCompilationUnit - // to this member function, and skip the entire compilation unit if it - // returns false. So the root DIE handler is actually also - // responsible for handling the compilation unit metadata. - // The default definition always visits the compilation unit. - virtual bool StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version) { return true; } - - // For the root DIE handler only, we pass the offset, tag and - // attributes of the compilation unit's root DIE. This is the only - // way the root DIE handler can find the root DIE's tag. If this - // function returns true, we will visit the root DIE using the usual - // DIEHandler methods; otherwise, we skip the entire compilation - // unit. - // - // The default definition elects to visit the root DIE. - virtual bool StartRootDIE(uint64 offset, enum DwarfTag tag) { return true; } -}; - -class DIEDispatcher: public Dwarf2Handler { - public: - // Create a Dwarf2Handler which uses ROOT_HANDLER as the handler for - // the compilation unit's root die, as described for the DIEHandler - // class. - DIEDispatcher(RootDIEHandler *root_handler) : root_handler_(root_handler) { } - // Destroying a DIEDispatcher destroys all active handler objects - // except the root handler. - ~DIEDispatcher(); - bool StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version); - bool StartDIE(uint64 offset, enum DwarfTag tag); - void ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - void ProcessAttributeSigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data); - void ProcessAttributeReference(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - void ProcessAttributeBuffer(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t *data, - uint64 len); - void ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string &data); - void ProcessAttributeSignature(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 signature); - void EndDIE(uint64 offset); - - private: - - // The type of a handler stack entry. This includes some fields - // which don't really need to be on the stack --- they could just be - // single data members of DIEDispatcher --- but putting them here - // makes it easier to see that the code is correct. - struct HandlerStack { - // The offset of the DIE for this handler stack entry. - uint64 offset_; - - // The handler object interested in this DIE's attributes and - // children. If NULL, we're not interested in either. - DIEHandler *handler_; - - // Have we reported the end of this DIE's attributes to the handler? - bool reported_attributes_end_; - }; - - // Stack of DIE attribute handlers. At StartDIE(D), the top of the - // stack is the handler of D's parent, whom we may ask for a handler - // for D itself. At EndDIE(D), the top of the stack is D's handler. - // Special cases: - // - // - Before we've seen the compilation unit's root DIE, the stack is - // empty; we'll call root_handler_'s special member functions, and - // perhaps push root_handler_ on the stack to look at the root's - // immediate children. - // - // - When we decide to ignore a subtree, we only push an entry on - // the stack for the root of the tree being ignored, rather than - // pushing lots of stack entries with handler_ set to NULL. - std::stack die_handlers_; - - // The root handler. We don't push it on die_handlers_ until we - // actually get the StartDIE call for the root. - RootDIEHandler *root_handler_; -}; - -} // namespace dwarf2reader -#endif // COMMON_DWARF_DWARF2DIEHANDLER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler_unittest.cc deleted file mode 100644 index db70eb31b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler_unittest.cc +++ /dev/null @@ -1,527 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher. - -#include - -#include -#include - -#include "breakpad_googletest_includes.h" - -#include "common/dwarf/dwarf2diehandler.h" -#include "common/using_std_string.h" - -using std::make_pair; - -using ::testing::_; -using ::testing::ContainerEq; -using ::testing::ElementsAreArray; -using ::testing::Eq; -using ::testing::InSequence; -using ::testing::Return; -using ::testing::Sequence; -using ::testing::StrEq; - -using dwarf2reader::DIEDispatcher; -using dwarf2reader::DIEHandler; -using dwarf2reader::DwarfAttribute; -using dwarf2reader::DwarfForm; -using dwarf2reader::DwarfTag; -using dwarf2reader::RootDIEHandler; - -class MockDIEHandler: public DIEHandler { - public: - MOCK_METHOD3(ProcessAttributeUnsigned, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD3(ProcessAttributeSigned, - void(DwarfAttribute, DwarfForm, int64)); - MOCK_METHOD3(ProcessAttributeReference, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD4(ProcessAttributeBuffer, - void(DwarfAttribute, DwarfForm, const uint8_t *, uint64)); - MOCK_METHOD3(ProcessAttributeString, - void(DwarfAttribute, DwarfForm, const string &)); - MOCK_METHOD3(ProcessAttributeSignature, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD0(EndAttributes, bool()); - MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag)); - MOCK_METHOD0(Finish, void()); -}; - -class MockRootDIEHandler: public RootDIEHandler { - public: - MOCK_METHOD3(ProcessAttributeUnsigned, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD3(ProcessAttributeSigned, - void(DwarfAttribute, DwarfForm, int64)); - MOCK_METHOD3(ProcessAttributeReference, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD4(ProcessAttributeBuffer, - void(DwarfAttribute, DwarfForm, const uint8_t *, uint64)); - MOCK_METHOD3(ProcessAttributeString, - void(DwarfAttribute, DwarfForm, const string &)); - MOCK_METHOD3(ProcessAttributeSignature, - void(DwarfAttribute, DwarfForm, uint64)); - MOCK_METHOD0(EndAttributes, bool()); - MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag)); - MOCK_METHOD0(Finish, void()); - MOCK_METHOD5(StartCompilationUnit, bool(uint64, uint8, uint8, uint64, uint8)); - MOCK_METHOD2(StartRootDIE, bool(uint64, DwarfTag)); -}; - -// If the handler elects to skip the compilation unit, the dispatcher -// should tell the reader so. -TEST(Dwarf2DIEHandler, SkipCompilationUnit) { - Sequence s; - MockRootDIEHandler mock_root_handler; - DIEDispatcher die_dispatcher(&mock_root_handler); - - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0x8d42aed77cfccf3eLL, - 0x89, 0xdc, - 0x2ecb4dc778a80f21LL, - 0x66)) - .InSequence(s) - .WillOnce(Return(false)); - - EXPECT_FALSE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL, - 0x89, 0xdc, - 0x2ecb4dc778a80f21LL, - 0x66)); -} - -// If the handler elects to skip the root DIE, the dispatcher should -// tell the reader so. -TEST(Dwarf2DIEHandler, SkipRootDIE) { - Sequence s; - MockRootDIEHandler mock_root_handler; - DIEDispatcher die_dispatcher(&mock_root_handler); - - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0xde8994029fc8b999LL, 0xf4, 0x02, - 0xb00febffa76e2b2bLL, 0x5c)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(mock_root_handler, - StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6)) - .InSequence(s) - .WillOnce(Return(false)); - - EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0xde8994029fc8b999LL, - 0xf4, 0x02, - 0xb00febffa76e2b2bLL, 0x5c)); - EXPECT_FALSE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL, - (DwarfTag) 0xb4f98da6)); - die_dispatcher.EndDIE(0x7d08242b4b510cf2LL); -} - -// If the handler elects to skip the root DIE's children, the -// dispatcher should tell the reader so --- and avoid deleting the -// root handler. -TEST(Dwarf2DIEHandler, SkipRootDIEChildren) { - MockRootDIEHandler mock_root_handler; - DIEDispatcher die_dispatcher(&mock_root_handler); - - { - InSequence s; - - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0x15d6897480cc65a7LL, 0x26, 0xa0, - 0x09f8bf0767f91675LL, 0xdb)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_root_handler, - StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6)) - .WillOnce(Return(true)); - // Please don't tell me about my children. - EXPECT_CALL(mock_root_handler, EndAttributes()) - .WillOnce(Return(false)); - EXPECT_CALL(mock_root_handler, Finish()) - .WillOnce(Return()); - } - - EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x15d6897480cc65a7LL, - 0x26, 0xa0, - 0x09f8bf0767f91675LL, 0xdb)); - EXPECT_TRUE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL, - (DwarfTag) 0xb4f98da6)); - EXPECT_FALSE(die_dispatcher.StartDIE(0x435150ceedccda18LL, - (DwarfTag) 0xc3a17bba)); - die_dispatcher.EndDIE(0x435150ceedccda18LL); - die_dispatcher.EndDIE(0x7d08242b4b510cf2LL); -} - -// The dispatcher should pass attribute values through to the die -// handler accurately. -TEST(Dwarf2DIEHandler, PassAttributeValues) { - MockRootDIEHandler mock_root_handler; - DIEDispatcher die_dispatcher(&mock_root_handler); - - const uint8_t buffer[10] = { - 0x24, 0x24, 0x35, 0x9a, 0xca, 0xcf, 0xa8, 0x84, 0xa7, 0x18 - }; - string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d"; - - // Set expectations. - { - InSequence s; - - // We'll like the compilation unit header. - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0x8d42aed77cfccf3eLL, 0x89, 0xdc, - 0x2ecb4dc778a80f21LL, 0x66)) - .WillOnce(Return(true)); - - // We'll like the root DIE. - EXPECT_CALL(mock_root_handler, - StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c)) - .WillOnce(Return(true)); - - // Expect some attribute values. - EXPECT_CALL(mock_root_handler, - ProcessAttributeUnsigned((DwarfAttribute) 0x1cc0bfed, - (DwarfForm) 0x424f1468, - 0xa592571997facda1ULL)) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, - ProcessAttributeSigned((DwarfAttribute) 0x43694dc9, - (DwarfForm) 0xf6f78901L, - 0x92602a4e3bf1f446LL)) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, - ProcessAttributeReference((DwarfAttribute) 0x4033e8cL, - (DwarfForm) 0xf66fbe0bL, - 0x50fddef44734fdecULL)) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, - ProcessAttributeBuffer((DwarfAttribute) 0x25d7e0af, - (DwarfForm) 0xe99a539a, - buffer, sizeof(buffer))) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, - ProcessAttributeString((DwarfAttribute) 0x310ed065, - (DwarfForm) 0x15762fec, - StrEq(str))) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, - ProcessAttributeSignature((DwarfAttribute) 0x58790d72, - (DwarfForm) 0x4159f138, - 0x94682463613e6a5fULL)) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, EndAttributes()) - .WillOnce(Return(true)); - EXPECT_CALL(mock_root_handler, FindChildHandler(_, _)) - .Times(0); - EXPECT_CALL(mock_root_handler, Finish()) - .WillOnce(Return()); - } - - // Drive the dispatcher. - - // Report the CU header. - EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL, - 0x89, 0xdc, - 0x2ecb4dc778a80f21LL, - 0x66)); - // Report the root DIE. - EXPECT_TRUE(die_dispatcher.StartDIE(0xe2222da01e29f2a9LL, - (DwarfTag) 0x9829445c)); - - // Report some attribute values. - die_dispatcher.ProcessAttributeUnsigned(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x1cc0bfed, - (DwarfForm) 0x424f1468, - 0xa592571997facda1ULL); - die_dispatcher.ProcessAttributeSigned(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x43694dc9, - (DwarfForm) 0xf6f78901, - 0x92602a4e3bf1f446LL); - die_dispatcher.ProcessAttributeReference(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x4033e8c, - (DwarfForm) 0xf66fbe0b, - 0x50fddef44734fdecULL); - die_dispatcher.ProcessAttributeBuffer(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x25d7e0af, - (DwarfForm) 0xe99a539a, - buffer, sizeof(buffer)); - die_dispatcher.ProcessAttributeString(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x310ed065, - (DwarfForm) 0x15762fec, - str); - die_dispatcher.ProcessAttributeSignature(0xe2222da01e29f2a9LL, - (DwarfAttribute) 0x58790d72, - (DwarfForm) 0x4159f138, - 0x94682463613e6a5fULL); - - // Finish the root DIE (and thus the CU). - die_dispatcher.EndDIE(0xe2222da01e29f2a9LL); -} - -TEST(Dwarf2DIEHandler, FindAndSkipChildren) { - MockRootDIEHandler mock_root_handler; - MockDIEHandler *mock_child1_handler = new(MockDIEHandler); - MockDIEHandler *mock_child3_handler = new(MockDIEHandler); - DIEDispatcher die_dispatcher(&mock_root_handler); - - { - InSequence s; - - // We'll like the compilation unit header. - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21, - 0x47dd3c764275a216LL, 0xa5)) - .WillOnce(Return(true)); - - // Root DIE. - { - EXPECT_CALL(mock_root_handler, - StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_root_handler, - ProcessAttributeSigned((DwarfAttribute) 0xf779a642, - (DwarfForm) 0x2cb63027, - 0x18e744661769d08fLL)) - .WillOnce(Return()); - EXPECT_CALL(mock_root_handler, EndAttributes()) - .WillOnce(Return(true)); - - // First child DIE. - EXPECT_CALL(mock_root_handler, - FindChildHandler(0x149f644f8116fe8cLL, - (DwarfTag) 0xac2cbd8c)) - .WillOnce(Return(mock_child1_handler)); - { - EXPECT_CALL(*mock_child1_handler, - ProcessAttributeSigned((DwarfAttribute) 0xa6fd6f65, - (DwarfForm) 0xe4f64c41, - 0x1b04e5444a55fe67LL)) - .WillOnce(Return()); - EXPECT_CALL(*mock_child1_handler, EndAttributes()) - .WillOnce(Return(false)); - // Skip first grandchild DIE and first great-grandchild DIE. - EXPECT_CALL(*mock_child1_handler, Finish()) - .WillOnce(Return()); - } - - // Second child DIE. Root handler will decline to return a handler - // for this child. - EXPECT_CALL(mock_root_handler, - FindChildHandler(0x97412be24875de9dLL, - (DwarfTag) 0x505a068b)) - .WillOnce(Return((DIEHandler *) NULL)); - - // Third child DIE. - EXPECT_CALL(mock_root_handler, - FindChildHandler(0x753c964c8ab538aeLL, - (DwarfTag) 0x8c22970e)) - .WillOnce(Return(mock_child3_handler)); - { - EXPECT_CALL(*mock_child3_handler, - ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb, - (DwarfForm) 0x610b7ae1, - 0x3ea5c609d7d7560fLL)) - .WillOnce(Return()); - EXPECT_CALL(*mock_child3_handler, EndAttributes()) - .WillOnce(Return(true)); - EXPECT_CALL(*mock_child3_handler, Finish()) - .WillOnce(Return()); - } - - EXPECT_CALL(mock_root_handler, Finish()) - .WillOnce(Return()); - } - } - - - // Drive the dispatcher. - - // Report the CU header. - EXPECT_TRUE(die_dispatcher - .StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21, - 0x47dd3c764275a216LL, 0xa5)); - // Report the root DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0x15f0e06bdfe3c372LL, - (DwarfTag) 0xf5d60c59)); - die_dispatcher.ProcessAttributeSigned(0x15f0e06bdfe3c372LL, - (DwarfAttribute) 0xf779a642, - (DwarfForm) 0x2cb63027, - 0x18e744661769d08fLL); - - // First child DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0x149f644f8116fe8cLL, - (DwarfTag) 0xac2cbd8c)); - die_dispatcher.ProcessAttributeSigned(0x149f644f8116fe8cLL, - (DwarfAttribute) 0xa6fd6f65, - (DwarfForm) 0xe4f64c41, - 0x1b04e5444a55fe67LL); - - // First grandchild DIE. Will be skipped. - { - EXPECT_FALSE(die_dispatcher.StartDIE(0xd68de1ee0bd29419LL, - (DwarfTag) 0x22f05a15)); - // First great-grandchild DIE. Will be skipped without being - // mentioned to any handler. - { - EXPECT_FALSE(die_dispatcher - .StartDIE(0xb3076285d25cac25LL, - (DwarfTag) 0xcff4061b)); - die_dispatcher.EndDIE(0xb3076285d25cac25LL); - } - die_dispatcher.EndDIE(0xd68de1ee0bd29419LL); - } - die_dispatcher.EndDIE(0x149f644f8116fe8cLL); - } - - // Second child DIE. Root handler will decline to find a handler for it. - { - EXPECT_FALSE(die_dispatcher.StartDIE(0x97412be24875de9dLL, - (DwarfTag) 0x505a068b)); - die_dispatcher.EndDIE(0x97412be24875de9dLL); - } - - // Third child DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0x753c964c8ab538aeLL, - (DwarfTag) 0x8c22970e)); - die_dispatcher.ProcessAttributeSigned(0x753c964c8ab538aeLL, - (DwarfAttribute) 0x4e2b7cfb, - (DwarfForm) 0x610b7ae1, - 0x3ea5c609d7d7560fLL); - die_dispatcher.EndDIE(0x753c964c8ab538aeLL); - } - - // Finish the root DIE (and thus the CU). - die_dispatcher.EndDIE(0x15f0e06bdfe3c372LL); - } -} - -// The DIEDispatcher destructor is supposed to delete all handlers on -// the stack, except for the root. -TEST(Dwarf2DIEHandler, FreeHandlersOnStack) { - MockRootDIEHandler mock_root_handler; - MockDIEHandler *mock_child_handler = new(MockDIEHandler); - MockDIEHandler *mock_grandchild_handler = new(MockDIEHandler); - - { - InSequence s; - - // We'll like the compilation unit header. - EXPECT_CALL(mock_root_handler, - StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89, - 0x76d392ff393ddda2LL, 0xbf)) - .WillOnce(Return(true)); - - // Root DIE. - { - EXPECT_CALL(mock_root_handler, - StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_root_handler, EndAttributes()) - .WillOnce(Return(true)); - - // Child DIE. - EXPECT_CALL(mock_root_handler, - FindChildHandler(0x058f09240c5fc8c9LL, - (DwarfTag) 0x898bf0d0)) - .WillOnce(Return(mock_child_handler)); - { - EXPECT_CALL(*mock_child_handler, EndAttributes()) - .WillOnce(Return(true)); - - // Grandchild DIE. - EXPECT_CALL(*mock_child_handler, - FindChildHandler(0x32dc00c9945dc0c8LL, - (DwarfTag) 0x2802d007)) - .WillOnce(Return(mock_grandchild_handler)); - { - EXPECT_CALL(*mock_grandchild_handler, - ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb, - (DwarfForm) 0x610b7ae1, - 0x3ea5c609d7d7560fLL)) - .WillOnce(Return()); - - // At this point, we abandon the traversal, so none of the - // usual stuff should get called. - EXPECT_CALL(*mock_grandchild_handler, EndAttributes()) - .Times(0); - EXPECT_CALL(*mock_grandchild_handler, Finish()) - .Times(0); - } - - EXPECT_CALL(*mock_child_handler, Finish()) - .Times(0); - } - - EXPECT_CALL(mock_root_handler, Finish()) - .Times(0); - } - } - - // The dispatcher. - DIEDispatcher die_dispatcher(&mock_root_handler); - - // Report the CU header. - EXPECT_TRUE(die_dispatcher - .StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89, - 0x76d392ff393ddda2LL, 0xbf)); - // Report the root DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0xbf13b761691ddc91LL, - (DwarfTag) 0x98980361)); - - // Child DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0x058f09240c5fc8c9LL, - (DwarfTag) 0x898bf0d0)); - - // Grandchild DIE. - { - EXPECT_TRUE(die_dispatcher.StartDIE(0x32dc00c9945dc0c8LL, - (DwarfTag) 0x2802d007)); - die_dispatcher.ProcessAttributeSigned(0x32dc00c9945dc0c8LL, - (DwarfAttribute) 0x4e2b7cfb, - (DwarfForm) 0x610b7ae1, - 0x3ea5c609d7d7560fLL); - - // Stop the traversal abruptly, so that there will still be - // handlers on the stack when the dispatcher is destructed. - - // No EndDIE call... - } - // No EndDIE call... - } - // No EndDIE call... - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2enums.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2enums.h deleted file mode 100644 index 6b8a72459..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2enums.h +++ /dev/null @@ -1,675 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_DWARF_DWARF2ENUMS_H__ -#define COMMON_DWARF_DWARF2ENUMS_H__ - -namespace dwarf2reader { - -// These enums do not follow the google3 style only because they are -// known universally (specs, other implementations) by the names in -// exactly this capitalization. -// Tag names and codes. -enum DwarfTag { - DW_TAG_padding = 0x00, - DW_TAG_array_type = 0x01, - DW_TAG_class_type = 0x02, - DW_TAG_entry_point = 0x03, - DW_TAG_enumeration_type = 0x04, - DW_TAG_formal_parameter = 0x05, - DW_TAG_imported_declaration = 0x08, - DW_TAG_label = 0x0a, - DW_TAG_lexical_block = 0x0b, - DW_TAG_member = 0x0d, - DW_TAG_pointer_type = 0x0f, - DW_TAG_reference_type = 0x10, - DW_TAG_compile_unit = 0x11, - DW_TAG_string_type = 0x12, - DW_TAG_structure_type = 0x13, - DW_TAG_subroutine_type = 0x15, - DW_TAG_typedef = 0x16, - DW_TAG_union_type = 0x17, - DW_TAG_unspecified_parameters = 0x18, - DW_TAG_variant = 0x19, - DW_TAG_common_block = 0x1a, - DW_TAG_common_inclusion = 0x1b, - DW_TAG_inheritance = 0x1c, - DW_TAG_inlined_subroutine = 0x1d, - DW_TAG_module = 0x1e, - DW_TAG_ptr_to_member_type = 0x1f, - DW_TAG_set_type = 0x20, - DW_TAG_subrange_type = 0x21, - DW_TAG_with_stmt = 0x22, - DW_TAG_access_declaration = 0x23, - DW_TAG_base_type = 0x24, - DW_TAG_catch_block = 0x25, - DW_TAG_const_type = 0x26, - DW_TAG_constant = 0x27, - DW_TAG_enumerator = 0x28, - DW_TAG_file_type = 0x29, - DW_TAG_friend = 0x2a, - DW_TAG_namelist = 0x2b, - DW_TAG_namelist_item = 0x2c, - DW_TAG_packed_type = 0x2d, - DW_TAG_subprogram = 0x2e, - DW_TAG_template_type_param = 0x2f, - DW_TAG_template_value_param = 0x30, - DW_TAG_thrown_type = 0x31, - DW_TAG_try_block = 0x32, - DW_TAG_variant_part = 0x33, - DW_TAG_variable = 0x34, - DW_TAG_volatile_type = 0x35, - // DWARF 3. - DW_TAG_dwarf_procedure = 0x36, - DW_TAG_restrict_type = 0x37, - DW_TAG_interface_type = 0x38, - DW_TAG_namespace = 0x39, - DW_TAG_imported_module = 0x3a, - DW_TAG_unspecified_type = 0x3b, - DW_TAG_partial_unit = 0x3c, - DW_TAG_imported_unit = 0x3d, - // SGI/MIPS Extensions. - DW_TAG_MIPS_loop = 0x4081, - // HP extensions. See: - // ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz - DW_TAG_HP_array_descriptor = 0x4090, - // GNU extensions. - DW_TAG_format_label = 0x4101, // For FORTRAN 77 and Fortran 90. - DW_TAG_function_template = 0x4102, // For C++. - DW_TAG_class_template = 0x4103, // For C++. - DW_TAG_GNU_BINCL = 0x4104, - DW_TAG_GNU_EINCL = 0x4105, - // Extensions for UPC. See: http://upc.gwu.edu/~upc. - DW_TAG_upc_shared_type = 0x8765, - DW_TAG_upc_strict_type = 0x8766, - DW_TAG_upc_relaxed_type = 0x8767, - // PGI (STMicroelectronics) extensions. No documentation available. - DW_TAG_PGI_kanji_type = 0xA000, - DW_TAG_PGI_interface_block = 0xA020 -}; - - -enum DwarfHasChild { - DW_children_no = 0, - DW_children_yes = 1 -}; - -// Form names and codes. -enum DwarfForm { - DW_FORM_addr = 0x01, - DW_FORM_block2 = 0x03, - DW_FORM_block4 = 0x04, - DW_FORM_data2 = 0x05, - DW_FORM_data4 = 0x06, - DW_FORM_data8 = 0x07, - DW_FORM_string = 0x08, - DW_FORM_block = 0x09, - DW_FORM_block1 = 0x0a, - DW_FORM_data1 = 0x0b, - DW_FORM_flag = 0x0c, - DW_FORM_sdata = 0x0d, - DW_FORM_strp = 0x0e, - DW_FORM_udata = 0x0f, - DW_FORM_ref_addr = 0x10, - DW_FORM_ref1 = 0x11, - DW_FORM_ref2 = 0x12, - DW_FORM_ref4 = 0x13, - DW_FORM_ref8 = 0x14, - DW_FORM_ref_udata = 0x15, - DW_FORM_indirect = 0x16, - - // Added in DWARF 4: - DW_FORM_sec_offset = 0x17, - DW_FORM_exprloc = 0x18, - DW_FORM_flag_present = 0x19, - DW_FORM_ref_sig8 = 0x20, - // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. - DW_FORM_GNU_addr_index = 0x1f01, - DW_FORM_GNU_str_index = 0x1f02 -}; - -// Attribute names and codes -enum DwarfAttribute { - DW_AT_sibling = 0x01, - DW_AT_location = 0x02, - DW_AT_name = 0x03, - DW_AT_ordering = 0x09, - DW_AT_subscr_data = 0x0a, - DW_AT_byte_size = 0x0b, - DW_AT_bit_offset = 0x0c, - DW_AT_bit_size = 0x0d, - DW_AT_element_list = 0x0f, - DW_AT_stmt_list = 0x10, - DW_AT_low_pc = 0x11, - DW_AT_high_pc = 0x12, - DW_AT_language = 0x13, - DW_AT_member = 0x14, - DW_AT_discr = 0x15, - DW_AT_discr_value = 0x16, - DW_AT_visibility = 0x17, - DW_AT_import = 0x18, - DW_AT_string_length = 0x19, - DW_AT_common_reference = 0x1a, - DW_AT_comp_dir = 0x1b, - DW_AT_const_value = 0x1c, - DW_AT_containing_type = 0x1d, - DW_AT_default_value = 0x1e, - DW_AT_inline = 0x20, - DW_AT_is_optional = 0x21, - DW_AT_lower_bound = 0x22, - DW_AT_producer = 0x25, - DW_AT_prototyped = 0x27, - DW_AT_return_addr = 0x2a, - DW_AT_start_scope = 0x2c, - DW_AT_stride_size = 0x2e, - DW_AT_upper_bound = 0x2f, - DW_AT_abstract_origin = 0x31, - DW_AT_accessibility = 0x32, - DW_AT_address_class = 0x33, - DW_AT_artificial = 0x34, - DW_AT_base_types = 0x35, - DW_AT_calling_convention = 0x36, - DW_AT_count = 0x37, - DW_AT_data_member_location = 0x38, - DW_AT_decl_column = 0x39, - DW_AT_decl_file = 0x3a, - DW_AT_decl_line = 0x3b, - DW_AT_declaration = 0x3c, - DW_AT_discr_list = 0x3d, - DW_AT_encoding = 0x3e, - DW_AT_external = 0x3f, - DW_AT_frame_base = 0x40, - DW_AT_friend = 0x41, - DW_AT_identifier_case = 0x42, - DW_AT_macro_info = 0x43, - DW_AT_namelist_items = 0x44, - DW_AT_priority = 0x45, - DW_AT_segment = 0x46, - DW_AT_specification = 0x47, - DW_AT_static_link = 0x48, - DW_AT_type = 0x49, - DW_AT_use_location = 0x4a, - DW_AT_variable_parameter = 0x4b, - DW_AT_virtuality = 0x4c, - DW_AT_vtable_elem_location = 0x4d, - // DWARF 3 values. - DW_AT_allocated = 0x4e, - DW_AT_associated = 0x4f, - DW_AT_data_location = 0x50, - DW_AT_stride = 0x51, - DW_AT_entry_pc = 0x52, - DW_AT_use_UTF8 = 0x53, - DW_AT_extension = 0x54, - DW_AT_ranges = 0x55, - DW_AT_trampoline = 0x56, - DW_AT_call_column = 0x57, - DW_AT_call_file = 0x58, - DW_AT_call_line = 0x59, - // SGI/MIPS extensions. - DW_AT_MIPS_fde = 0x2001, - DW_AT_MIPS_loop_begin = 0x2002, - DW_AT_MIPS_tail_loop_begin = 0x2003, - DW_AT_MIPS_epilog_begin = 0x2004, - DW_AT_MIPS_loop_unroll_factor = 0x2005, - DW_AT_MIPS_software_pipeline_depth = 0x2006, - DW_AT_MIPS_linkage_name = 0x2007, - DW_AT_MIPS_stride = 0x2008, - DW_AT_MIPS_abstract_name = 0x2009, - DW_AT_MIPS_clone_origin = 0x200a, - DW_AT_MIPS_has_inlines = 0x200b, - // HP extensions. - DW_AT_HP_block_index = 0x2000, - DW_AT_HP_unmodifiable = 0x2001, // Same as DW_AT_MIPS_fde. - DW_AT_HP_actuals_stmt_list = 0x2010, - DW_AT_HP_proc_per_section = 0x2011, - DW_AT_HP_raw_data_ptr = 0x2012, - DW_AT_HP_pass_by_reference = 0x2013, - DW_AT_HP_opt_level = 0x2014, - DW_AT_HP_prof_version_id = 0x2015, - DW_AT_HP_opt_flags = 0x2016, - DW_AT_HP_cold_region_low_pc = 0x2017, - DW_AT_HP_cold_region_high_pc = 0x2018, - DW_AT_HP_all_variables_modifiable = 0x2019, - DW_AT_HP_linkage_name = 0x201a, - DW_AT_HP_prof_flags = 0x201b, // In comp unit of procs_info for -g. - // GNU extensions. - DW_AT_sf_names = 0x2101, - DW_AT_src_info = 0x2102, - DW_AT_mac_info = 0x2103, - DW_AT_src_coords = 0x2104, - DW_AT_body_begin = 0x2105, - DW_AT_body_end = 0x2106, - DW_AT_GNU_vector = 0x2107, - // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. - DW_AT_GNU_dwo_name = 0x2130, - DW_AT_GNU_dwo_id = 0x2131, - DW_AT_GNU_ranges_base = 0x2132, - DW_AT_GNU_addr_base = 0x2133, - DW_AT_GNU_pubnames = 0x2134, - DW_AT_GNU_pubtypes = 0x2135, - // VMS extensions. - DW_AT_VMS_rtnbeg_pd_address = 0x2201, - // UPC extension. - DW_AT_upc_threads_scaled = 0x3210, - // PGI (STMicroelectronics) extensions. - DW_AT_PGI_lbase = 0x3a00, - DW_AT_PGI_soffset = 0x3a01, - DW_AT_PGI_lstride = 0x3a02 -}; - - -// Line number opcodes. -enum DwarfLineNumberOps { - DW_LNS_extended_op = 0, - DW_LNS_copy = 1, - DW_LNS_advance_pc = 2, - DW_LNS_advance_line = 3, - DW_LNS_set_file = 4, - DW_LNS_set_column = 5, - DW_LNS_negate_stmt = 6, - DW_LNS_set_basic_block = 7, - DW_LNS_const_add_pc = 8, - DW_LNS_fixed_advance_pc = 9, - // DWARF 3. - DW_LNS_set_prologue_end = 10, - DW_LNS_set_epilogue_begin = 11, - DW_LNS_set_isa = 12 -}; - -// Line number extended opcodes. -enum DwarfLineNumberExtendedOps { - DW_LNE_end_sequence = 1, - DW_LNE_set_address = 2, - DW_LNE_define_file = 3, - // HP extensions. - DW_LNE_HP_negate_is_UV_update = 0x11, - DW_LNE_HP_push_context = 0x12, - DW_LNE_HP_pop_context = 0x13, - DW_LNE_HP_set_file_line_column = 0x14, - DW_LNE_HP_set_routine_name = 0x15, - DW_LNE_HP_set_sequence = 0x16, - DW_LNE_HP_negate_post_semantics = 0x17, - DW_LNE_HP_negate_function_exit = 0x18, - DW_LNE_HP_negate_front_end_logical = 0x19, - DW_LNE_HP_define_proc = 0x20 -}; - -// Type encoding names and codes -enum DwarfEncoding { - DW_ATE_address =0x1, - DW_ATE_boolean =0x2, - DW_ATE_complex_float =0x3, - DW_ATE_float =0x4, - DW_ATE_signed =0x5, - DW_ATE_signed_char =0x6, - DW_ATE_unsigned =0x7, - DW_ATE_unsigned_char =0x8, - // DWARF3/DWARF3f - DW_ATE_imaginary_float =0x9, - DW_ATE_packed_decimal =0xa, - DW_ATE_numeric_string =0xb, - DW_ATE_edited =0xc, - DW_ATE_signed_fixed =0xd, - DW_ATE_unsigned_fixed =0xe, - DW_ATE_decimal_float =0xf, - DW_ATE_lo_user =0x80, - DW_ATE_hi_user =0xff -}; - -// Location virtual machine opcodes -enum DwarfOpcode { - DW_OP_addr =0x03, - DW_OP_deref =0x06, - DW_OP_const1u =0x08, - DW_OP_const1s =0x09, - DW_OP_const2u =0x0a, - DW_OP_const2s =0x0b, - DW_OP_const4u =0x0c, - DW_OP_const4s =0x0d, - DW_OP_const8u =0x0e, - DW_OP_const8s =0x0f, - DW_OP_constu =0x10, - DW_OP_consts =0x11, - DW_OP_dup =0x12, - DW_OP_drop =0x13, - DW_OP_over =0x14, - DW_OP_pick =0x15, - DW_OP_swap =0x16, - DW_OP_rot =0x17, - DW_OP_xderef =0x18, - DW_OP_abs =0x19, - DW_OP_and =0x1a, - DW_OP_div =0x1b, - DW_OP_minus =0x1c, - DW_OP_mod =0x1d, - DW_OP_mul =0x1e, - DW_OP_neg =0x1f, - DW_OP_not =0x20, - DW_OP_or =0x21, - DW_OP_plus =0x22, - DW_OP_plus_uconst =0x23, - DW_OP_shl =0x24, - DW_OP_shr =0x25, - DW_OP_shra =0x26, - DW_OP_xor =0x27, - DW_OP_bra =0x28, - DW_OP_eq =0x29, - DW_OP_ge =0x2a, - DW_OP_gt =0x2b, - DW_OP_le =0x2c, - DW_OP_lt =0x2d, - DW_OP_ne =0x2e, - DW_OP_skip =0x2f, - DW_OP_lit0 =0x30, - DW_OP_lit1 =0x31, - DW_OP_lit2 =0x32, - DW_OP_lit3 =0x33, - DW_OP_lit4 =0x34, - DW_OP_lit5 =0x35, - DW_OP_lit6 =0x36, - DW_OP_lit7 =0x37, - DW_OP_lit8 =0x38, - DW_OP_lit9 =0x39, - DW_OP_lit10 =0x3a, - DW_OP_lit11 =0x3b, - DW_OP_lit12 =0x3c, - DW_OP_lit13 =0x3d, - DW_OP_lit14 =0x3e, - DW_OP_lit15 =0x3f, - DW_OP_lit16 =0x40, - DW_OP_lit17 =0x41, - DW_OP_lit18 =0x42, - DW_OP_lit19 =0x43, - DW_OP_lit20 =0x44, - DW_OP_lit21 =0x45, - DW_OP_lit22 =0x46, - DW_OP_lit23 =0x47, - DW_OP_lit24 =0x48, - DW_OP_lit25 =0x49, - DW_OP_lit26 =0x4a, - DW_OP_lit27 =0x4b, - DW_OP_lit28 =0x4c, - DW_OP_lit29 =0x4d, - DW_OP_lit30 =0x4e, - DW_OP_lit31 =0x4f, - DW_OP_reg0 =0x50, - DW_OP_reg1 =0x51, - DW_OP_reg2 =0x52, - DW_OP_reg3 =0x53, - DW_OP_reg4 =0x54, - DW_OP_reg5 =0x55, - DW_OP_reg6 =0x56, - DW_OP_reg7 =0x57, - DW_OP_reg8 =0x58, - DW_OP_reg9 =0x59, - DW_OP_reg10 =0x5a, - DW_OP_reg11 =0x5b, - DW_OP_reg12 =0x5c, - DW_OP_reg13 =0x5d, - DW_OP_reg14 =0x5e, - DW_OP_reg15 =0x5f, - DW_OP_reg16 =0x60, - DW_OP_reg17 =0x61, - DW_OP_reg18 =0x62, - DW_OP_reg19 =0x63, - DW_OP_reg20 =0x64, - DW_OP_reg21 =0x65, - DW_OP_reg22 =0x66, - DW_OP_reg23 =0x67, - DW_OP_reg24 =0x68, - DW_OP_reg25 =0x69, - DW_OP_reg26 =0x6a, - DW_OP_reg27 =0x6b, - DW_OP_reg28 =0x6c, - DW_OP_reg29 =0x6d, - DW_OP_reg30 =0x6e, - DW_OP_reg31 =0x6f, - DW_OP_breg0 =0x70, - DW_OP_breg1 =0x71, - DW_OP_breg2 =0x72, - DW_OP_breg3 =0x73, - DW_OP_breg4 =0x74, - DW_OP_breg5 =0x75, - DW_OP_breg6 =0x76, - DW_OP_breg7 =0x77, - DW_OP_breg8 =0x78, - DW_OP_breg9 =0x79, - DW_OP_breg10 =0x7a, - DW_OP_breg11 =0x7b, - DW_OP_breg12 =0x7c, - DW_OP_breg13 =0x7d, - DW_OP_breg14 =0x7e, - DW_OP_breg15 =0x7f, - DW_OP_breg16 =0x80, - DW_OP_breg17 =0x81, - DW_OP_breg18 =0x82, - DW_OP_breg19 =0x83, - DW_OP_breg20 =0x84, - DW_OP_breg21 =0x85, - DW_OP_breg22 =0x86, - DW_OP_breg23 =0x87, - DW_OP_breg24 =0x88, - DW_OP_breg25 =0x89, - DW_OP_breg26 =0x8a, - DW_OP_breg27 =0x8b, - DW_OP_breg28 =0x8c, - DW_OP_breg29 =0x8d, - DW_OP_breg30 =0x8e, - DW_OP_breg31 =0x8f, - DW_OP_regX =0x90, - DW_OP_fbreg =0x91, - DW_OP_bregX =0x92, - DW_OP_piece =0x93, - DW_OP_deref_size =0x94, - DW_OP_xderef_size =0x95, - DW_OP_nop =0x96, - // DWARF3/DWARF3f - DW_OP_push_object_address =0x97, - DW_OP_call2 =0x98, - DW_OP_call4 =0x99, - DW_OP_call_ref =0x9a, - DW_OP_form_tls_address =0x9b, - DW_OP_call_frame_cfa =0x9c, - DW_OP_bit_piece =0x9d, - DW_OP_lo_user =0xe0, - DW_OP_hi_user =0xff, - // GNU extensions - DW_OP_GNU_push_tls_address =0xe0, - // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. - DW_OP_GNU_addr_index =0xfb, - DW_OP_GNU_const_index =0xfc -}; - -// Section identifiers for DWP files -enum DwarfSectionId { - DW_SECT_INFO = 1, - DW_SECT_TYPES = 2, - DW_SECT_ABBREV = 3, - DW_SECT_LINE = 4, - DW_SECT_LOC = 5, - DW_SECT_STR_OFFSETS = 6, - DW_SECT_MACINFO = 7, - DW_SECT_MACRO = 8 -}; - -// Source languages. These are values for DW_AT_language. -enum DwarfLanguage - { - DW_LANG_none =0x0000, - DW_LANG_C89 =0x0001, - DW_LANG_C =0x0002, - DW_LANG_Ada83 =0x0003, - DW_LANG_C_plus_plus =0x0004, - DW_LANG_Cobol74 =0x0005, - DW_LANG_Cobol85 =0x0006, - DW_LANG_Fortran77 =0x0007, - DW_LANG_Fortran90 =0x0008, - DW_LANG_Pascal83 =0x0009, - DW_LANG_Modula2 =0x000a, - DW_LANG_Java =0x000b, - DW_LANG_C99 =0x000c, - DW_LANG_Ada95 =0x000d, - DW_LANG_Fortran95 =0x000e, - DW_LANG_PLI =0x000f, - DW_LANG_ObjC =0x0010, - DW_LANG_ObjC_plus_plus =0x0011, - DW_LANG_UPC =0x0012, - DW_LANG_D =0x0013, - // Implementation-defined language code range. - DW_LANG_lo_user = 0x8000, - DW_LANG_hi_user = 0xffff, - - // Extensions. - - // MIPS assembly language. The GNU toolchain uses this for all - // assembly languages, since there's no generic DW_LANG_ value for that. - // See include/dwarf2.h in the binutils, gdb, or gcc source trees. - DW_LANG_Mips_Assembler =0x8001, - DW_LANG_Upc =0x8765 // Unified Parallel C - }; - -// Inline codes. These are values for DW_AT_inline. -enum DwarfInline { - DW_INL_not_inlined =0x0, - DW_INL_inlined =0x1, - DW_INL_declared_not_inlined =0x2, - DW_INL_declared_inlined =0x3 -}; - -// Call Frame Info instructions. -enum DwarfCFI - { - DW_CFA_advance_loc = 0x40, - DW_CFA_offset = 0x80, - DW_CFA_restore = 0xc0, - DW_CFA_nop = 0x00, - DW_CFA_set_loc = 0x01, - DW_CFA_advance_loc1 = 0x02, - DW_CFA_advance_loc2 = 0x03, - DW_CFA_advance_loc4 = 0x04, - DW_CFA_offset_extended = 0x05, - DW_CFA_restore_extended = 0x06, - DW_CFA_undefined = 0x07, - DW_CFA_same_value = 0x08, - DW_CFA_register = 0x09, - DW_CFA_remember_state = 0x0a, - DW_CFA_restore_state = 0x0b, - DW_CFA_def_cfa = 0x0c, - DW_CFA_def_cfa_register = 0x0d, - DW_CFA_def_cfa_offset = 0x0e, - DW_CFA_def_cfa_expression = 0x0f, - DW_CFA_expression = 0x10, - DW_CFA_offset_extended_sf = 0x11, - DW_CFA_def_cfa_sf = 0x12, - DW_CFA_def_cfa_offset_sf = 0x13, - DW_CFA_val_offset = 0x14, - DW_CFA_val_offset_sf = 0x15, - DW_CFA_val_expression = 0x16, - - // Opcodes in this range are reserved for user extensions. - DW_CFA_lo_user = 0x1c, - DW_CFA_hi_user = 0x3f, - - // SGI/MIPS specific. - DW_CFA_MIPS_advance_loc8 = 0x1d, - - // GNU extensions. - DW_CFA_GNU_window_save = 0x2d, - DW_CFA_GNU_args_size = 0x2e, - DW_CFA_GNU_negative_offset_extended = 0x2f - }; - -// Exception handling 'z' augmentation letters. -enum DwarfZAugmentationCodes { - // If the CFI augmentation string begins with 'z', then the CIE and FDE - // have an augmentation data area just before the instructions, whose - // contents are determined by the subsequent augmentation letters. - DW_Z_augmentation_start = 'z', - - // If this letter is present in a 'z' augmentation string, the CIE - // augmentation data includes a pointer encoding, and the FDE - // augmentation data includes a language-specific data area pointer, - // represented using that encoding. - DW_Z_has_LSDA = 'L', - - // If this letter is present in a 'z' augmentation string, the CIE - // augmentation data includes a pointer encoding, followed by a pointer - // to a personality routine, represented using that encoding. - DW_Z_has_personality_routine = 'P', - - // If this letter is present in a 'z' augmentation string, the CIE - // augmentation data includes a pointer encoding describing how the FDE's - // initial location, address range, and DW_CFA_set_loc operands are - // encoded. - DW_Z_has_FDE_address_encoding = 'R', - - // If this letter is present in a 'z' augmentation string, then code - // addresses covered by FDEs that cite this CIE are signal delivery - // trampolines. Return addresses of frames in trampolines should not be - // adjusted as described in section 6.4.4 of the DWARF 3 spec. - DW_Z_is_signal_trampoline = 'S' -}; - -// Exception handling frame description pointer formats, as described -// by the Linux Standard Base Core Specification 4.0, section 11.5, -// DWARF Extensions. -enum DwarfPointerEncoding - { - DW_EH_PE_absptr = 0x00, - DW_EH_PE_omit = 0xff, - DW_EH_PE_uleb128 = 0x01, - DW_EH_PE_udata2 = 0x02, - DW_EH_PE_udata4 = 0x03, - DW_EH_PE_udata8 = 0x04, - DW_EH_PE_sleb128 = 0x09, - DW_EH_PE_sdata2 = 0x0A, - DW_EH_PE_sdata4 = 0x0B, - DW_EH_PE_sdata8 = 0x0C, - DW_EH_PE_pcrel = 0x10, - DW_EH_PE_textrel = 0x20, - DW_EH_PE_datarel = 0x30, - DW_EH_PE_funcrel = 0x40, - DW_EH_PE_aligned = 0x50, - - // The GNU toolchain sources define this enum value as well, - // simply to help classify the lower nybble values into signed and - // unsigned groups. - DW_EH_PE_signed = 0x08, - - // This is not documented in LSB 4.0, but it is used in both the - // Linux and OS X toolchains. It can be added to any other - // encoding (except DW_EH_PE_aligned), and indicates that the - // encoded value represents the address at which the true address - // is stored, not the true address itself. - DW_EH_PE_indirect = 0x80 - }; - -} // namespace dwarf2reader -#endif // COMMON_DWARF_DWARF2ENUMS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.cc deleted file mode 100644 index a65b43c8a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.cc +++ /dev/null @@ -1,2734 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// CFI reader author: Jim Blandy - -// Implementation of dwarf2reader::LineInfo, dwarf2reader::CompilationUnit, -// and dwarf2reader::CallFrameInfo. See dwarf2reader.h for details. - -#include "common/dwarf/dwarf2reader.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/bytereader.h" -#include "common/dwarf/line_state_machine.h" -#include "common/using_std_string.h" - -namespace dwarf2reader { - -CompilationUnit::CompilationUnit(const string& path, - const SectionMap& sections, uint64 offset, - ByteReader* reader, Dwarf2Handler* handler) - : path_(path), offset_from_section_start_(offset), reader_(reader), - sections_(sections), handler_(handler), abbrevs_(), - string_buffer_(NULL), string_buffer_length_(0), - str_offsets_buffer_(NULL), str_offsets_buffer_length_(0), - addr_buffer_(NULL), addr_buffer_length_(0), - is_split_dwarf_(false), dwo_id_(0), dwo_name_(), - skeleton_dwo_id_(0), ranges_base_(0), addr_base_(0), - have_checked_for_dwp_(false), dwp_path_(), - dwp_byte_reader_(), dwp_reader_() {} - -// Initialize a compilation unit from a .dwo or .dwp file. -// In this case, we need the .debug_addr section from the -// executable file that contains the corresponding skeleton -// compilation unit. We also inherit the Dwarf2Handler from -// the executable file, and call it as if we were still -// processing the original compilation unit. - -void CompilationUnit::SetSplitDwarf(const uint8_t* addr_buffer, - uint64 addr_buffer_length, - uint64 addr_base, - uint64 ranges_base, - uint64 dwo_id) { - is_split_dwarf_ = true; - addr_buffer_ = addr_buffer; - addr_buffer_length_ = addr_buffer_length; - addr_base_ = addr_base; - ranges_base_ = ranges_base; - skeleton_dwo_id_ = dwo_id; -} - -// Read a DWARF2/3 abbreviation section. -// Each abbrev consists of a abbreviation number, a tag, a byte -// specifying whether the tag has children, and a list of -// attribute/form pairs. -// The list of forms is terminated by a 0 for the attribute, and a -// zero for the form. The entire abbreviation section is terminated -// by a zero for the code. - -void CompilationUnit::ReadAbbrevs() { - if (abbrevs_) - return; - - // First get the debug_abbrev section. ".debug_abbrev" is the name - // recommended in the DWARF spec, and used on Linux; - // "__debug_abbrev" is the name used in Mac OS X Mach-O files. - SectionMap::const_iterator iter = sections_.find(".debug_abbrev"); - if (iter == sections_.end()) - iter = sections_.find("__debug_abbrev"); - assert(iter != sections_.end()); - - abbrevs_ = new std::vector; - abbrevs_->resize(1); - - // The only way to check whether we are reading over the end of the - // buffer would be to first compute the size of the leb128 data by - // reading it, then go back and read it again. - const uint8_t *abbrev_start = iter->second.first + - header_.abbrev_offset; - const uint8_t *abbrevptr = abbrev_start; -#ifndef NDEBUG - const uint64 abbrev_length = iter->second.second - header_.abbrev_offset; -#endif - - while (1) { - CompilationUnit::Abbrev abbrev; - size_t len; - const uint64 number = reader_->ReadUnsignedLEB128(abbrevptr, &len); - - if (number == 0) - break; - abbrev.number = number; - abbrevptr += len; - - assert(abbrevptr < abbrev_start + abbrev_length); - const uint64 tag = reader_->ReadUnsignedLEB128(abbrevptr, &len); - abbrevptr += len; - abbrev.tag = static_cast(tag); - - assert(abbrevptr < abbrev_start + abbrev_length); - abbrev.has_children = reader_->ReadOneByte(abbrevptr); - abbrevptr += 1; - - assert(abbrevptr < abbrev_start + abbrev_length); - - while (1) { - const uint64 nametemp = reader_->ReadUnsignedLEB128(abbrevptr, &len); - abbrevptr += len; - - assert(abbrevptr < abbrev_start + abbrev_length); - const uint64 formtemp = reader_->ReadUnsignedLEB128(abbrevptr, &len); - abbrevptr += len; - if (nametemp == 0 && formtemp == 0) - break; - - const enum DwarfAttribute name = - static_cast(nametemp); - const enum DwarfForm form = static_cast(formtemp); - abbrev.attributes.push_back(std::make_pair(name, form)); - } - assert(abbrev.number == abbrevs_->size()); - abbrevs_->push_back(abbrev); - } -} - -// Skips a single DIE's attributes. -const uint8_t *CompilationUnit::SkipDIE(const uint8_t* start, - const Abbrev& abbrev) { - for (AttributeList::const_iterator i = abbrev.attributes.begin(); - i != abbrev.attributes.end(); - i++) { - start = SkipAttribute(start, i->second); - } - return start; -} - -// Skips a single attribute form's data. -const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start, - enum DwarfForm form) { - size_t len; - - switch (form) { - case DW_FORM_indirect: - form = static_cast(reader_->ReadUnsignedLEB128(start, - &len)); - start += len; - return SkipAttribute(start, form); - - case DW_FORM_flag_present: - return start; - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - return start + 1; - case DW_FORM_ref2: - case DW_FORM_data2: - return start + 2; - case DW_FORM_ref4: - case DW_FORM_data4: - return start + 4; - case DW_FORM_ref8: - case DW_FORM_data8: - case DW_FORM_ref_sig8: - return start + 8; - case DW_FORM_string: - return start + strlen(reinterpret_cast(start)) + 1; - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_str_index: - case DW_FORM_GNU_addr_index: - reader_->ReadUnsignedLEB128(start, &len); - return start + len; - - case DW_FORM_sdata: - reader_->ReadSignedLEB128(start, &len); - return start + len; - case DW_FORM_addr: - return start + reader_->AddressSize(); - case DW_FORM_ref_addr: - // DWARF2 and 3/4 differ on whether ref_addr is address size or - // offset size. - assert(header_.version >= 2); - if (header_.version == 2) { - return start + reader_->AddressSize(); - } else if (header_.version >= 3) { - return start + reader_->OffsetSize(); - } - break; - - case DW_FORM_block1: - return start + 1 + reader_->ReadOneByte(start); - case DW_FORM_block2: - return start + 2 + reader_->ReadTwoBytes(start); - case DW_FORM_block4: - return start + 4 + reader_->ReadFourBytes(start); - case DW_FORM_block: - case DW_FORM_exprloc: { - uint64 size = reader_->ReadUnsignedLEB128(start, &len); - return start + size + len; - } - case DW_FORM_strp: - case DW_FORM_sec_offset: - return start + reader_->OffsetSize(); - } - fprintf(stderr,"Unhandled form type"); - return NULL; -} - -// Read a DWARF2/3 header. -// The header is variable length in DWARF3 (and DWARF2 as extended by -// most compilers), and consists of an length field, a version number, -// the offset in the .debug_abbrev section for our abbrevs, and an -// address size. -void CompilationUnit::ReadHeader() { - const uint8_t *headerptr = buffer_; - size_t initial_length_size; - - assert(headerptr + 4 < buffer_ + buffer_length_); - const uint64 initial_length - = reader_->ReadInitialLength(headerptr, &initial_length_size); - headerptr += initial_length_size; - header_.length = initial_length; - - assert(headerptr + 2 < buffer_ + buffer_length_); - header_.version = reader_->ReadTwoBytes(headerptr); - headerptr += 2; - - assert(headerptr + reader_->OffsetSize() < buffer_ + buffer_length_); - header_.abbrev_offset = reader_->ReadOffset(headerptr); - headerptr += reader_->OffsetSize(); - - // Compare against less than or equal because this may be the last - // section in the file. - assert(headerptr + 1 <= buffer_ + buffer_length_); - header_.address_size = reader_->ReadOneByte(headerptr); - reader_->SetAddressSize(header_.address_size); - headerptr += 1; - - after_header_ = headerptr; - - // This check ensures that we don't have to do checking during the - // reading of DIEs. header_.length does not include the size of the - // initial length. - assert(buffer_ + initial_length_size + header_.length <= - buffer_ + buffer_length_); -} - -uint64 CompilationUnit::Start() { - // First get the debug_info section. ".debug_info" is the name - // recommended in the DWARF spec, and used on Linux; "__debug_info" - // is the name used in Mac OS X Mach-O files. - SectionMap::const_iterator iter = sections_.find(".debug_info"); - if (iter == sections_.end()) - iter = sections_.find("__debug_info"); - assert(iter != sections_.end()); - - // Set up our buffer - buffer_ = iter->second.first + offset_from_section_start_; - buffer_length_ = iter->second.second - offset_from_section_start_; - - // Read the header - ReadHeader(); - - // Figure out the real length from the end of the initial length to - // the end of the compilation unit, since that is the value we - // return. - uint64 ourlength = header_.length; - if (reader_->OffsetSize() == 8) - ourlength += 12; - else - ourlength += 4; - - // See if the user wants this compilation unit, and if not, just return. - if (!handler_->StartCompilationUnit(offset_from_section_start_, - reader_->AddressSize(), - reader_->OffsetSize(), - header_.length, - header_.version)) - return ourlength; - - // Otherwise, continue by reading our abbreviation entries. - ReadAbbrevs(); - - // Set the string section if we have one. ".debug_str" is the name - // recommended in the DWARF spec, and used on Linux; "__debug_str" - // is the name used in Mac OS X Mach-O files. - iter = sections_.find(".debug_str"); - if (iter == sections_.end()) - iter = sections_.find("__debug_str"); - if (iter != sections_.end()) { - string_buffer_ = iter->second.first; - string_buffer_length_ = iter->second.second; - } - - // Set the string offsets section if we have one. - iter = sections_.find(".debug_str_offsets"); - if (iter != sections_.end()) { - str_offsets_buffer_ = iter->second.first; - str_offsets_buffer_length_ = iter->second.second; - } - - // Set the address section if we have one. - iter = sections_.find(".debug_addr"); - if (iter != sections_.end()) { - addr_buffer_ = iter->second.first; - addr_buffer_length_ = iter->second.second; - } - - // Now that we have our abbreviations, start processing DIE's. - ProcessDIEs(); - - // If this is a skeleton compilation unit generated with split DWARF, - // and the client needs the full debug info, we need to find the full - // compilation unit in a .dwo or .dwp file. - if (!is_split_dwarf_ - && dwo_name_ != NULL - && handler_->NeedSplitDebugInfo()) - ProcessSplitDwarf(); - - return ourlength; -} - -// If one really wanted, you could merge SkipAttribute and -// ProcessAttribute -// This is all boring data manipulation and calling of the handler. -const uint8_t *CompilationUnit::ProcessAttribute( - uint64 dieoffset, const uint8_t *start, enum DwarfAttribute attr, - enum DwarfForm form) { - size_t len; - - switch (form) { - // DW_FORM_indirect is never used because it is such a space - // waster. - case DW_FORM_indirect: - form = static_cast(reader_->ReadUnsignedLEB128(start, - &len)); - start += len; - return ProcessAttribute(dieoffset, start, attr, form); - - case DW_FORM_flag_present: - ProcessAttributeUnsigned(dieoffset, attr, form, 1); - return start; - case DW_FORM_data1: - case DW_FORM_flag: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadOneByte(start)); - return start + 1; - case DW_FORM_data2: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadTwoBytes(start)); - return start + 2; - case DW_FORM_data4: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadFourBytes(start)); - return start + 4; - case DW_FORM_data8: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadEightBytes(start)); - return start + 8; - case DW_FORM_string: { - const char *str = reinterpret_cast(start); - ProcessAttributeString(dieoffset, attr, form, str); - return start + strlen(str) + 1; - } - case DW_FORM_udata: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadUnsignedLEB128(start, &len)); - return start + len; - - case DW_FORM_sdata: - ProcessAttributeSigned(dieoffset, attr, form, - reader_->ReadSignedLEB128(start, &len)); - return start + len; - case DW_FORM_addr: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadAddress(start)); - return start + reader_->AddressSize(); - case DW_FORM_sec_offset: - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadOffset(start)); - return start + reader_->OffsetSize(); - - case DW_FORM_ref1: - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadOneByte(start) - + offset_from_section_start_); - return start + 1; - case DW_FORM_ref2: - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadTwoBytes(start) - + offset_from_section_start_); - return start + 2; - case DW_FORM_ref4: - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadFourBytes(start) - + offset_from_section_start_); - return start + 4; - case DW_FORM_ref8: - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadEightBytes(start) - + offset_from_section_start_); - return start + 8; - case DW_FORM_ref_udata: - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadUnsignedLEB128(start, - &len) - + offset_from_section_start_); - return start + len; - case DW_FORM_ref_addr: - // DWARF2 and 3/4 differ on whether ref_addr is address size or - // offset size. - assert(header_.version >= 2); - if (header_.version == 2) { - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadAddress(start)); - return start + reader_->AddressSize(); - } else if (header_.version >= 3) { - handler_->ProcessAttributeReference(dieoffset, attr, form, - reader_->ReadOffset(start)); - return start + reader_->OffsetSize(); - } - break; - case DW_FORM_ref_sig8: - handler_->ProcessAttributeSignature(dieoffset, attr, form, - reader_->ReadEightBytes(start)); - return start + 8; - - case DW_FORM_block1: { - uint64 datalen = reader_->ReadOneByte(start); - handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 1, - datalen); - return start + 1 + datalen; - } - case DW_FORM_block2: { - uint64 datalen = reader_->ReadTwoBytes(start); - handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 2, - datalen); - return start + 2 + datalen; - } - case DW_FORM_block4: { - uint64 datalen = reader_->ReadFourBytes(start); - handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 4, - datalen); - return start + 4 + datalen; - } - case DW_FORM_block: - case DW_FORM_exprloc: { - uint64 datalen = reader_->ReadUnsignedLEB128(start, &len); - handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len, - datalen); - return start + datalen + len; - } - case DW_FORM_strp: { - assert(string_buffer_ != NULL); - - const uint64 offset = reader_->ReadOffset(start); - assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); - - const char *str = reinterpret_cast(string_buffer_ + offset); - ProcessAttributeString(dieoffset, attr, form, str); - return start + reader_->OffsetSize(); - } - - case DW_FORM_GNU_str_index: { - uint64 str_index = reader_->ReadUnsignedLEB128(start, &len); - const uint8_t* offset_ptr = - str_offsets_buffer_ + str_index * reader_->OffsetSize(); - const uint64 offset = reader_->ReadOffset(offset_ptr); - if (offset >= string_buffer_length_) { - return NULL; - } - - const char* str = reinterpret_cast(string_buffer_) + offset; - ProcessAttributeString(dieoffset, attr, form, str); - return start + len; - break; - } - case DW_FORM_GNU_addr_index: { - uint64 addr_index = reader_->ReadUnsignedLEB128(start, &len); - const uint8_t* addr_ptr = - addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize(); - ProcessAttributeUnsigned(dieoffset, attr, form, - reader_->ReadAddress(addr_ptr)); - return start + len; - } - } - fprintf(stderr, "Unhandled form type\n"); - return NULL; -} - -const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset, - const uint8_t *start, - const Abbrev& abbrev) { - for (AttributeList::const_iterator i = abbrev.attributes.begin(); - i != abbrev.attributes.end(); - i++) { - start = ProcessAttribute(dieoffset, start, i->first, i->second); - } - - // If this is a compilation unit in a split DWARF object, verify that - // the dwo_id matches. If it does not match, we will ignore this - // compilation unit. - if (abbrev.tag == DW_TAG_compile_unit - && is_split_dwarf_ - && dwo_id_ != skeleton_dwo_id_) { - return NULL; - } - - return start; -} - -void CompilationUnit::ProcessDIEs() { - const uint8_t *dieptr = after_header_; - size_t len; - - // lengthstart is the place the length field is based on. - // It is the point in the header after the initial length field - const uint8_t *lengthstart = buffer_; - - // In 64 bit dwarf, the initial length is 12 bytes, because of the - // 0xffffffff at the start. - if (reader_->OffsetSize() == 8) - lengthstart += 12; - else - lengthstart += 4; - - std::stack die_stack; - - while (dieptr < (lengthstart + header_.length)) { - // We give the user the absolute offset from the beginning of - // debug_info, since they need it to deal with ref_addr forms. - uint64 absolute_offset = (dieptr - buffer_) + offset_from_section_start_; - - uint64 abbrev_num = reader_->ReadUnsignedLEB128(dieptr, &len); - - dieptr += len; - - // Abbrev == 0 represents the end of a list of children, or padding - // at the end of the compilation unit. - if (abbrev_num == 0) { - if (die_stack.size() == 0) - // If it is padding, then we are done with the compilation unit's DIEs. - return; - const uint64 offset = die_stack.top(); - die_stack.pop(); - handler_->EndDIE(offset); - continue; - } - - const Abbrev& abbrev = abbrevs_->at(static_cast(abbrev_num)); - const enum DwarfTag tag = abbrev.tag; - if (!handler_->StartDIE(absolute_offset, tag)) { - dieptr = SkipDIE(dieptr, abbrev); - } else { - dieptr = ProcessDIE(absolute_offset, dieptr, abbrev); - } - - if (abbrev.has_children) { - die_stack.push(absolute_offset); - } else { - handler_->EndDIE(absolute_offset); - } - } -} - -// Check for a valid ELF file and return the Address size. -// Returns 0 if not a valid ELF file. -inline int GetElfWidth(const ElfReader& elf) { - if (elf.IsElf32File()) - return 4; - if (elf.IsElf64File()) - return 8; - return 0; -} - -void CompilationUnit::ProcessSplitDwarf() { - struct stat statbuf; - if (!have_checked_for_dwp_) { - // Look for a .dwp file in the same directory as the executable. - have_checked_for_dwp_ = true; - string dwp_suffix(".dwp"); - dwp_path_ = path_ + dwp_suffix; - if (stat(dwp_path_.c_str(), &statbuf) != 0) { - // Fall back to a split .debug file in the same directory. - string debug_suffix(".debug"); - dwp_path_ = path_; - size_t found = path_.rfind(debug_suffix); - if (found + debug_suffix.length() == path_.length()) - dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix); - } - if (stat(dwp_path_.c_str(), &statbuf) == 0) { - ElfReader* elf = new ElfReader(dwp_path_); - int width = GetElfWidth(*elf); - if (width != 0) { - dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness())); - dwp_byte_reader_->SetAddressSize(width); - dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf)); - dwp_reader_->Initialize(); - } else { - delete elf; - } - } - } - bool found_in_dwp = false; - if (dwp_reader_) { - // If we have a .dwp file, read the debug sections for the requested CU. - SectionMap sections; - dwp_reader_->ReadDebugSectionsForCU(dwo_id_, §ions); - if (!sections.empty()) { - found_in_dwp = true; - CompilationUnit dwp_comp_unit(dwp_path_, sections, 0, - dwp_byte_reader_.get(), handler_); - dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_, - ranges_base_, dwo_id_); - dwp_comp_unit.Start(); - } - } - if (!found_in_dwp) { - // If no .dwp file, try to open the .dwo file. - if (stat(dwo_name_, &statbuf) == 0) { - ElfReader elf(dwo_name_); - int width = GetElfWidth(elf); - if (width != 0) { - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(width); - SectionMap sections; - ReadDebugSectionsFromDwo(&elf, §ions); - CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader, - handler_); - dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, - addr_base_, ranges_base_, dwo_id_); - dwo_comp_unit.Start(); - } - } - } -} - -void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader, - SectionMap* sections) { - static const char* const section_names[] = { - ".debug_abbrev", - ".debug_info", - ".debug_str_offsets", - ".debug_str" - }; - for (unsigned int i = 0u; - i < sizeof(section_names)/sizeof(*(section_names)); ++i) { - string base_name = section_names[i]; - string dwo_name = base_name + ".dwo"; - size_t section_size; - const char* section_data = elf_reader->GetSectionByName(dwo_name, - §ion_size); - if (section_data != NULL) - sections->insert(std::make_pair( - base_name, std::make_pair( - reinterpret_cast(section_data), - section_size))); - } -} - -DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader) - : elf_reader_(elf_reader), byte_reader_(byte_reader), - cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL), - string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0), - nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL), - offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL), - abbrev_size_(0), info_data_(NULL), info_size_(0), - str_offsets_data_(NULL), str_offsets_size_(0) {} - -DwpReader::~DwpReader() { - if (elf_reader_) delete elf_reader_; -} - -void DwpReader::Initialize() { - cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index", - &cu_index_size_); - if (cu_index_ == NULL) { - return; - } - // The .debug_str.dwo section is shared by all CUs in the file. - string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo", - &string_buffer_size_); - - version_ = byte_reader_.ReadFourBytes( - reinterpret_cast(cu_index_)); - - if (version_ == 1) { - nslots_ = byte_reader_.ReadFourBytes( - reinterpret_cast(cu_index_) - + 3 * sizeof(uint32)); - phash_ = cu_index_ + 4 * sizeof(uint32); - pindex_ = phash_ + nslots_ * sizeof(uint64); - shndx_pool_ = pindex_ + nslots_ * sizeof(uint32); - if (shndx_pool_ >= cu_index_ + cu_index_size_) { - version_ = 0; - } - } else if (version_ == 2) { - ncolumns_ = byte_reader_.ReadFourBytes( - reinterpret_cast(cu_index_) + sizeof(uint32)); - nunits_ = byte_reader_.ReadFourBytes( - reinterpret_cast(cu_index_) + 2 * sizeof(uint32)); - nslots_ = byte_reader_.ReadFourBytes( - reinterpret_cast(cu_index_) + 3 * sizeof(uint32)); - phash_ = cu_index_ + 4 * sizeof(uint32); - pindex_ = phash_ + nslots_ * sizeof(uint64); - offset_table_ = pindex_ + nslots_ * sizeof(uint32); - size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32); - abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo", - &abbrev_size_); - info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_); - str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo", - &str_offsets_size_); - if (size_table_ >= cu_index_ + cu_index_size_) { - version_ = 0; - } - } -} - -void DwpReader::ReadDebugSectionsForCU(uint64 dwo_id, - SectionMap* sections) { - if (version_ == 1) { - int slot = LookupCU(dwo_id); - if (slot == -1) { - return; - } - - // The index table points to the section index pool, where we - // can read a list of section indexes for the debug sections - // for the CU whose dwo_id we are looking for. - int index = byte_reader_.ReadFourBytes( - reinterpret_cast(pindex_) - + slot * sizeof(uint32)); - const char* shndx_list = shndx_pool_ + index * sizeof(uint32); - for (;;) { - if (shndx_list >= cu_index_ + cu_index_size_) { - version_ = 0; - return; - } - unsigned int shndx = byte_reader_.ReadFourBytes( - reinterpret_cast(shndx_list)); - shndx_list += sizeof(uint32); - if (shndx == 0) - break; - const char* section_name = elf_reader_->GetSectionName(shndx); - size_t section_size; - const char* section_data; - // We're only interested in these four debug sections. - // The section names in the .dwo file end with ".dwo", but we - // add them to the sections table with their normal names. - if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) { - section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size); - sections->insert(std::make_pair( - ".debug_abbrev", - std::make_pair(reinterpret_cast (section_data), - section_size))); - } else if (!strncmp(section_name, ".debug_info", strlen(".debug_info"))) { - section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size); - sections->insert(std::make_pair( - ".debug_info", - std::make_pair(reinterpret_cast (section_data), - section_size))); - } else if (!strncmp(section_name, ".debug_str_offsets", - strlen(".debug_str_offsets"))) { - section_data = elf_reader_->GetSectionByIndex(shndx, §ion_size); - sections->insert(std::make_pair( - ".debug_str_offsets", - std::make_pair(reinterpret_cast (section_data), - section_size))); - } - } - sections->insert(std::make_pair( - ".debug_str", - std::make_pair(reinterpret_cast (string_buffer_), - string_buffer_size_))); - } else if (version_ == 2) { - uint32 index = LookupCUv2(dwo_id); - if (index == 0) { - return; - } - - // The index points to a row in each of the section offsets table - // and the section size table, where we can read the offsets and sizes - // of the contributions to each debug section from the CU whose dwo_id - // we are looking for. Row 0 of the section offsets table has the - // section ids for each column of the table. The size table begins - // with row 1. - const char* id_row = offset_table_; - const char* offset_row = offset_table_ - + index * ncolumns_ * sizeof(uint32); - const char* size_row = - size_table_ + (index - 1) * ncolumns_ * sizeof(uint32); - if (size_row + ncolumns_ * sizeof(uint32) > cu_index_ + cu_index_size_) { - version_ = 0; - return; - } - for (unsigned int col = 0u; col < ncolumns_; ++col) { - uint32 section_id = - byte_reader_.ReadFourBytes(reinterpret_cast(id_row) - + col * sizeof(uint32)); - uint32 offset = byte_reader_.ReadFourBytes( - reinterpret_cast(offset_row) - + col * sizeof(uint32)); - uint32 size = byte_reader_.ReadFourBytes( - reinterpret_cast(size_row) + col * sizeof(uint32)); - if (section_id == DW_SECT_ABBREV) { - sections->insert(std::make_pair( - ".debug_abbrev", - std::make_pair(reinterpret_cast (abbrev_data_) - + offset, size))); - } else if (section_id == DW_SECT_INFO) { - sections->insert(std::make_pair( - ".debug_info", - std::make_pair(reinterpret_cast (info_data_) - + offset, size))); - } else if (section_id == DW_SECT_STR_OFFSETS) { - sections->insert(std::make_pair( - ".debug_str_offsets", - std::make_pair(reinterpret_cast (str_offsets_data_) - + offset, size))); - } - } - sections->insert(std::make_pair( - ".debug_str", - std::make_pair(reinterpret_cast (string_buffer_), - string_buffer_size_))); - } -} - -int DwpReader::LookupCU(uint64 dwo_id) { - uint32 slot = static_cast(dwo_id) & (nslots_ - 1); - uint64 probe = byte_reader_.ReadEightBytes( - reinterpret_cast(phash_) + slot * sizeof(uint64)); - if (probe != 0 && probe != dwo_id) { - uint32 secondary_hash = - (static_cast(dwo_id >> 32) & (nslots_ - 1)) | 1; - do { - slot = (slot + secondary_hash) & (nslots_ - 1); - probe = byte_reader_.ReadEightBytes( - reinterpret_cast(phash_) + slot * sizeof(uint64)); - } while (probe != 0 && probe != dwo_id); - } - if (probe == 0) - return -1; - return slot; -} - -uint32 DwpReader::LookupCUv2(uint64 dwo_id) { - uint32 slot = static_cast(dwo_id) & (nslots_ - 1); - uint64 probe = byte_reader_.ReadEightBytes( - reinterpret_cast(phash_) + slot * sizeof(uint64)); - uint32 index = byte_reader_.ReadFourBytes( - reinterpret_cast(pindex_) + slot * sizeof(uint32)); - if (index != 0 && probe != dwo_id) { - uint32 secondary_hash = - (static_cast(dwo_id >> 32) & (nslots_ - 1)) | 1; - do { - slot = (slot + secondary_hash) & (nslots_ - 1); - probe = byte_reader_.ReadEightBytes( - reinterpret_cast(phash_) + slot * sizeof(uint64)); - index = byte_reader_.ReadFourBytes( - reinterpret_cast(pindex_) + slot * sizeof(uint32)); - } while (index != 0 && probe != dwo_id); - } - return index; -} - -LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length, - ByteReader* reader, LineInfoHandler* handler): - handler_(handler), reader_(reader), buffer_(buffer) { -#ifndef NDEBUG - buffer_length_ = buffer_length; -#endif - header_.std_opcode_lengths = NULL; -} - -uint64 LineInfo::Start() { - ReadHeader(); - ReadLines(); - return after_header_ - buffer_; -} - -// The header for a debug_line section is mildly complicated, because -// the line info is very tightly encoded. -void LineInfo::ReadHeader() { - const uint8_t *lineptr = buffer_; - size_t initial_length_size; - - const uint64 initial_length - = reader_->ReadInitialLength(lineptr, &initial_length_size); - - lineptr += initial_length_size; - header_.total_length = initial_length; - assert(buffer_ + initial_length_size + header_.total_length <= - buffer_ + buffer_length_); - - // Address size *must* be set by CU ahead of time. - assert(reader_->AddressSize() != 0); - - header_.version = reader_->ReadTwoBytes(lineptr); - lineptr += 2; - - header_.prologue_length = reader_->ReadOffset(lineptr); - lineptr += reader_->OffsetSize(); - - header_.min_insn_length = reader_->ReadOneByte(lineptr); - lineptr += 1; - - header_.default_is_stmt = reader_->ReadOneByte(lineptr); - lineptr += 1; - - header_.line_base = *reinterpret_cast(lineptr); - lineptr += 1; - - header_.line_range = reader_->ReadOneByte(lineptr); - lineptr += 1; - - header_.opcode_base = reader_->ReadOneByte(lineptr); - lineptr += 1; - - header_.std_opcode_lengths = new std::vector; - header_.std_opcode_lengths->resize(header_.opcode_base + 1); - (*header_.std_opcode_lengths)[0] = 0; - for (int i = 1; i < header_.opcode_base; i++) { - (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr); - lineptr += 1; - } - - // It is legal for the directory entry table to be empty. - if (*lineptr) { - uint32 dirindex = 1; - while (*lineptr) { - const char *dirname = reinterpret_cast(lineptr); - handler_->DefineDir(dirname, dirindex); - lineptr += strlen(dirname) + 1; - dirindex++; - } - } - lineptr++; - - // It is also legal for the file entry table to be empty. - if (*lineptr) { - uint32 fileindex = 1; - size_t len; - while (*lineptr) { - const char *filename = reinterpret_cast(lineptr); - lineptr += strlen(filename) + 1; - - uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len); - lineptr += len; - - uint64 mod_time = reader_->ReadUnsignedLEB128(lineptr, &len); - lineptr += len; - - uint64 filelength = reader_->ReadUnsignedLEB128(lineptr, &len); - lineptr += len; - handler_->DefineFile(filename, fileindex, static_cast(dirindex), - mod_time, filelength); - fileindex++; - } - } - lineptr++; - - after_header_ = lineptr; -} - -/* static */ -bool LineInfo::ProcessOneOpcode(ByteReader* reader, - LineInfoHandler* handler, - const struct LineInfoHeader &header, - const uint8_t *start, - struct LineStateMachine* lsm, - size_t* len, - uintptr pc, - bool *lsm_passes_pc) { - size_t oplen = 0; - size_t templen; - uint8 opcode = reader->ReadOneByte(start); - oplen++; - start++; - - // If the opcode is great than the opcode_base, it is a special - // opcode. Most line programs consist mainly of special opcodes. - if (opcode >= header.opcode_base) { - opcode -= header.opcode_base; - const int64 advance_address = (opcode / header.line_range) - * header.min_insn_length; - const int32 advance_line = (opcode % header.line_range) - + header.line_base; - - // Check if the lsm passes "pc". If so, mark it as passed. - if (lsm_passes_pc && - lsm->address <= pc && pc < lsm->address + advance_address) { - *lsm_passes_pc = true; - } - - lsm->address += advance_address; - lsm->line_num += advance_line; - lsm->basic_block = true; - *len = oplen; - return true; - } - - // Otherwise, we have the regular opcodes - switch (opcode) { - case DW_LNS_copy: { - lsm->basic_block = false; - *len = oplen; - return true; - } - - case DW_LNS_advance_pc: { - uint64 advance_address = reader->ReadUnsignedLEB128(start, &templen); - oplen += templen; - - // Check if the lsm passes "pc". If so, mark it as passed. - if (lsm_passes_pc && lsm->address <= pc && - pc < lsm->address + header.min_insn_length * advance_address) { - *lsm_passes_pc = true; - } - - lsm->address += header.min_insn_length * advance_address; - } - break; - case DW_LNS_advance_line: { - const int64 advance_line = reader->ReadSignedLEB128(start, &templen); - oplen += templen; - lsm->line_num += static_cast(advance_line); - - // With gcc 4.2.1, we can get the line_no here for the first time - // since DW_LNS_advance_line is called after DW_LNE_set_address is - // called. So we check if the lsm passes "pc" here, not in - // DW_LNE_set_address. - if (lsm_passes_pc && lsm->address == pc) { - *lsm_passes_pc = true; - } - } - break; - case DW_LNS_set_file: { - const uint64 fileno = reader->ReadUnsignedLEB128(start, &templen); - oplen += templen; - lsm->file_num = static_cast(fileno); - } - break; - case DW_LNS_set_column: { - const uint64 colno = reader->ReadUnsignedLEB128(start, &templen); - oplen += templen; - lsm->column_num = static_cast(colno); - } - break; - case DW_LNS_negate_stmt: { - lsm->is_stmt = !lsm->is_stmt; - } - break; - case DW_LNS_set_basic_block: { - lsm->basic_block = true; - } - break; - case DW_LNS_fixed_advance_pc: { - const uint16 advance_address = reader->ReadTwoBytes(start); - oplen += 2; - - // Check if the lsm passes "pc". If so, mark it as passed. - if (lsm_passes_pc && - lsm->address <= pc && pc < lsm->address + advance_address) { - *lsm_passes_pc = true; - } - - lsm->address += advance_address; - } - break; - case DW_LNS_const_add_pc: { - const int64 advance_address = header.min_insn_length - * ((255 - header.opcode_base) - / header.line_range); - - // Check if the lsm passes "pc". If so, mark it as passed. - if (lsm_passes_pc && - lsm->address <= pc && pc < lsm->address + advance_address) { - *lsm_passes_pc = true; - } - - lsm->address += advance_address; - } - break; - case DW_LNS_extended_op: { - const uint64 extended_op_len = reader->ReadUnsignedLEB128(start, - &templen); - start += templen; - oplen += templen + extended_op_len; - - const uint64 extended_op = reader->ReadOneByte(start); - start++; - - switch (extended_op) { - case DW_LNE_end_sequence: { - lsm->end_sequence = true; - *len = oplen; - return true; - } - break; - case DW_LNE_set_address: { - // With gcc 4.2.1, we cannot tell the line_no here since - // DW_LNE_set_address is called before DW_LNS_advance_line is - // called. So we do not check if the lsm passes "pc" here. See - // also the comment in DW_LNS_advance_line. - uint64 address = reader->ReadAddress(start); - lsm->address = address; - } - break; - case DW_LNE_define_file: { - const char *filename = reinterpret_cast(start); - - templen = strlen(filename) + 1; - start += templen; - - uint64 dirindex = reader->ReadUnsignedLEB128(start, &templen); - oplen += templen; - - const uint64 mod_time = reader->ReadUnsignedLEB128(start, - &templen); - oplen += templen; - - const uint64 filelength = reader->ReadUnsignedLEB128(start, - &templen); - oplen += templen; - - if (handler) { - handler->DefineFile(filename, -1, static_cast(dirindex), - mod_time, filelength); - } - } - break; - } - } - break; - - default: { - // Ignore unknown opcode silently - if (header.std_opcode_lengths) { - for (int i = 0; i < (*header.std_opcode_lengths)[opcode]; i++) { - reader->ReadUnsignedLEB128(start, &templen); - start += templen; - oplen += templen; - } - } - } - break; - } - *len = oplen; - return false; -} - -void LineInfo::ReadLines() { - struct LineStateMachine lsm; - - // lengthstart is the place the length field is based on. - // It is the point in the header after the initial length field - const uint8_t *lengthstart = buffer_; - - // In 64 bit dwarf, the initial length is 12 bytes, because of the - // 0xffffffff at the start. - if (reader_->OffsetSize() == 8) - lengthstart += 12; - else - lengthstart += 4; - - const uint8_t *lineptr = after_header_; - lsm.Reset(header_.default_is_stmt); - - // The LineInfoHandler interface expects each line's length along - // with its address, but DWARF only provides addresses (sans - // length), and an end-of-sequence address; one infers the length - // from the next address. So we report a line only when we get the - // next line's address, or the end-of-sequence address. - bool have_pending_line = false; - uint64 pending_address = 0; - uint32 pending_file_num = 0, pending_line_num = 0, pending_column_num = 0; - - while (lineptr < lengthstart + header_.total_length) { - size_t oplength; - bool add_row = ProcessOneOpcode(reader_, handler_, header_, - lineptr, &lsm, &oplength, (uintptr)-1, - NULL); - if (add_row) { - if (have_pending_line) - handler_->AddLine(pending_address, lsm.address - pending_address, - pending_file_num, pending_line_num, - pending_column_num); - if (lsm.end_sequence) { - lsm.Reset(header_.default_is_stmt); - have_pending_line = false; - } else { - pending_address = lsm.address; - pending_file_num = lsm.file_num; - pending_line_num = lsm.line_num; - pending_column_num = lsm.column_num; - have_pending_line = true; - } - } - lineptr += oplength; - } - - after_header_ = lengthstart + header_.total_length; -} - -// A DWARF rule for recovering the address or value of a register, or -// computing the canonical frame address. There is one subclass of this for -// each '*Rule' member function in CallFrameInfo::Handler. -// -// It's annoying that we have to handle Rules using pointers (because -// the concrete instances can have an arbitrary size). They're small, -// so it would be much nicer if we could just handle them by value -// instead of fretting about ownership and destruction. -// -// It seems like all these could simply be instances of std::tr1::bind, -// except that we need instances to be EqualityComparable, too. -// -// This could logically be nested within State, but then the qualified names -// get horrendous. -class CallFrameInfo::Rule { - public: - virtual ~Rule() { } - - // Tell HANDLER that, at ADDRESS in the program, REGISTER can be - // recovered using this rule. If REGISTER is kCFARegister, then this rule - // describes how to compute the canonical frame address. Return what the - // HANDLER member function returned. - virtual bool Handle(Handler *handler, - uint64 address, int register) const = 0; - - // Equality on rules. We use these to decide which rules we need - // to report after a DW_CFA_restore_state instruction. - virtual bool operator==(const Rule &rhs) const = 0; - - bool operator!=(const Rule &rhs) const { return ! (*this == rhs); } - - // Return a pointer to a copy of this rule. - virtual Rule *Copy() const = 0; - - // If this is a base+offset rule, change its base register to REG. - // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.) - virtual void SetBaseRegister(unsigned reg) { } - - // If this is a base+offset rule, change its offset to OFFSET. Otherwise, - // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.) - virtual void SetOffset(long long offset) { } -}; - -// Rule: the value the register had in the caller cannot be recovered. -class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule { - public: - UndefinedRule() { } - ~UndefinedRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->UndefinedRule(address, reg); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const UndefinedRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs != NULL); - } - Rule *Copy() const { return new UndefinedRule(*this); } -}; - -// Rule: the register's value is the same as that it had in the caller. -class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule { - public: - SameValueRule() { } - ~SameValueRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->SameValueRule(address, reg); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const SameValueRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs != NULL); - } - Rule *Copy() const { return new SameValueRule(*this); } -}; - -// Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER -// may be CallFrameInfo::Handler::kCFARegister. -class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule { - public: - OffsetRule(int base_register, long offset) - : base_register_(base_register), offset_(offset) { } - ~OffsetRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->OffsetRule(address, reg, base_register_, offset_); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const OffsetRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs && - base_register_ == our_rhs->base_register_ && - offset_ == our_rhs->offset_); - } - Rule *Copy() const { return new OffsetRule(*this); } - // We don't actually need SetBaseRegister or SetOffset here, since they - // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it - // doesn't make sense to use OffsetRule for computing the CFA: it - // computes the address at which a register is saved, not a value. - private: - int base_register_; - long offset_; -}; - -// Rule: the value the register had in the caller is the value of -// BASE_REGISTER plus offset. BASE_REGISTER may be -// CallFrameInfo::Handler::kCFARegister. -class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule { - public: - ValOffsetRule(int base_register, long offset) - : base_register_(base_register), offset_(offset) { } - ~ValOffsetRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->ValOffsetRule(address, reg, base_register_, offset_); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const ValOffsetRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs && - base_register_ == our_rhs->base_register_ && - offset_ == our_rhs->offset_); - } - Rule *Copy() const { return new ValOffsetRule(*this); } - void SetBaseRegister(unsigned reg) { base_register_ = reg; } - void SetOffset(long long offset) { offset_ = offset; } - private: - int base_register_; - long offset_; -}; - -// Rule: the register has been saved in another register REGISTER_NUMBER_. -class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule { - public: - explicit RegisterRule(int register_number) - : register_number_(register_number) { } - ~RegisterRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->RegisterRule(address, reg, register_number_); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const RegisterRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs && register_number_ == our_rhs->register_number_); - } - Rule *Copy() const { return new RegisterRule(*this); } - private: - int register_number_; -}; - -// Rule: EXPRESSION evaluates to the address at which the register is saved. -class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule { - public: - explicit ExpressionRule(const string &expression) - : expression_(expression) { } - ~ExpressionRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->ExpressionRule(address, reg, expression_); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const ExpressionRule *our_rhs = dynamic_cast(&rhs); - return (our_rhs && expression_ == our_rhs->expression_); - } - Rule *Copy() const { return new ExpressionRule(*this); } - private: - string expression_; -}; - -// Rule: EXPRESSION evaluates to the address at which the register is saved. -class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule { - public: - explicit ValExpressionRule(const string &expression) - : expression_(expression) { } - ~ValExpressionRule() { } - bool Handle(Handler *handler, uint64 address, int reg) const { - return handler->ValExpressionRule(address, reg, expression_); - } - bool operator==(const Rule &rhs) const { - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has - // been carefully considered; cheap RTTI-like workarounds are forbidden. - const ValExpressionRule *our_rhs = - dynamic_cast(&rhs); - return (our_rhs && expression_ == our_rhs->expression_); - } - Rule *Copy() const { return new ValExpressionRule(*this); } - private: - string expression_; -}; - -// A map from register numbers to rules. -class CallFrameInfo::RuleMap { - public: - RuleMap() : cfa_rule_(NULL) { } - RuleMap(const RuleMap &rhs) : cfa_rule_(NULL) { *this = rhs; } - ~RuleMap() { Clear(); } - - RuleMap &operator=(const RuleMap &rhs); - - // Set the rule for computing the CFA to RULE. Take ownership of RULE. - void SetCFARule(Rule *rule) { delete cfa_rule_; cfa_rule_ = rule; } - - // Return the current CFA rule. Unlike RegisterRule, this RuleMap retains - // ownership of the rule. We use this for DW_CFA_def_cfa_offset and - // DW_CFA_def_cfa_register, and for detecting references to the CFA before - // a rule for it has been established. - Rule *CFARule() const { return cfa_rule_; } - - // Return the rule for REG, or NULL if there is none. The caller takes - // ownership of the result. - Rule *RegisterRule(int reg) const; - - // Set the rule for computing REG to RULE. Take ownership of RULE. - void SetRegisterRule(int reg, Rule *rule); - - // Make all the appropriate calls to HANDLER as if we were changing from - // this RuleMap to NEW_RULES at ADDRESS. We use this to implement - // DW_CFA_restore_state, where lots of rules can change simultaneously. - // Return true if all handlers returned true; otherwise, return false. - bool HandleTransitionTo(Handler *handler, uint64 address, - const RuleMap &new_rules) const; - - private: - // A map from register numbers to Rules. - typedef std::map RuleByNumber; - - // Remove all register rules and clear cfa_rule_. - void Clear(); - - // The rule for computing the canonical frame address. This RuleMap owns - // this rule. - Rule *cfa_rule_; - - // A map from register numbers to postfix expressions to recover - // their values. This RuleMap owns the Rules the map refers to. - RuleByNumber registers_; -}; - -CallFrameInfo::RuleMap &CallFrameInfo::RuleMap::operator=(const RuleMap &rhs) { - Clear(); - // Since each map owns the rules it refers to, assignment must copy them. - if (rhs.cfa_rule_) cfa_rule_ = rhs.cfa_rule_->Copy(); - for (RuleByNumber::const_iterator it = rhs.registers_.begin(); - it != rhs.registers_.end(); it++) - registers_[it->first] = it->second->Copy(); - return *this; -} - -CallFrameInfo::Rule *CallFrameInfo::RuleMap::RegisterRule(int reg) const { - assert(reg != Handler::kCFARegister); - RuleByNumber::const_iterator it = registers_.find(reg); - if (it != registers_.end()) - return it->second->Copy(); - else - return NULL; -} - -void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule *rule) { - assert(reg != Handler::kCFARegister); - assert(rule); - Rule **slot = ®isters_[reg]; - delete *slot; - *slot = rule; -} - -bool CallFrameInfo::RuleMap::HandleTransitionTo( - Handler *handler, - uint64 address, - const RuleMap &new_rules) const { - // Transition from cfa_rule_ to new_rules.cfa_rule_. - if (cfa_rule_ && new_rules.cfa_rule_) { - if (*cfa_rule_ != *new_rules.cfa_rule_ && - !new_rules.cfa_rule_->Handle(handler, address, - Handler::kCFARegister)) - return false; - } else if (cfa_rule_) { - // this RuleMap has a CFA rule but new_rules doesn't. - // CallFrameInfo::Handler has no way to handle this --- and shouldn't; - // it's garbage input. The instruction interpreter should have - // detected this and warned, so take no action here. - } else if (new_rules.cfa_rule_) { - // This shouldn't be possible: NEW_RULES is some prior state, and - // there's no way to remove entries. - assert(0); - } else { - // Both CFA rules are empty. No action needed. - } - - // Traverse the two maps in order by register number, and report - // whatever differences we find. - RuleByNumber::const_iterator old_it = registers_.begin(); - RuleByNumber::const_iterator new_it = new_rules.registers_.begin(); - while (old_it != registers_.end() && new_it != new_rules.registers_.end()) { - if (old_it->first < new_it->first) { - // This RuleMap has an entry for old_it->first, but NEW_RULES - // doesn't. - // - // This isn't really the right thing to do, but since CFI generally - // only mentions callee-saves registers, and GCC's convention for - // callee-saves registers is that they are unchanged, it's a good - // approximation. - if (!handler->SameValueRule(address, old_it->first)) - return false; - old_it++; - } else if (old_it->first > new_it->first) { - // NEW_RULES has entry for new_it->first, but this RuleMap - // doesn't. This shouldn't be possible: NEW_RULES is some prior - // state, and there's no way to remove entries. - assert(0); - } else { - // Both maps have an entry for this register. Report the new - // rule if it is different. - if (*old_it->second != *new_it->second && - !new_it->second->Handle(handler, address, new_it->first)) - return false; - new_it++, old_it++; - } - } - // Finish off entries from this RuleMap with no counterparts in new_rules. - while (old_it != registers_.end()) { - if (!handler->SameValueRule(address, old_it->first)) - return false; - old_it++; - } - // Since we only make transitions from a rule set to some previously - // saved rule set, and we can only add rules to the map, NEW_RULES - // must have fewer rules than *this. - assert(new_it == new_rules.registers_.end()); - - return true; -} - -// Remove all register rules and clear cfa_rule_. -void CallFrameInfo::RuleMap::Clear() { - delete cfa_rule_; - cfa_rule_ = NULL; - for (RuleByNumber::iterator it = registers_.begin(); - it != registers_.end(); it++) - delete it->second; - registers_.clear(); -} - -// The state of the call frame information interpreter as it processes -// instructions from a CIE and FDE. -class CallFrameInfo::State { - public: - // Create a call frame information interpreter state with the given - // reporter, reader, handler, and initial call frame info address. - State(ByteReader *reader, Handler *handler, Reporter *reporter, - uint64 address) - : reader_(reader), handler_(handler), reporter_(reporter), - address_(address), entry_(NULL), cursor_(NULL) { } - - // Interpret instructions from CIE, save the resulting rule set for - // DW_CFA_restore instructions, and return true. On error, report - // the problem to reporter_ and return false. - bool InterpretCIE(const CIE &cie); - - // Interpret instructions from FDE, and return true. On error, - // report the problem to reporter_ and return false. - bool InterpretFDE(const FDE &fde); - - private: - // The operands of a CFI instruction, for ParseOperands. - struct Operands { - unsigned register_number; // A register number. - uint64 offset; // An offset or address. - long signed_offset; // A signed offset. - string expression; // A DWARF expression. - }; - - // Parse CFI instruction operands from STATE's instruction stream as - // described by FORMAT. On success, populate OPERANDS with the - // results, and return true. On failure, report the problem and - // return false. - // - // Each character of FORMAT should be one of the following: - // - // 'r' unsigned LEB128 register number (OPERANDS->register_number) - // 'o' unsigned LEB128 offset (OPERANDS->offset) - // 's' signed LEB128 offset (OPERANDS->signed_offset) - // 'a' machine-size address (OPERANDS->offset) - // (If the CIE has a 'z' augmentation string, 'a' uses the - // encoding specified by the 'R' argument.) - // '1' a one-byte offset (OPERANDS->offset) - // '2' a two-byte offset (OPERANDS->offset) - // '4' a four-byte offset (OPERANDS->offset) - // '8' an eight-byte offset (OPERANDS->offset) - // 'e' a DW_FORM_block holding a (OPERANDS->expression) - // DWARF expression - bool ParseOperands(const char *format, Operands *operands); - - // Interpret one CFI instruction from STATE's instruction stream, update - // STATE, report any rule changes to handler_, and return true. On - // failure, report the problem and return false. - bool DoInstruction(); - - // The following Do* member functions are subroutines of DoInstruction, - // factoring out the actual work of operations that have several - // different encodings. - - // Set the CFA rule to be the value of BASE_REGISTER plus OFFSET, and - // return true. On failure, report and return false. (Used for - // DW_CFA_def_cfa and DW_CFA_def_cfa_sf.) - bool DoDefCFA(unsigned base_register, long offset); - - // Change the offset of the CFA rule to OFFSET, and return true. On - // failure, report and return false. (Subroutine for - // DW_CFA_def_cfa_offset and DW_CFA_def_cfa_offset_sf.) - bool DoDefCFAOffset(long offset); - - // Specify that REG can be recovered using RULE, and return true. On - // failure, report and return false. - bool DoRule(unsigned reg, Rule *rule); - - // Specify that REG can be found at OFFSET from the CFA, and return true. - // On failure, report and return false. (Subroutine for DW_CFA_offset, - // DW_CFA_offset_extended, and DW_CFA_offset_extended_sf.) - bool DoOffset(unsigned reg, long offset); - - // Specify that the caller's value for REG is the CFA plus OFFSET, - // and return true. On failure, report and return false. (Subroutine - // for DW_CFA_val_offset and DW_CFA_val_offset_sf.) - bool DoValOffset(unsigned reg, long offset); - - // Restore REG to the rule established in the CIE, and return true. On - // failure, report and return false. (Subroutine for DW_CFA_restore and - // DW_CFA_restore_extended.) - bool DoRestore(unsigned reg); - - // Return the section offset of the instruction at cursor. For use - // in error messages. - uint64 CursorOffset() { return entry_->offset + (cursor_ - entry_->start); } - - // Report that entry_ is incomplete, and return false. For brevity. - bool ReportIncomplete() { - reporter_->Incomplete(entry_->offset, entry_->kind); - return false; - } - - // For reading multi-byte values with the appropriate endianness. - ByteReader *reader_; - - // The handler to which we should report the data we find. - Handler *handler_; - - // For reporting problems in the info we're parsing. - Reporter *reporter_; - - // The code address to which the next instruction in the stream applies. - uint64 address_; - - // The entry whose instructions we are currently processing. This is - // first a CIE, and then an FDE. - const Entry *entry_; - - // The next instruction to process. - const uint8_t *cursor_; - - // The current set of rules. - RuleMap rules_; - - // The set of rules established by the CIE, used by DW_CFA_restore - // and DW_CFA_restore_extended. We set this after interpreting the - // CIE's instructions. - RuleMap cie_rules_; - - // A stack of saved states, for DW_CFA_remember_state and - // DW_CFA_restore_state. - std::stack saved_rules_; -}; - -bool CallFrameInfo::State::InterpretCIE(const CIE &cie) { - entry_ = &cie; - cursor_ = entry_->instructions; - while (cursor_ < entry_->end) - if (!DoInstruction()) - return false; - // Note the rules established by the CIE, for use by DW_CFA_restore - // and DW_CFA_restore_extended. - cie_rules_ = rules_; - return true; -} - -bool CallFrameInfo::State::InterpretFDE(const FDE &fde) { - entry_ = &fde; - cursor_ = entry_->instructions; - while (cursor_ < entry_->end) - if (!DoInstruction()) - return false; - return true; -} - -bool CallFrameInfo::State::ParseOperands(const char *format, - Operands *operands) { - size_t len; - const char *operand; - - for (operand = format; *operand; operand++) { - size_t bytes_left = entry_->end - cursor_; - switch (*operand) { - case 'r': - operands->register_number = reader_->ReadUnsignedLEB128(cursor_, &len); - if (len > bytes_left) return ReportIncomplete(); - cursor_ += len; - break; - - case 'o': - operands->offset = reader_->ReadUnsignedLEB128(cursor_, &len); - if (len > bytes_left) return ReportIncomplete(); - cursor_ += len; - break; - - case 's': - operands->signed_offset = reader_->ReadSignedLEB128(cursor_, &len); - if (len > bytes_left) return ReportIncomplete(); - cursor_ += len; - break; - - case 'a': - operands->offset = - reader_->ReadEncodedPointer(cursor_, entry_->cie->pointer_encoding, - &len); - if (len > bytes_left) return ReportIncomplete(); - cursor_ += len; - break; - - case '1': - if (1 > bytes_left) return ReportIncomplete(); - operands->offset = static_cast(*cursor_++); - break; - - case '2': - if (2 > bytes_left) return ReportIncomplete(); - operands->offset = reader_->ReadTwoBytes(cursor_); - cursor_ += 2; - break; - - case '4': - if (4 > bytes_left) return ReportIncomplete(); - operands->offset = reader_->ReadFourBytes(cursor_); - cursor_ += 4; - break; - - case '8': - if (8 > bytes_left) return ReportIncomplete(); - operands->offset = reader_->ReadEightBytes(cursor_); - cursor_ += 8; - break; - - case 'e': { - size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len); - if (len > bytes_left || expression_length > bytes_left - len) - return ReportIncomplete(); - cursor_ += len; - operands->expression = string(reinterpret_cast(cursor_), - expression_length); - cursor_ += expression_length; - break; - } - - default: - assert(0); - } - } - - return true; -} - -bool CallFrameInfo::State::DoInstruction() { - CIE *cie = entry_->cie; - Operands ops; - - // Our entry's kind should have been set by now. - assert(entry_->kind != kUnknown); - - // We shouldn't have been invoked unless there were more - // instructions to parse. - assert(cursor_ < entry_->end); - - unsigned opcode = *cursor_++; - if ((opcode & 0xc0) != 0) { - switch (opcode & 0xc0) { - // Advance the address. - case DW_CFA_advance_loc: { - size_t code_offset = opcode & 0x3f; - address_ += code_offset * cie->code_alignment_factor; - break; - } - - // Find a register at an offset from the CFA. - case DW_CFA_offset: - if (!ParseOperands("o", &ops) || - !DoOffset(opcode & 0x3f, ops.offset * cie->data_alignment_factor)) - return false; - break; - - // Restore the rule established for a register by the CIE. - case DW_CFA_restore: - if (!DoRestore(opcode & 0x3f)) return false; - break; - - // The 'if' above should have excluded this possibility. - default: - assert(0); - } - - // Return here, so the big switch below won't be indented. - return true; - } - - switch (opcode) { - // Set the address. - case DW_CFA_set_loc: - if (!ParseOperands("a", &ops)) return false; - address_ = ops.offset; - break; - - // Advance the address. - case DW_CFA_advance_loc1: - if (!ParseOperands("1", &ops)) return false; - address_ += ops.offset * cie->code_alignment_factor; - break; - - // Advance the address. - case DW_CFA_advance_loc2: - if (!ParseOperands("2", &ops)) return false; - address_ += ops.offset * cie->code_alignment_factor; - break; - - // Advance the address. - case DW_CFA_advance_loc4: - if (!ParseOperands("4", &ops)) return false; - address_ += ops.offset * cie->code_alignment_factor; - break; - - // Advance the address. - case DW_CFA_MIPS_advance_loc8: - if (!ParseOperands("8", &ops)) return false; - address_ += ops.offset * cie->code_alignment_factor; - break; - - // Compute the CFA by adding an offset to a register. - case DW_CFA_def_cfa: - if (!ParseOperands("ro", &ops) || - !DoDefCFA(ops.register_number, ops.offset)) - return false; - break; - - // Compute the CFA by adding an offset to a register. - case DW_CFA_def_cfa_sf: - if (!ParseOperands("rs", &ops) || - !DoDefCFA(ops.register_number, - ops.signed_offset * cie->data_alignment_factor)) - return false; - break; - - // Change the base register used to compute the CFA. - case DW_CFA_def_cfa_register: { - if (!ParseOperands("r", &ops)) return false; - Rule *cfa_rule = rules_.CFARule(); - if (!cfa_rule) { - if (!DoDefCFA(ops.register_number, ops.offset)) { - reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset()); - return false; - } - } else { - cfa_rule->SetBaseRegister(ops.register_number); - if (!cfa_rule->Handle(handler_, address_, - Handler::kCFARegister)) - return false; - } - break; - } - - // Change the offset used to compute the CFA. - case DW_CFA_def_cfa_offset: - if (!ParseOperands("o", &ops) || - !DoDefCFAOffset(ops.offset)) - return false; - break; - - // Change the offset used to compute the CFA. - case DW_CFA_def_cfa_offset_sf: - if (!ParseOperands("s", &ops) || - !DoDefCFAOffset(ops.signed_offset * cie->data_alignment_factor)) - return false; - break; - - // Specify an expression whose value is the CFA. - case DW_CFA_def_cfa_expression: { - if (!ParseOperands("e", &ops)) - return false; - Rule *rule = new ValExpressionRule(ops.expression); - rules_.SetCFARule(rule); - if (!rule->Handle(handler_, address_, - Handler::kCFARegister)) - return false; - break; - } - - // The register's value cannot be recovered. - case DW_CFA_undefined: { - if (!ParseOperands("r", &ops) || - !DoRule(ops.register_number, new UndefinedRule())) - return false; - break; - } - - // The register's value is unchanged from its value in the caller. - case DW_CFA_same_value: { - if (!ParseOperands("r", &ops) || - !DoRule(ops.register_number, new SameValueRule())) - return false; - break; - } - - // Find a register at an offset from the CFA. - case DW_CFA_offset_extended: - if (!ParseOperands("ro", &ops) || - !DoOffset(ops.register_number, - ops.offset * cie->data_alignment_factor)) - return false; - break; - - // The register is saved at an offset from the CFA. - case DW_CFA_offset_extended_sf: - if (!ParseOperands("rs", &ops) || - !DoOffset(ops.register_number, - ops.signed_offset * cie->data_alignment_factor)) - return false; - break; - - // The register is saved at an offset from the CFA. - case DW_CFA_GNU_negative_offset_extended: - if (!ParseOperands("ro", &ops) || - !DoOffset(ops.register_number, - -ops.offset * cie->data_alignment_factor)) - return false; - break; - - // The register's value is the sum of the CFA plus an offset. - case DW_CFA_val_offset: - if (!ParseOperands("ro", &ops) || - !DoValOffset(ops.register_number, - ops.offset * cie->data_alignment_factor)) - return false; - break; - - // The register's value is the sum of the CFA plus an offset. - case DW_CFA_val_offset_sf: - if (!ParseOperands("rs", &ops) || - !DoValOffset(ops.register_number, - ops.signed_offset * cie->data_alignment_factor)) - return false; - break; - - // The register has been saved in another register. - case DW_CFA_register: { - if (!ParseOperands("ro", &ops) || - !DoRule(ops.register_number, new RegisterRule(ops.offset))) - return false; - break; - } - - // An expression yields the address at which the register is saved. - case DW_CFA_expression: { - if (!ParseOperands("re", &ops) || - !DoRule(ops.register_number, new ExpressionRule(ops.expression))) - return false; - break; - } - - // An expression yields the caller's value for the register. - case DW_CFA_val_expression: { - if (!ParseOperands("re", &ops) || - !DoRule(ops.register_number, new ValExpressionRule(ops.expression))) - return false; - break; - } - - // Restore the rule established for a register by the CIE. - case DW_CFA_restore_extended: - if (!ParseOperands("r", &ops) || - !DoRestore( ops.register_number)) - return false; - break; - - // Save the current set of rules on a stack. - case DW_CFA_remember_state: - saved_rules_.push(rules_); - break; - - // Pop the current set of rules off the stack. - case DW_CFA_restore_state: { - if (saved_rules_.empty()) { - reporter_->EmptyStateStack(entry_->offset, entry_->kind, - CursorOffset()); - return false; - } - const RuleMap &new_rules = saved_rules_.top(); - if (rules_.CFARule() && !new_rules.CFARule()) { - reporter_->ClearingCFARule(entry_->offset, entry_->kind, - CursorOffset()); - return false; - } - rules_.HandleTransitionTo(handler_, address_, new_rules); - rules_ = new_rules; - saved_rules_.pop(); - break; - } - - // No operation. (Padding instruction.) - case DW_CFA_nop: - break; - - // A SPARC register window save: Registers 8 through 15 (%o0-%o7) - // are saved in registers 24 through 31 (%i0-%i7), and registers - // 16 through 31 (%l0-%l7 and %i0-%i7) are saved at CFA offsets - // (0-15 * the register size). The register numbers must be - // hard-coded. A GNU extension, and not a pretty one. - case DW_CFA_GNU_window_save: { - // Save %o0-%o7 in %i0-%i7. - for (int i = 8; i < 16; i++) - if (!DoRule(i, new RegisterRule(i + 16))) - return false; - // Save %l0-%l7 and %i0-%i7 at the CFA. - for (int i = 16; i < 32; i++) - // Assume that the byte reader's address size is the same as - // the architecture's register size. !@#%*^ hilarious. - if (!DoRule(i, new OffsetRule(Handler::kCFARegister, - (i - 16) * reader_->AddressSize()))) - return false; - break; - } - - // I'm not sure what this is. GDB doesn't use it for unwinding. - case DW_CFA_GNU_args_size: - if (!ParseOperands("o", &ops)) return false; - break; - - // An opcode we don't recognize. - default: { - reporter_->BadInstruction(entry_->offset, entry_->kind, CursorOffset()); - return false; - } - } - - return true; -} - -bool CallFrameInfo::State::DoDefCFA(unsigned base_register, long offset) { - Rule *rule = new ValOffsetRule(base_register, offset); - rules_.SetCFARule(rule); - return rule->Handle(handler_, address_, - Handler::kCFARegister); -} - -bool CallFrameInfo::State::DoDefCFAOffset(long offset) { - Rule *cfa_rule = rules_.CFARule(); - if (!cfa_rule) { - reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset()); - return false; - } - cfa_rule->SetOffset(offset); - return cfa_rule->Handle(handler_, address_, - Handler::kCFARegister); -} - -bool CallFrameInfo::State::DoRule(unsigned reg, Rule *rule) { - rules_.SetRegisterRule(reg, rule); - return rule->Handle(handler_, address_, reg); -} - -bool CallFrameInfo::State::DoOffset(unsigned reg, long offset) { - if (!rules_.CFARule()) { - reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset()); - return false; - } - return DoRule(reg, - new OffsetRule(Handler::kCFARegister, offset)); -} - -bool CallFrameInfo::State::DoValOffset(unsigned reg, long offset) { - if (!rules_.CFARule()) { - reporter_->NoCFARule(entry_->offset, entry_->kind, CursorOffset()); - return false; - } - return DoRule(reg, - new ValOffsetRule(Handler::kCFARegister, offset)); -} - -bool CallFrameInfo::State::DoRestore(unsigned reg) { - // DW_CFA_restore and DW_CFA_restore_extended don't make sense in a CIE. - if (entry_->kind == kCIE) { - reporter_->RestoreInCIE(entry_->offset, CursorOffset()); - return false; - } - Rule *rule = cie_rules_.RegisterRule(reg); - if (!rule) { - // This isn't really the right thing to do, but since CFI generally - // only mentions callee-saves registers, and GCC's convention for - // callee-saves registers is that they are unchanged, it's a good - // approximation. - rule = new SameValueRule(); - } - return DoRule(reg, rule); -} - -bool CallFrameInfo::ReadEntryPrologue(const uint8_t *cursor, Entry *entry) { - const uint8_t *buffer_end = buffer_ + buffer_length_; - - // Initialize enough of ENTRY for use in error reporting. - entry->offset = cursor - buffer_; - entry->start = cursor; - entry->kind = kUnknown; - entry->end = NULL; - - // Read the initial length. This sets reader_'s offset size. - size_t length_size; - uint64 length = reader_->ReadInitialLength(cursor, &length_size); - if (length_size > size_t(buffer_end - cursor)) - return ReportIncomplete(entry); - cursor += length_size; - - // In a .eh_frame section, a length of zero marks the end of the series - // of entries. - if (length == 0 && eh_frame_) { - entry->kind = kTerminator; - entry->end = cursor; - return true; - } - - // Validate the length. - if (length > size_t(buffer_end - cursor)) - return ReportIncomplete(entry); - - // The length is the number of bytes after the initial length field; - // we have that position handy at this point, so compute the end - // now. (If we're parsing 64-bit-offset DWARF on a 32-bit machine, - // and the length didn't fit in a size_t, we would have rejected it - // above.) - entry->end = cursor + length; - - // Parse the next field: either the offset of a CIE or a CIE id. - size_t offset_size = reader_->OffsetSize(); - if (offset_size > size_t(entry->end - cursor)) return ReportIncomplete(entry); - entry->id = reader_->ReadOffset(cursor); - - // Don't advance cursor past id field yet; in .eh_frame data we need - // the id's position to compute the section offset of an FDE's CIE. - - // Now we can decide what kind of entry this is. - if (eh_frame_) { - // In .eh_frame data, an ID of zero marks the entry as a CIE, and - // anything else is an offset from the id field of the FDE to the start - // of the CIE. - if (entry->id == 0) { - entry->kind = kCIE; - } else { - entry->kind = kFDE; - // Turn the offset from the id into an offset from the buffer's start. - entry->id = (cursor - buffer_) - entry->id; - } - } else { - // In DWARF CFI data, an ID of ~0 (of the appropriate width, given the - // offset size for the entry) marks the entry as a CIE, and anything - // else is the offset of the CIE from the beginning of the section. - if (offset_size == 4) - entry->kind = (entry->id == 0xffffffff) ? kCIE : kFDE; - else { - assert(offset_size == 8); - entry->kind = (entry->id == 0xffffffffffffffffULL) ? kCIE : kFDE; - } - } - - // Now advance cursor past the id. - cursor += offset_size; - - // The fields specific to this kind of entry start here. - entry->fields = cursor; - - entry->cie = NULL; - - return true; -} - -bool CallFrameInfo::ReadCIEFields(CIE *cie) { - const uint8_t *cursor = cie->fields; - size_t len; - - assert(cie->kind == kCIE); - - // Prepare for early exit. - cie->version = 0; - cie->augmentation.clear(); - cie->code_alignment_factor = 0; - cie->data_alignment_factor = 0; - cie->return_address_register = 0; - cie->has_z_augmentation = false; - cie->pointer_encoding = DW_EH_PE_absptr; - cie->instructions = 0; - - // Parse the version number. - if (cie->end - cursor < 1) - return ReportIncomplete(cie); - cie->version = reader_->ReadOneByte(cursor); - cursor++; - - // If we don't recognize the version, we can't parse any more fields of the - // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a - // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well; - // the difference between those versions seems to be the same as for - // .debug_frame. - if (cie->version < 1 || cie->version > 3) { - reporter_->UnrecognizedVersion(cie->offset, cie->version); - return false; - } - - const uint8_t *augmentation_start = cursor; - const uint8_t *augmentation_end = - reinterpret_cast(memchr(augmentation_start, '\0', - cie->end - augmentation_start)); - if (! augmentation_end) return ReportIncomplete(cie); - cursor = augmentation_end; - cie->augmentation = string(reinterpret_cast(augmentation_start), - cursor - augmentation_start); - // Skip the terminating '\0'. - cursor++; - - // Is this CFI augmented? - if (!cie->augmentation.empty()) { - // Is it an augmentation we recognize? - if (cie->augmentation[0] == DW_Z_augmentation_start) { - // Linux C++ ABI 'z' augmentation, used for exception handling data. - cie->has_z_augmentation = true; - } else { - // Not an augmentation we recognize. Augmentations can have arbitrary - // effects on the form of rest of the content, so we have to give up. - reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation); - return false; - } - } - - // Parse the code alignment factor. - cie->code_alignment_factor = reader_->ReadUnsignedLEB128(cursor, &len); - if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie); - cursor += len; - - // Parse the data alignment factor. - cie->data_alignment_factor = reader_->ReadSignedLEB128(cursor, &len); - if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie); - cursor += len; - - // Parse the return address register. This is a ubyte in version 1, and - // a ULEB128 in version 3. - if (cie->version == 1) { - if (cursor >= cie->end) return ReportIncomplete(cie); - cie->return_address_register = uint8(*cursor++); - } else { - cie->return_address_register = reader_->ReadUnsignedLEB128(cursor, &len); - if (size_t(cie->end - cursor) < len) return ReportIncomplete(cie); - cursor += len; - } - - // If we have a 'z' augmentation string, find the augmentation data and - // use the augmentation string to parse it. - if (cie->has_z_augmentation) { - uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len); - if (size_t(cie->end - cursor) < len + data_size) - return ReportIncomplete(cie); - cursor += len; - const uint8_t *data = cursor; - cursor += data_size; - const uint8_t *data_end = cursor; - - cie->has_z_lsda = false; - cie->has_z_personality = false; - cie->has_z_signal_frame = false; - - // Walk the augmentation string, and extract values from the - // augmentation data as the string directs. - for (size_t i = 1; i < cie->augmentation.size(); i++) { - switch (cie->augmentation[i]) { - case DW_Z_has_LSDA: - // The CIE's augmentation data holds the language-specific data - // area pointer's encoding, and the FDE's augmentation data holds - // the pointer itself. - cie->has_z_lsda = true; - // Fetch the LSDA encoding from the augmentation data. - if (data >= data_end) return ReportIncomplete(cie); - cie->lsda_encoding = DwarfPointerEncoding(*data++); - if (!reader_->ValidEncoding(cie->lsda_encoding)) { - reporter_->InvalidPointerEncoding(cie->offset, cie->lsda_encoding); - return false; - } - // Don't check if the encoding is usable here --- we haven't - // read the FDE's fields yet, so we're not prepared for - // DW_EH_PE_funcrel, although that's a fine encoding for the - // LSDA to use, since it appears in the FDE. - break; - - case DW_Z_has_personality_routine: - // The CIE's augmentation data holds the personality routine - // pointer's encoding, followed by the pointer itself. - cie->has_z_personality = true; - // Fetch the personality routine pointer's encoding from the - // augmentation data. - if (data >= data_end) return ReportIncomplete(cie); - cie->personality_encoding = DwarfPointerEncoding(*data++); - if (!reader_->ValidEncoding(cie->personality_encoding)) { - reporter_->InvalidPointerEncoding(cie->offset, - cie->personality_encoding); - return false; - } - if (!reader_->UsableEncoding(cie->personality_encoding)) { - reporter_->UnusablePointerEncoding(cie->offset, - cie->personality_encoding); - return false; - } - // Fetch the personality routine's pointer itself from the data. - cie->personality_address = - reader_->ReadEncodedPointer(data, cie->personality_encoding, - &len); - if (len > size_t(data_end - data)) - return ReportIncomplete(cie); - data += len; - break; - - case DW_Z_has_FDE_address_encoding: - // The CIE's augmentation data holds the pointer encoding to use - // for addresses in the FDE. - if (data >= data_end) return ReportIncomplete(cie); - cie->pointer_encoding = DwarfPointerEncoding(*data++); - if (!reader_->ValidEncoding(cie->pointer_encoding)) { - reporter_->InvalidPointerEncoding(cie->offset, - cie->pointer_encoding); - return false; - } - if (!reader_->UsableEncoding(cie->pointer_encoding)) { - reporter_->UnusablePointerEncoding(cie->offset, - cie->pointer_encoding); - return false; - } - break; - - case DW_Z_is_signal_trampoline: - // Frames using this CIE are signal delivery frames. - cie->has_z_signal_frame = true; - break; - - default: - // An augmentation we don't recognize. - reporter_->UnrecognizedAugmentation(cie->offset, cie->augmentation); - return false; - } - } - } - - // The CIE's instructions start here. - cie->instructions = cursor; - - return true; -} - -bool CallFrameInfo::ReadFDEFields(FDE *fde) { - const uint8_t *cursor = fde->fields; - size_t size; - - fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding, - &size); - if (size > size_t(fde->end - cursor)) - return ReportIncomplete(fde); - cursor += size; - reader_->SetFunctionBase(fde->address); - - // For the length, we strip off the upper nybble of the encoding used for - // the starting address. - DwarfPointerEncoding length_encoding = - DwarfPointerEncoding(fde->cie->pointer_encoding & 0x0f); - fde->size = reader_->ReadEncodedPointer(cursor, length_encoding, &size); - if (size > size_t(fde->end - cursor)) - return ReportIncomplete(fde); - cursor += size; - - // If the CIE has a 'z' augmentation string, then augmentation data - // appears here. - if (fde->cie->has_z_augmentation) { - uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &size); - if (size_t(fde->end - cursor) < size + data_size) - return ReportIncomplete(fde); - cursor += size; - - // In the abstract, we should walk the augmentation string, and extract - // items from the FDE's augmentation data as we encounter augmentation - // string characters that specify their presence: the ordering of items - // in the augmentation string determines the arrangement of values in - // the augmentation data. - // - // In practice, there's only ever one value in FDE augmentation data - // that we support --- the LSDA pointer --- and we have to bail if we - // see any unrecognized augmentation string characters. So if there is - // anything here at all, we know what it is, and where it starts. - if (fde->cie->has_z_lsda) { - // Check whether the LSDA's pointer encoding is usable now: only once - // we've parsed the FDE's starting address do we call reader_-> - // SetFunctionBase, so that the DW_EH_PE_funcrel encoding becomes - // usable. - if (!reader_->UsableEncoding(fde->cie->lsda_encoding)) { - reporter_->UnusablePointerEncoding(fde->cie->offset, - fde->cie->lsda_encoding); - return false; - } - - fde->lsda_address = - reader_->ReadEncodedPointer(cursor, fde->cie->lsda_encoding, &size); - if (size > data_size) - return ReportIncomplete(fde); - // Ideally, we would also complain here if there were unconsumed - // augmentation data. - } - - cursor += data_size; - } - - // The FDE's instructions start after those. - fde->instructions = cursor; - - return true; -} - -bool CallFrameInfo::Start() { - const uint8_t *buffer_end = buffer_ + buffer_length_; - const uint8_t *cursor; - bool all_ok = true; - const uint8_t *entry_end; - bool ok; - - // Traverse all the entries in buffer_, skipping CIEs and offering - // FDEs to the handler. - for (cursor = buffer_; cursor < buffer_end; - cursor = entry_end, all_ok = all_ok && ok) { - FDE fde; - - // Make it easy to skip this entry with 'continue': assume that - // things are not okay until we've checked all the data, and - // prepare the address of the next entry. - ok = false; - - // Read the entry's prologue. - if (!ReadEntryPrologue(cursor, &fde)) { - if (!fde.end) { - // If we couldn't even figure out this entry's extent, then we - // must stop processing entries altogether. - all_ok = false; - break; - } - entry_end = fde.end; - continue; - } - - // The next iteration picks up after this entry. - entry_end = fde.end; - - // Did we see an .eh_frame terminating mark? - if (fde.kind == kTerminator) { - // If there appears to be more data left in the section after the - // terminating mark, warn the user. But this is just a warning; - // we leave all_ok true. - if (fde.end < buffer_end) reporter_->EarlyEHTerminator(fde.offset); - break; - } - - // In this loop, we skip CIEs. We only parse them fully when we - // parse an FDE that refers to them. This limits our memory - // consumption (beyond the buffer itself) to that needed to - // process the largest single entry. - if (fde.kind != kFDE) { - ok = true; - continue; - } - - // Validate the CIE pointer. - if (fde.id > buffer_length_) { - reporter_->CIEPointerOutOfRange(fde.offset, fde.id); - continue; - } - - CIE cie; - - // Parse this FDE's CIE header. - if (!ReadEntryPrologue(buffer_ + fde.id, &cie)) - continue; - // This had better be an actual CIE. - if (cie.kind != kCIE) { - reporter_->BadCIEId(fde.offset, fde.id); - continue; - } - if (!ReadCIEFields(&cie)) - continue; - - // We now have the values that govern both the CIE and the FDE. - cie.cie = &cie; - fde.cie = &cie; - - // Parse the FDE's header. - if (!ReadFDEFields(&fde)) - continue; - - // Call Entry to ask the consumer if they're interested. - if (!handler_->Entry(fde.offset, fde.address, fde.size, - cie.version, cie.augmentation, - cie.return_address_register)) { - // The handler isn't interested in this entry. That's not an error. - ok = true; - continue; - } - - if (cie.has_z_augmentation) { - // Report the personality routine address, if we have one. - if (cie.has_z_personality) { - if (!handler_ - ->PersonalityRoutine(cie.personality_address, - IsIndirectEncoding(cie.personality_encoding))) - continue; - } - - // Report the language-specific data area address, if we have one. - if (cie.has_z_lsda) { - if (!handler_ - ->LanguageSpecificDataArea(fde.lsda_address, - IsIndirectEncoding(cie.lsda_encoding))) - continue; - } - - // If this is a signal-handling frame, report that. - if (cie.has_z_signal_frame) { - if (!handler_->SignalHandler()) - continue; - } - } - - // Interpret the CIE's instructions, and then the FDE's instructions. - State state(reader_, handler_, reporter_, fde.address); - ok = state.InterpretCIE(cie) && state.InterpretFDE(fde); - - // Tell the ByteReader that the function start address from the - // FDE header is no longer valid. - reader_->ClearFunctionBase(); - - // Report the end of the entry. - handler_->End(); - } - - return all_ok; -} - -const char *CallFrameInfo::KindName(EntryKind kind) { - if (kind == CallFrameInfo::kUnknown) - return "entry"; - else if (kind == CallFrameInfo::kCIE) - return "common information entry"; - else if (kind == CallFrameInfo::kFDE) - return "frame description entry"; - else { - assert (kind == CallFrameInfo::kTerminator); - return ".eh_frame sequence terminator"; - } -} - -bool CallFrameInfo::ReportIncomplete(Entry *entry) { - reporter_->Incomplete(entry->offset, entry->kind); - return false; -} - -void CallFrameInfo::Reporter::Incomplete(uint64 offset, - CallFrameInfo::EntryKind kind) { - fprintf(stderr, - "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n", - filename_.c_str(), CallFrameInfo::KindName(kind), offset, - section_.c_str()); -} - -void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) { - fprintf(stderr, - "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker" - " before end of section contents\n", - filename_.c_str(), offset, section_.c_str()); -} - -void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset, - uint64 cie_offset) { - fprintf(stderr, - "%s: CFI frame description entry at offset 0x%llx in '%s':" - " CIE pointer is out of range: 0x%llx\n", - filename_.c_str(), offset, section_.c_str(), cie_offset); -} - -void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) { - fprintf(stderr, - "%s: CFI frame description entry at offset 0x%llx in '%s':" - " CIE pointer does not point to a CIE: 0x%llx\n", - filename_.c_str(), offset, section_.c_str(), cie_offset); -} - -void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) { - fprintf(stderr, - "%s: CFI frame description entry at offset 0x%llx in '%s':" - " CIE specifies unrecognized version: %d\n", - filename_.c_str(), offset, section_.c_str(), version); -} - -void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset, - const string &aug) { - fprintf(stderr, - "%s: CFI frame description entry at offset 0x%llx in '%s':" - " CIE specifies unrecognized augmentation: '%s'\n", - filename_.c_str(), offset, section_.c_str(), aug.c_str()); -} - -void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset, - uint8 encoding) { - fprintf(stderr, - "%s: CFI common information entry at offset 0x%llx in '%s':" - " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n", - filename_.c_str(), offset, section_.c_str(), encoding); -} - -void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset, - uint8 encoding) { - fprintf(stderr, - "%s: CFI common information entry at offset 0x%llx in '%s':" - " 'z' augmentation specifies a pointer encoding for which" - " we have no base address: 0x%02x\n", - filename_.c_str(), offset, section_.c_str(), encoding); -} - -void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) { - fprintf(stderr, - "%s: CFI common information entry at offset 0x%llx in '%s':" - " the DW_CFA_restore instruction at offset 0x%llx" - " cannot be used in a common information entry\n", - filename_.c_str(), offset, section_.c_str(), insn_offset); -} - -void CallFrameInfo::Reporter::BadInstruction(uint64 offset, - CallFrameInfo::EntryKind kind, - uint64 insn_offset) { - fprintf(stderr, - "%s: CFI %s at offset 0x%llx in section '%s':" - " the instruction at offset 0x%llx is unrecognized\n", - filename_.c_str(), CallFrameInfo::KindName(kind), - offset, section_.c_str(), insn_offset); -} - -void CallFrameInfo::Reporter::NoCFARule(uint64 offset, - CallFrameInfo::EntryKind kind, - uint64 insn_offset) { - fprintf(stderr, - "%s: CFI %s at offset 0x%llx in section '%s':" - " the instruction at offset 0x%llx assumes that a CFA rule has" - " been set, but none has been set\n", - filename_.c_str(), CallFrameInfo::KindName(kind), offset, - section_.c_str(), insn_offset); -} - -void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset, - CallFrameInfo::EntryKind kind, - uint64 insn_offset) { - fprintf(stderr, - "%s: CFI %s at offset 0x%llx in section '%s':" - " the DW_CFA_restore_state instruction at offset 0x%llx" - " should pop a saved state from the stack, but the stack is empty\n", - filename_.c_str(), CallFrameInfo::KindName(kind), offset, - section_.c_str(), insn_offset); -} - -void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset, - CallFrameInfo::EntryKind kind, - uint64 insn_offset) { - fprintf(stderr, - "%s: CFI %s at offset 0x%llx in section '%s':" - " the DW_CFA_restore_state instruction at offset 0x%llx" - " would clear the CFA rule in effect\n", - filename_.c_str(), CallFrameInfo::KindName(kind), offset, - section_.c_str(), insn_offset); -} - -} // namespace dwarf2reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.h deleted file mode 100644 index 064c42bc8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader.h +++ /dev/null @@ -1,1288 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// CFI reader author: Jim Blandy - -// This file contains definitions related to the DWARF2/3 reader and -// it's handler interfaces. -// The DWARF2/3 specification can be found at -// http://dwarf.freestandards.org and should be considered required -// reading if you wish to modify the implementation. -// Only a cursory attempt is made to explain terminology that is -// used here, as it is much better explained in the standard documents -#ifndef COMMON_DWARF_DWARF2READER_H__ -#define COMMON_DWARF_DWARF2READER_H__ - -#include - -#include -#include -#include -#include -#include -#include - -#include "common/dwarf/bytereader.h" -#include "common/dwarf/dwarf2enums.h" -#include "common/dwarf/types.h" -#include "common/using_std_string.h" -#include "common/dwarf/elf_reader.h" - -namespace dwarf2reader { -struct LineStateMachine; -class Dwarf2Handler; -class LineInfoHandler; -class DwpReader; - -// This maps from a string naming a section to a pair containing a -// the data for the section, and the size of the section. -typedef std::map > SectionMap; -typedef std::list > - AttributeList; -typedef AttributeList::iterator AttributeIterator; -typedef AttributeList::const_iterator ConstAttributeIterator; - -struct LineInfoHeader { - uint64 total_length; - uint16 version; - uint64 prologue_length; - uint8 min_insn_length; // insn stands for instructin - bool default_is_stmt; // stmt stands for statement - int8 line_base; - uint8 line_range; - uint8 opcode_base; - // Use a pointer so that signalsafe_addr2line is able to use this structure - // without heap allocation problem. - std::vector *std_opcode_lengths; -}; - -class LineInfo { - public: - - // Initializes a .debug_line reader. Buffer and buffer length point - // to the beginning and length of the line information to read. - // Reader is a ByteReader class that has the endianness set - // properly. - LineInfo(const uint8_t *buffer_, uint64 buffer_length, - ByteReader* reader, LineInfoHandler* handler); - - virtual ~LineInfo() { - if (header_.std_opcode_lengths) { - delete header_.std_opcode_lengths; - } - } - - // Start processing line info, and calling callbacks in the handler. - // Consumes the line number information for a single compilation unit. - // Returns the number of bytes processed. - uint64 Start(); - - // Process a single line info opcode at START using the state - // machine at LSM. Return true if we should define a line using the - // current state of the line state machine. Place the length of the - // opcode in LEN. - // If LSM_PASSES_PC is non-NULL, this function also checks if the lsm - // passes the address of PC. In other words, LSM_PASSES_PC will be - // set to true, if the following condition is met. - // - // lsm's old address < PC <= lsm's new address - static bool ProcessOneOpcode(ByteReader* reader, - LineInfoHandler* handler, - const struct LineInfoHeader &header, - const uint8_t *start, - struct LineStateMachine* lsm, - size_t* len, - uintptr pc, - bool *lsm_passes_pc); - - private: - // Reads the DWARF2/3 header for this line info. - void ReadHeader(); - - // Reads the DWARF2/3 line information - void ReadLines(); - - // The associated handler to call processing functions in - LineInfoHandler* handler_; - - // The associated ByteReader that handles endianness issues for us - ByteReader* reader_; - - // A DWARF2/3 line info header. This is not the same size as - // in the actual file, as the one in the file may have a 32 bit or - // 64 bit lengths - - struct LineInfoHeader header_; - - // buffer is the buffer for our line info, starting at exactly where - // the line info to read is. after_header is the place right after - // the end of the line information header. - const uint8_t *buffer_; -#ifndef NDEBUG - uint64 buffer_length_; -#endif - const uint8_t *after_header_; -}; - -// This class is the main interface between the line info reader and -// the client. The virtual functions inside this get called for -// interesting events that happen during line info reading. The -// default implementation does nothing - -class LineInfoHandler { - public: - LineInfoHandler() { } - - virtual ~LineInfoHandler() { } - - // Called when we define a directory. NAME is the directory name, - // DIR_NUM is the directory number - virtual void DefineDir(const string& name, uint32 dir_num) { } - - // Called when we define a filename. NAME is the filename, FILE_NUM - // is the file number which is -1 if the file index is the next - // index after the last numbered index (this happens when files are - // dynamically defined by the line program), DIR_NUM is the - // directory index for the directory name of this file, MOD_TIME is - // the modification time of the file, and LENGTH is the length of - // the file - virtual void DefineFile(const string& name, int32 file_num, - uint32 dir_num, uint64 mod_time, - uint64 length) { } - - // Called when the line info reader has a new line, address pair - // ready for us. ADDRESS is the address of the code, LENGTH is the - // length of its machine code in bytes, FILE_NUM is the file number - // containing the code, LINE_NUM is the line number in that file for - // the code, and COLUMN_NUM is the column number the code starts at, - // if we know it (0 otherwise). - virtual void AddLine(uint64 address, uint64 length, - uint32 file_num, uint32 line_num, uint32 column_num) { } -}; - -// This class is the main interface between the reader and the -// client. The virtual functions inside this get called for -// interesting events that happen during DWARF2 reading. -// The default implementation skips everything. -class Dwarf2Handler { - public: - Dwarf2Handler() { } - - virtual ~Dwarf2Handler() { } - - // Start to process a compilation unit at OFFSET from the beginning of the - // .debug_info section. Return false if you would like to skip this - // compilation unit. - virtual bool StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version) { return false; } - - // When processing a skeleton compilation unit, resulting from a split - // DWARF compilation, once the skeleton debug info has been read, - // the reader will call this function to ask the client if it needs - // the full debug info from the .dwo or .dwp file. Return true if - // you need it, or false to skip processing the split debug info. - virtual bool NeedSplitDebugInfo() { return true; } - - // Start to process a split compilation unit at OFFSET from the beginning of - // the debug_info section in the .dwp/.dwo file. Return false if you would - // like to skip this compilation unit. - virtual bool StartSplitCompilationUnit(uint64 offset, - uint64 cu_length) { return false; } - - // Start to process a DIE at OFFSET from the beginning of the .debug_info - // section. Return false if you would like to skip this DIE. - virtual bool StartDIE(uint64 offset, enum DwarfTag tag) { return false; } - - // Called when we have an attribute with unsigned data to give to our - // handler. The attribute is for the DIE at OFFSET from the beginning of the - // .debug_info section. Its name is ATTR, its form is FORM, and its value is - // DATA. - virtual void ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { } - - // Called when we have an attribute with signed data to give to our handler. - // The attribute is for the DIE at OFFSET from the beginning of the - // .debug_info section. Its name is ATTR, its form is FORM, and its value is - // DATA. - virtual void ProcessAttributeSigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { } - - // Called when we have an attribute whose value is a reference to - // another DIE. The attribute belongs to the DIE at OFFSET from the - // beginning of the .debug_info section. Its name is ATTR, its form - // is FORM, and the offset of the DIE being referred to from the - // beginning of the .debug_info section is DATA. - virtual void ProcessAttributeReference(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { } - - // Called when we have an attribute with a buffer of data to give to our - // handler. The attribute is for the DIE at OFFSET from the beginning of the - // .debug_info section. Its name is ATTR, its form is FORM, DATA points to - // the buffer's contents, and its length in bytes is LENGTH. The buffer is - // owned by the caller, not the callee, and may not persist for very long. - // If you want the data to be available later, it needs to be copied. - virtual void ProcessAttributeBuffer(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t *data, - uint64 len) { } - - // Called when we have an attribute with string data to give to our handler. - // The attribute is for the DIE at OFFSET from the beginning of the - // .debug_info section. Its name is ATTR, its form is FORM, and its value is - // DATA. - virtual void ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string& data) { } - - // Called when we have an attribute whose value is the 64-bit signature - // of a type unit in the .debug_types section. OFFSET is the offset of - // the DIE whose attribute we're reporting. ATTR and FORM are the - // attribute's name and form. SIGNATURE is the type unit's signature. - virtual void ProcessAttributeSignature(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 signature) { } - - // Called when finished processing the DIE at OFFSET. - // Because DWARF2/3 specifies a tree of DIEs, you may get starts - // before ends of the previous DIE, as we process children before - // ending the parent. - virtual void EndDIE(uint64 offset) { } - -}; - -// The base of DWARF2/3 debug info is a DIE (Debugging Information -// Entry. -// DWARF groups DIE's into a tree and calls the root of this tree a -// "compilation unit". Most of the time, there is one compilation -// unit in the .debug_info section for each file that had debug info -// generated. -// Each DIE consists of - -// 1. a tag specifying a thing that is being described (ie -// DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc -// 2. attributes (such as DW_AT_location for location in memory, -// DW_AT_name for name), and data for each attribute. -// 3. A flag saying whether the DIE has children or not - -// In order to gain some amount of compression, the format of -// each DIE (tag name, attributes and data forms for the attributes) -// are stored in a separate table called the "abbreviation table". -// This is done because a large number of DIEs have the exact same tag -// and list of attributes, but different data for those attributes. -// As a result, the .debug_info section is just a stream of data, and -// requires reading of the .debug_abbrev section to say what the data -// means. - -// As a warning to the user, it should be noted that the reason for -// using absolute offsets from the beginning of .debug_info is that -// DWARF2/3 supports referencing DIE's from other DIE's by their offset -// from either the current compilation unit start, *or* the beginning -// of the .debug_info section. This means it is possible to reference -// a DIE in one compilation unit from a DIE in another compilation -// unit. This style of reference is usually used to eliminate -// duplicated information that occurs across compilation -// units, such as base types, etc. GCC 3.4+ support this with -// -feliminate-dwarf2-dups. Other toolchains will sometimes do -// duplicate elimination in the linker. - -class CompilationUnit { - public: - - // Initialize a compilation unit. This requires a map of sections, - // the offset of this compilation unit in the .debug_info section, a - // ByteReader, and a Dwarf2Handler class to call callbacks in. - CompilationUnit(const string& path, const SectionMap& sections, uint64 offset, - ByteReader* reader, Dwarf2Handler* handler); - virtual ~CompilationUnit() { - if (abbrevs_) delete abbrevs_; - } - - // Initialize a compilation unit from a .dwo or .dwp file. - // In this case, we need the .debug_addr section from the - // executable file that contains the corresponding skeleton - // compilation unit. We also inherit the Dwarf2Handler from - // the executable file, and call it as if we were still - // processing the original compilation unit. - void SetSplitDwarf(const uint8_t* addr_buffer, uint64 addr_buffer_length, - uint64 addr_base, uint64 ranges_base, uint64 dwo_id); - - // Begin reading a Dwarf2 compilation unit, and calling the - // callbacks in the Dwarf2Handler - - // Return the full length of the compilation unit, including - // headers. This plus the starting offset passed to the constructor - // is the offset of the end of the compilation unit --- and the - // start of the next compilation unit, if there is one. - uint64 Start(); - - private: - - // This struct represents a single DWARF2/3 abbreviation - // The abbreviation tells how to read a DWARF2/3 DIE, and consist of a - // tag and a list of attributes, as well as the data form of each attribute. - struct Abbrev { - uint64 number; - enum DwarfTag tag; - bool has_children; - AttributeList attributes; - }; - - // A DWARF2/3 compilation unit header. This is not the same size as - // in the actual file, as the one in the file may have a 32 bit or - // 64 bit length. - struct CompilationUnitHeader { - uint64 length; - uint16 version; - uint64 abbrev_offset; - uint8 address_size; - } header_; - - // Reads the DWARF2/3 header for this compilation unit. - void ReadHeader(); - - // Reads the DWARF2/3 abbreviations for this compilation unit - void ReadAbbrevs(); - - // Processes a single DIE for this compilation unit and return a new - // pointer just past the end of it - const uint8_t *ProcessDIE(uint64 dieoffset, - const uint8_t *start, - const Abbrev& abbrev); - - // Processes a single attribute and return a new pointer just past the - // end of it - const uint8_t *ProcessAttribute(uint64 dieoffset, - const uint8_t *start, - enum DwarfAttribute attr, - enum DwarfForm form); - - // Called when we have an attribute with unsigned data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of compilation unit, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA. - // If we see a DW_AT_GNU_dwo_id attribute, save the value so that - // we can find the debug info in a .dwo or .dwp file. - void ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - if (attr == DW_AT_GNU_dwo_id) { - dwo_id_ = data; - } - else if (attr == DW_AT_GNU_addr_base) { - addr_base_ = data; - } - else if (attr == DW_AT_GNU_ranges_base) { - ranges_base_ = data; - } - // TODO(yunlian): When we add DW_AT_ranges_base from DWARF-5, - // that base will apply to DW_AT_ranges attributes in the - // skeleton CU as well as in the .dwo/.dwp files. - else if (attr == DW_AT_ranges && is_split_dwarf_) { - data += ranges_base_; - } - handler_->ProcessAttributeUnsigned(offset, attr, form, data); - } - - // Called when we have an attribute with signed data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of compilation unit, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA. - void ProcessAttributeSigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { - handler_->ProcessAttributeSigned(offset, attr, form, data); - } - - // Called when we have an attribute with a buffer of data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of compilation unit, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA, and the - // length of the buffer is LENGTH. - void ProcessAttributeBuffer(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t* data, - uint64 len) { - handler_->ProcessAttributeBuffer(offset, attr, form, data, len); - } - - // Called when we have an attribute with string data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of compilation unit, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA. - // If we see a DW_AT_GNU_dwo_name attribute, save the value so - // that we can find the debug info in a .dwo or .dwp file. - void ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const char* data) { - if (attr == DW_AT_GNU_dwo_name) - dwo_name_ = data; - handler_->ProcessAttributeString(offset, attr, form, data); - } - - // Processes all DIEs for this compilation unit - void ProcessDIEs(); - - // Skips the die with attributes specified in ABBREV starting at - // START, and return the new place to position the stream to. - const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev); - - // Skips the attribute starting at START, with FORM, and return the - // new place to position the stream to. - const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form); - - // Process the actual debug information in a split DWARF file. - void ProcessSplitDwarf(); - - // Read the debug sections from a .dwo file. - void ReadDebugSectionsFromDwo(ElfReader* elf_reader, - SectionMap* sections); - - // Path of the file containing the debug information. - const string path_; - - // Offset from section start is the offset of this compilation unit - // from the beginning of the .debug_info section. - uint64 offset_from_section_start_; - - // buffer is the buffer for our CU, starting at .debug_info + offset - // passed in from constructor. - // after_header points to right after the compilation unit header. - const uint8_t *buffer_; - uint64 buffer_length_; - const uint8_t *after_header_; - - // The associated ByteReader that handles endianness issues for us - ByteReader* reader_; - - // The map of sections in our file to buffers containing their data - const SectionMap& sections_; - - // The associated handler to call processing functions in - Dwarf2Handler* handler_; - - // Set of DWARF2/3 abbreviations for this compilation unit. Indexed - // by abbreviation number, which means that abbrevs_[0] is not - // valid. - std::vector* abbrevs_; - - // String section buffer and length, if we have a string section. - // This is here to avoid doing a section lookup for strings in - // ProcessAttribute, which is in the hot path for DWARF2 reading. - const uint8_t *string_buffer_; - uint64 string_buffer_length_; - - // String offsets section buffer and length, if we have a string offsets - // section (.debug_str_offsets or .debug_str_offsets.dwo). - const uint8_t* str_offsets_buffer_; - uint64 str_offsets_buffer_length_; - - // Address section buffer and length, if we have an address section - // (.debug_addr). - const uint8_t* addr_buffer_; - uint64 addr_buffer_length_; - - // Flag indicating whether this compilation unit is part of a .dwo - // or .dwp file. If true, we are reading this unit because a - // skeleton compilation unit in an executable file had a - // DW_AT_GNU_dwo_name or DW_AT_GNU_dwo_id attribute. - // In a .dwo file, we expect the string offsets section to - // have a ".dwo" suffix, and we will use the ".debug_addr" section - // associated with the skeleton compilation unit. - bool is_split_dwarf_; - - // The value of the DW_AT_GNU_dwo_id attribute, if any. - uint64 dwo_id_; - - // The value of the DW_AT_GNU_dwo_name attribute, if any. - const char* dwo_name_; - - // If this is a split DWARF CU, the value of the DW_AT_GNU_dwo_id attribute - // from the skeleton CU. - uint64 skeleton_dwo_id_; - - // The value of the DW_AT_GNU_ranges_base attribute, if any. - uint64 ranges_base_; - - // The value of the DW_AT_GNU_addr_base attribute, if any. - uint64 addr_base_; - - // True if we have already looked for a .dwp file. - bool have_checked_for_dwp_; - - // Path to the .dwp file. - string dwp_path_; - - // ByteReader for the DWP file. - std::unique_ptr dwp_byte_reader_; - - // DWP reader. - std::unique_ptr dwp_reader_; -}; - -// A Reader for a .dwp file. Supports the fetching of DWARF debug -// info for a given dwo_id. -// -// There are two versions of .dwp files. In both versions, the -// .dwp file is an ELF file containing only debug sections. -// In Version 1, the file contains many copies of each debug -// section, one for each .dwo file that is packaged in the .dwp -// file, and the .debug_cu_index section maps from the dwo_id -// to a set of section indexes. In Version 2, the file contains -// one of each debug section, and the .debug_cu_index section -// maps from the dwo_id to a set of offsets and lengths that -// identify each .dwo file's contribution to the larger sections. - -class DwpReader { - public: - DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader); - - ~DwpReader(); - - // Read the CU index and initialize data members. - void Initialize(); - - // Read the debug sections for the given dwo_id. - void ReadDebugSectionsForCU(uint64 dwo_id, SectionMap* sections); - - private: - // Search a v1 hash table for "dwo_id". Returns the slot index - // where the dwo_id was found, or -1 if it was not found. - int LookupCU(uint64 dwo_id); - - // Search a v2 hash table for "dwo_id". Returns the row index - // in the offsets and sizes tables, or 0 if it was not found. - uint32 LookupCUv2(uint64 dwo_id); - - // The ELF reader for the .dwp file. - ElfReader* elf_reader_; - - // The ByteReader for the .dwp file. - const ByteReader& byte_reader_; - - // Pointer to the .debug_cu_index section. - const char* cu_index_; - - // Size of the .debug_cu_index section. - size_t cu_index_size_; - - // Pointer to the .debug_str.dwo section. - const char* string_buffer_; - - // Size of the .debug_str.dwo section. - size_t string_buffer_size_; - - // Version of the .dwp file. We support versions 1 and 2 currently. - int version_; - - // Number of columns in the section tables (version 2). - unsigned int ncolumns_; - - // Number of units in the section tables (version 2). - unsigned int nunits_; - - // Number of slots in the hash table. - unsigned int nslots_; - - // Pointer to the beginning of the hash table. - const char* phash_; - - // Pointer to the beginning of the index table. - const char* pindex_; - - // Pointer to the beginning of the section index pool (version 1). - const char* shndx_pool_; - - // Pointer to the beginning of the section offset table (version 2). - const char* offset_table_; - - // Pointer to the beginning of the section size table (version 2). - const char* size_table_; - - // Contents of the sections of interest (version 2). - const char* abbrev_data_; - size_t abbrev_size_; - const char* info_data_; - size_t info_size_; - const char* str_offsets_data_; - size_t str_offsets_size_; -}; - -// This class is a reader for DWARF's Call Frame Information. CFI -// describes how to unwind stack frames --- even for functions that do -// not follow fixed conventions for saving registers, whose frame size -// varies as they execute, etc. -// -// CFI describes, at each machine instruction, how to compute the -// stack frame's base address, how to find the return address, and -// where to find the saved values of the caller's registers (if the -// callee has stashed them somewhere to free up the registers for its -// own use). -// -// For example, suppose we have a function whose machine code looks -// like this (imagine an assembly language that looks like C, for a -// machine with 32-bit registers, and a stack that grows towards lower -// addresses): -// -// func: ; entry point; return address at sp -// func+0: sp = sp - 16 ; allocate space for stack frame -// func+1: sp[12] = r0 ; save r0 at sp+12 -// ... ; other code, not frame-related -// func+10: sp -= 4; *sp = x ; push some x on the stack -// ... ; other code, not frame-related -// func+20: r0 = sp[16] ; restore saved r0 -// func+21: sp += 20 ; pop whole stack frame -// func+22: pc = *sp; sp += 4 ; pop return address and jump to it -// -// DWARF CFI is (a very compressed representation of) a table with a -// row for each machine instruction address and a column for each -// register showing how to restore it, if possible. -// -// A special column named "CFA", for "Canonical Frame Address", tells how -// to compute the base address of the frame; registers' entries may -// refer to the CFA in describing where the registers are saved. -// -// Another special column, named "RA", represents the return address. -// -// For example, here is a complete (uncompressed) table describing the -// function above: -// -// insn cfa r0 r1 ... ra -// ======================================= -// func+0: sp cfa[0] -// func+1: sp+16 cfa[0] -// func+2: sp+16 cfa[-4] cfa[0] -// func+11: sp+20 cfa[-4] cfa[0] -// func+21: sp+20 cfa[0] -// func+22: sp cfa[0] -// -// Some things to note here: -// -// - Each row describes the state of affairs *before* executing the -// instruction at the given address. Thus, the row for func+0 -// describes the state before we allocate the stack frame. In the -// next row, the formula for computing the CFA has changed, -// reflecting that allocation. -// -// - The other entries are written in terms of the CFA; this allows -// them to remain unchanged as the stack pointer gets bumped around. -// For example, the rule for recovering the return address (the "ra" -// column) remains unchanged throughout the function, even as the -// stack pointer takes on three different offsets from the return -// address. -// -// - Although we haven't shown it, most calling conventions designate -// "callee-saves" and "caller-saves" registers. The callee must -// preserve the values of callee-saves registers; if it uses them, -// it must save their original values somewhere, and restore them -// before it returns. In contrast, the callee is free to trash -// caller-saves registers; if the callee uses these, it will -// probably not bother to save them anywhere, and the CFI will -// probably mark their values as "unrecoverable". -// -// (However, since the caller cannot assume the callee was going to -// save them, caller-saves registers are probably dead in the caller -// anyway, so compilers usually don't generate CFA for caller-saves -// registers.) -// -// - Exactly where the CFA points is a matter of convention that -// depends on the architecture and ABI in use. In the example, the -// CFA is the value the stack pointer had upon entry to the -// function, pointing at the saved return address. But on the x86, -// the call frame information generated by GCC follows the -// convention that the CFA is the address *after* the saved return -// address. -// -// But by definition, the CFA remains constant throughout the -// lifetime of the frame. This makes it a useful value for other -// columns to refer to. It is also gives debuggers a useful handle -// for identifying a frame. -// -// If you look at the table above, you'll notice that a given entry is -// often the same as the one immediately above it: most instructions -// change only one or two aspects of the stack frame, if they affect -// it at all. The DWARF format takes advantage of this fact, and -// reduces the size of the data by mentioning only the addresses and -// columns at which changes take place. So for the above, DWARF CFI -// data would only actually mention the following: -// -// insn cfa r0 r1 ... ra -// ======================================= -// func+0: sp cfa[0] -// func+1: sp+16 -// func+2: cfa[-4] -// func+11: sp+20 -// func+21: r0 -// func+22: sp -// -// In fact, this is the way the parser reports CFI to the consumer: as -// a series of statements of the form, "At address X, column Y changed -// to Z," and related conventions for describing the initial state. -// -// Naturally, it would be impractical to have to scan the entire -// program's CFI, noting changes as we go, just to recover the -// unwinding rules in effect at one particular instruction. To avoid -// this, CFI data is grouped into "entries", each of which covers a -// specified range of addresses and begins with a complete statement -// of the rules for all recoverable registers at that starting -// address. Each entry typically covers a single function. -// -// Thus, to compute the contents of a given row of the table --- that -// is, rules for recovering the CFA, RA, and registers at a given -// instruction --- the consumer should find the entry that covers that -// instruction's address, start with the initial state supplied at the -// beginning of the entry, and work forward until it has processed all -// the changes up to and including those for the present instruction. -// -// There are seven kinds of rules that can appear in an entry of the -// table: -// -// - "undefined": The given register is not preserved by the callee; -// its value cannot be recovered. -// -// - "same value": This register has the same value it did in the callee. -// -// - offset(N): The register is saved at offset N from the CFA. -// -// - val_offset(N): The value the register had in the caller is the -// CFA plus offset N. (This is usually only useful for describing -// the stack pointer.) -// -// - register(R): The register's value was saved in another register R. -// -// - expression(E): Evaluating the DWARF expression E using the -// current frame's registers' values yields the address at which the -// register was saved. -// -// - val_expression(E): Evaluating the DWARF expression E using the -// current frame's registers' values yields the value the register -// had in the caller. - -class CallFrameInfo { - public: - // The different kinds of entries one finds in CFI. Used internally, - // and for error reporting. - enum EntryKind { kUnknown, kCIE, kFDE, kTerminator }; - - // The handler class to which the parser hands the parsed call frame - // information. Defined below. - class Handler; - - // A reporter class, which CallFrameInfo uses to report errors - // encountered while parsing call frame information. Defined below. - class Reporter; - - // Create a DWARF CFI parser. BUFFER points to the contents of the - // .debug_frame section to parse; BUFFER_LENGTH is its length in bytes. - // REPORTER is an error reporter the parser should use to report - // problems. READER is a ByteReader instance that has the endianness and - // address size set properly. Report the data we find to HANDLER. - // - // This class can also parse Linux C++ exception handling data, as found - // in '.eh_frame' sections. This data is a variant of DWARF CFI that is - // placed in loadable segments so that it is present in the program's - // address space, and is interpreted by the C++ runtime to search the - // call stack for a handler interested in the exception being thrown, - // actually pop the frames, and find cleanup code to run. - // - // There are two differences between the call frame information described - // in the DWARF standard and the exception handling data Linux places in - // the .eh_frame section: - // - // - Exception handling data uses uses a different format for call frame - // information entry headers. The distinguished CIE id, the way FDEs - // refer to their CIEs, and the way the end of the series of entries is - // determined are all slightly different. - // - // If the constructor's EH_FRAME argument is true, then the - // CallFrameInfo parses the entry headers as Linux C++ exception - // handling data. If EH_FRAME is false or omitted, the CallFrameInfo - // parses standard DWARF call frame information. - // - // - Linux C++ exception handling data uses CIE augmentation strings - // beginning with 'z' to specify the presence of additional data after - // the CIE and FDE headers and special encodings used for addresses in - // frame description entries. - // - // CallFrameInfo can handle 'z' augmentations in either DWARF CFI or - // exception handling data if you have supplied READER with the base - // addresses needed to interpret the pointer encodings that 'z' - // augmentations can specify. See the ByteReader interface for details - // about the base addresses. See the CallFrameInfo::Handler interface - // for details about the additional information one might find in - // 'z'-augmented data. - // - // Thus: - // - // - If you are parsing standard DWARF CFI, as found in a .debug_frame - // section, you should pass false for the EH_FRAME argument, or omit - // it, and you need not worry about providing READER with the - // additional base addresses. - // - // - If you want to parse Linux C++ exception handling data from a - // .eh_frame section, you should pass EH_FRAME as true, and call - // READER's Set*Base member functions before calling our Start method. - // - // - If you want to parse DWARF CFI that uses the 'z' augmentations - // (although I don't think any toolchain ever emits such data), you - // could pass false for EH_FRAME, but call READER's Set*Base members. - // - // The extensions the Linux C++ ABI makes to DWARF for exception - // handling are described here, rather poorly: - // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html - // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html - // - // The mechanics of C++ exception handling, personality routines, - // and language-specific data areas are described here, rather nicely: - // http://www.codesourcery.com/public/cxx-abi/abi-eh.html - CallFrameInfo(const uint8_t *buffer, size_t buffer_length, - ByteReader *reader, Handler *handler, Reporter *reporter, - bool eh_frame = false) - : buffer_(buffer), buffer_length_(buffer_length), - reader_(reader), handler_(handler), reporter_(reporter), - eh_frame_(eh_frame) { } - - ~CallFrameInfo() { } - - // Parse the entries in BUFFER, reporting what we find to HANDLER. - // Return true if we reach the end of the section successfully, or - // false if we encounter an error. - bool Start(); - - // Return the textual name of KIND. For error reporting. - static const char *KindName(EntryKind kind); - - private: - - struct CIE; - - // A CFI entry, either an FDE or a CIE. - struct Entry { - // The starting offset of the entry in the section, for error - // reporting. - size_t offset; - - // The start of this entry in the buffer. - const uint8_t *start; - - // Which kind of entry this is. - // - // We want to be able to use this for error reporting even while we're - // in the midst of parsing. Error reporting code may assume that kind, - // offset, and start fields are valid, although kind may be kUnknown. - EntryKind kind; - - // The end of this entry's common prologue (initial length and id), and - // the start of this entry's kind-specific fields. - const uint8_t *fields; - - // The start of this entry's instructions. - const uint8_t *instructions; - - // The address past the entry's last byte in the buffer. (Note that - // since offset points to the entry's initial length field, and the - // length field is the number of bytes after that field, this is not - // simply buffer_ + offset + length.) - const uint8_t *end; - - // For both DWARF CFI and .eh_frame sections, this is the CIE id in a - // CIE, and the offset of the associated CIE in an FDE. - uint64 id; - - // The CIE that applies to this entry, if we've parsed it. If this is a - // CIE, then this field points to this structure. - CIE *cie; - }; - - // A common information entry (CIE). - struct CIE: public Entry { - uint8 version; // CFI data version number - string augmentation; // vendor format extension markers - uint64 code_alignment_factor; // scale for code address adjustments - int data_alignment_factor; // scale for stack pointer adjustments - unsigned return_address_register; // which register holds the return addr - - // True if this CIE includes Linux C++ ABI 'z' augmentation data. - bool has_z_augmentation; - - // Parsed 'z' augmentation data. These are meaningful only if - // has_z_augmentation is true. - bool has_z_lsda; // The 'z' augmentation included 'L'. - bool has_z_personality; // The 'z' augmentation included 'P'. - bool has_z_signal_frame; // The 'z' augmentation included 'S'. - - // If has_z_lsda is true, this is the encoding to be used for language- - // specific data area pointers in FDEs. - DwarfPointerEncoding lsda_encoding; - - // If has_z_personality is true, this is the encoding used for the - // personality routine pointer in the augmentation data. - DwarfPointerEncoding personality_encoding; - - // If has_z_personality is true, this is the address of the personality - // routine --- or, if personality_encoding & DW_EH_PE_indirect, the - // address where the personality routine's address is stored. - uint64 personality_address; - - // This is the encoding used for addresses in the FDE header and - // in DW_CFA_set_loc instructions. This is always valid, whether - // or not we saw a 'z' augmentation string; its default value is - // DW_EH_PE_absptr, which is what normal DWARF CFI uses. - DwarfPointerEncoding pointer_encoding; - }; - - // A frame description entry (FDE). - struct FDE: public Entry { - uint64 address; // start address of described code - uint64 size; // size of described code, in bytes - - // If cie->has_z_lsda is true, then this is the language-specific data - // area's address --- or its address's address, if cie->lsda_encoding - // has the DW_EH_PE_indirect bit set. - uint64 lsda_address; - }; - - // Internal use. - class Rule; - class UndefinedRule; - class SameValueRule; - class OffsetRule; - class ValOffsetRule; - class RegisterRule; - class ExpressionRule; - class ValExpressionRule; - class RuleMap; - class State; - - // Parse the initial length and id of a CFI entry, either a CIE, an FDE, - // or a .eh_frame end-of-data mark. CURSOR points to the beginning of the - // data to parse. On success, populate ENTRY as appropriate, and return - // true. On failure, report the problem, and return false. Even if we - // return false, set ENTRY->end to the first byte after the entry if we - // were able to figure that out, or NULL if we weren't. - bool ReadEntryPrologue(const uint8_t *cursor, Entry *entry); - - // Parse the fields of a CIE after the entry prologue, including any 'z' - // augmentation data. Assume that the 'Entry' fields of CIE are - // populated; use CIE->fields and CIE->end as the start and limit for - // parsing. On success, populate the rest of *CIE, and return true; on - // failure, report the problem and return false. - bool ReadCIEFields(CIE *cie); - - // Parse the fields of an FDE after the entry prologue, including any 'z' - // augmentation data. Assume that the 'Entry' fields of *FDE are - // initialized; use FDE->fields and FDE->end as the start and limit for - // parsing. Assume that FDE->cie is fully initialized. On success, - // populate the rest of *FDE, and return true; on failure, report the - // problem and return false. - bool ReadFDEFields(FDE *fde); - - // Report that ENTRY is incomplete, and return false. This is just a - // trivial wrapper for invoking reporter_->Incomplete; it provides a - // little brevity. - bool ReportIncomplete(Entry *entry); - - // Return true if ENCODING has the DW_EH_PE_indirect bit set. - static bool IsIndirectEncoding(DwarfPointerEncoding encoding) { - return encoding & DW_EH_PE_indirect; - } - - // The contents of the DWARF .debug_info section we're parsing. - const uint8_t *buffer_; - size_t buffer_length_; - - // For reading multi-byte values with the appropriate endianness. - ByteReader *reader_; - - // The handler to which we should report the data we find. - Handler *handler_; - - // For reporting problems in the info we're parsing. - Reporter *reporter_; - - // True if we are processing .eh_frame-format data. - bool eh_frame_; -}; - -// The handler class for CallFrameInfo. The a CFI parser calls the -// member functions of a handler object to report the data it finds. -class CallFrameInfo::Handler { - public: - // The pseudo-register number for the canonical frame address. - enum { kCFARegister = -1 }; - - Handler() { } - virtual ~Handler() { } - - // The parser has found CFI for the machine code at ADDRESS, - // extending for LENGTH bytes. OFFSET is the offset of the frame - // description entry in the section, for use in error messages. - // VERSION is the version number of the CFI format. AUGMENTATION is - // a string describing any producer-specific extensions present in - // the data. RETURN_ADDRESS is the number of the register that holds - // the address to which the function should return. - // - // Entry should return true to process this CFI, or false to skip to - // the next entry. - // - // The parser invokes Entry for each Frame Description Entry (FDE) - // it finds. The parser doesn't report Common Information Entries - // to the handler explicitly; instead, if the handler elects to - // process a given FDE, the parser reiterates the appropriate CIE's - // contents at the beginning of the FDE's rules. - virtual bool Entry(size_t offset, uint64 address, uint64 length, - uint8 version, const string &augmentation, - unsigned return_address) = 0; - - // When the Entry function returns true, the parser calls these - // handler functions repeatedly to describe the rules for recovering - // registers at each instruction in the given range of machine code. - // Immediately after a call to Entry, the handler should assume that - // the rule for each callee-saves register is "unchanged" --- that - // is, that the register still has the value it had in the caller. - // - // If a *Rule function returns true, we continue processing this entry's - // instructions. If a *Rule function returns false, we stop evaluating - // instructions, and skip to the next entry. Either way, we call End - // before going on to the next entry. - // - // In all of these functions, if the REG parameter is kCFARegister, then - // the rule describes how to find the canonical frame address. - // kCFARegister may be passed as a BASE_REGISTER argument, meaning that - // the canonical frame address should be used as the base address for the - // computation. All other REG values will be positive. - - // At ADDRESS, register REG's value is not recoverable. - virtual bool UndefinedRule(uint64 address, int reg) = 0; - - // At ADDRESS, register REG's value is the same as that it had in - // the caller. - virtual bool SameValueRule(uint64 address, int reg) = 0; - - // At ADDRESS, register REG has been saved at offset OFFSET from - // BASE_REGISTER. - virtual bool OffsetRule(uint64 address, int reg, - int base_register, long offset) = 0; - - // At ADDRESS, the caller's value of register REG is the current - // value of BASE_REGISTER plus OFFSET. (This rule doesn't provide an - // address at which the register's value is saved.) - virtual bool ValOffsetRule(uint64 address, int reg, - int base_register, long offset) = 0; - - // At ADDRESS, register REG has been saved in BASE_REGISTER. This differs - // from ValOffsetRule(ADDRESS, REG, BASE_REGISTER, 0), in that - // BASE_REGISTER is the "home" for REG's saved value: if you want to - // assign to a variable whose home is REG in the calling frame, you - // should put the value in BASE_REGISTER. - virtual bool RegisterRule(uint64 address, int reg, int base_register) = 0; - - // At ADDRESS, the DWARF expression EXPRESSION yields the address at - // which REG was saved. - virtual bool ExpressionRule(uint64 address, int reg, - const string &expression) = 0; - - // At ADDRESS, the DWARF expression EXPRESSION yields the caller's - // value for REG. (This rule doesn't provide an address at which the - // register's value is saved.) - virtual bool ValExpressionRule(uint64 address, int reg, - const string &expression) = 0; - - // Indicate that the rules for the address range reported by the - // last call to Entry are complete. End should return true if - // everything is okay, or false if an error has occurred and parsing - // should stop. - virtual bool End() = 0; - - // Handler functions for Linux C++ exception handling data. These are - // only called if the data includes 'z' augmentation strings. - - // The Linux C++ ABI uses an extension of the DWARF CFI format to - // walk the stack to propagate exceptions from the throw to the - // appropriate catch, and do the appropriate cleanups along the way. - // CFI entries used for exception handling have two additional data - // associated with them: - // - // - The "language-specific data area" describes which exception - // types the function has 'catch' clauses for, and indicates how - // to go about re-entering the function at the appropriate catch - // clause. If the exception is not caught, it describes the - // destructors that must run before the frame is popped. - // - // - The "personality routine" is responsible for interpreting the - // language-specific data area's contents, and deciding whether - // the exception should continue to propagate down the stack, - // perhaps after doing some cleanup for this frame, or whether the - // exception will be caught here. - // - // In principle, the language-specific data area is opaque to - // everybody but the personality routine. In practice, these values - // may be useful or interesting to readers with extra context, and - // we have to at least skip them anyway, so we might as well report - // them to the handler. - - // This entry's exception handling personality routine's address is - // ADDRESS. If INDIRECT is true, then ADDRESS is the address at - // which the routine's address is stored. The default definition for - // this handler function simply returns true, allowing parsing of - // the entry to continue. - virtual bool PersonalityRoutine(uint64 address, bool indirect) { - return true; - } - - // This entry's language-specific data area (LSDA) is located at - // ADDRESS. If INDIRECT is true, then ADDRESS is the address at - // which the area's address is stored. The default definition for - // this handler function simply returns true, allowing parsing of - // the entry to continue. - virtual bool LanguageSpecificDataArea(uint64 address, bool indirect) { - return true; - } - - // This entry describes a signal trampoline --- this frame is the - // caller of a signal handler. The default definition for this - // handler function simply returns true, allowing parsing of the - // entry to continue. - // - // The best description of the rationale for and meaning of signal - // trampoline CFI entries seems to be in the GCC bug database: - // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208 - virtual bool SignalHandler() { return true; } -}; - -// The CallFrameInfo class makes calls on an instance of this class to -// report errors or warn about problems in the data it is parsing. The -// default definitions of these methods print a message to stderr, but -// you can make a derived class that overrides them. -class CallFrameInfo::Reporter { - public: - // Create an error reporter which attributes troubles to the section - // named SECTION in FILENAME. - // - // Normally SECTION would be .debug_frame, but the Mac puts CFI data - // in a Mach-O section named __debug_frame. If we support - // Linux-style exception handling data, we could be reading an - // .eh_frame section. - Reporter(const string &filename, - const string §ion = ".debug_frame") - : filename_(filename), section_(section) { } - virtual ~Reporter() { } - - // The CFI entry at OFFSET ends too early to be well-formed. KIND - // indicates what kind of entry it is; KIND can be kUnknown if we - // haven't parsed enough of the entry to tell yet. - virtual void Incomplete(uint64 offset, CallFrameInfo::EntryKind kind); - - // The .eh_frame data has a four-byte zero at OFFSET where the next - // entry's length would be; this is a terminator. However, the buffer - // length as given to the CallFrameInfo constructor says there should be - // more data. - virtual void EarlyEHTerminator(uint64 offset); - - // The FDE at OFFSET refers to the CIE at CIE_OFFSET, but the - // section is not that large. - virtual void CIEPointerOutOfRange(uint64 offset, uint64 cie_offset); - - // The FDE at OFFSET refers to the CIE at CIE_OFFSET, but the entry - // there is not a CIE. - virtual void BadCIEId(uint64 offset, uint64 cie_offset); - - // The FDE at OFFSET refers to a CIE with version number VERSION, - // which we don't recognize. We cannot parse DWARF CFI if it uses - // a version number we don't recognize. - virtual void UnrecognizedVersion(uint64 offset, int version); - - // The FDE at OFFSET refers to a CIE with augmentation AUGMENTATION, - // which we don't recognize. We cannot parse DWARF CFI if it uses - // augmentations we don't recognize. - virtual void UnrecognizedAugmentation(uint64 offset, - const string &augmentation); - - // The pointer encoding ENCODING, specified by the CIE at OFFSET, is not - // a valid encoding. - virtual void InvalidPointerEncoding(uint64 offset, uint8 encoding); - - // The pointer encoding ENCODING, specified by the CIE at OFFSET, depends - // on a base address which has not been supplied. - virtual void UnusablePointerEncoding(uint64 offset, uint8 encoding); - - // The CIE at OFFSET contains a DW_CFA_restore instruction at - // INSN_OFFSET, which may not appear in a CIE. - virtual void RestoreInCIE(uint64 offset, uint64 insn_offset); - - // The entry at OFFSET, of kind KIND, has an unrecognized - // instruction at INSN_OFFSET. - virtual void BadInstruction(uint64 offset, CallFrameInfo::EntryKind kind, - uint64 insn_offset); - - // The instruction at INSN_OFFSET in the entry at OFFSET, of kind - // KIND, establishes a rule that cites the CFA, but we have not - // established a CFA rule yet. - virtual void NoCFARule(uint64 offset, CallFrameInfo::EntryKind kind, - uint64 insn_offset); - - // The instruction at INSN_OFFSET in the entry at OFFSET, of kind - // KIND, is a DW_CFA_restore_state instruction, but the stack of - // saved states is empty. - virtual void EmptyStateStack(uint64 offset, CallFrameInfo::EntryKind kind, - uint64 insn_offset); - - // The DW_CFA_remember_state instruction at INSN_OFFSET in the entry - // at OFFSET, of kind KIND, would restore a state that has no CFA - // rule, whereas the current state does have a CFA rule. This is - // bogus input, which the CallFrameInfo::Handler interface doesn't - // (and shouldn't) have any way to report. - virtual void ClearingCFARule(uint64 offset, CallFrameInfo::EntryKind kind, - uint64 insn_offset); - - protected: - // The name of the file whose CFI we're reading. - string filename_; - - // The name of the CFI section in that file. - string section_; -}; - -} // namespace dwarf2reader - -#endif // UTIL_DEBUGINFO_DWARF2READER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_cfi_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_cfi_unittest.cc deleted file mode 100644 index e50ea5fbd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_cfi_unittest.cc +++ /dev/null @@ -1,2468 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2reader_cfi_unittest.cc: Unit tests for dwarf2reader::CallFrameInfo - -#include -#include - -#include -#include - -// The '.eh_frame' format, used by the Linux C++ ABI for exception -// handling, is poorly specified. To help test our support for .eh_frame, -// if you #define WRITE_ELF while compiling this file, and add the -// 'include' directory from the binutils, gcc, or gdb source tree to the -// #include path, then each test that calls the -// PERHAPS_WRITE_DEBUG_FRAME_FILE or PERHAPS_WRITE_EH_FRAME_FILE will write -// an ELF file containing a .debug_frame or .eh_frame section; you can then -// use tools like readelf to examine the test data, and check the tools' -// interpretation against the test's intentions. Each ELF file is named -// "cfitest-TEST", where TEST identifies the particular test. -#ifdef WRITE_ELF -#include -#include -#include -extern "C" { -// To compile with WRITE_ELF, you should add the 'include' directory -// of the binutils, gcc, or gdb source tree to your #include path; -// that directory contains this header. -#include "elf/common.h" -} -#endif - -#include "breakpad_googletest_includes.h" -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/cfi_assembler.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -using google_breakpad::CFISection; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Section; - -using dwarf2reader::DwarfPointerEncoding; -using dwarf2reader::ENDIANNESS_BIG; -using dwarf2reader::ENDIANNESS_LITTLE; -using dwarf2reader::ByteReader; -using dwarf2reader::CallFrameInfo; - -using std::vector; -using testing::InSequence; -using testing::Return; -using testing::Sequence; -using testing::Test; -using testing::_; - -#ifdef WRITE_ELF -void WriteELFFrameSection(const char *filename, const char *section_name, - const CFISection §ion); -#define PERHAPS_WRITE_DEBUG_FRAME_FILE(name, section) \ - WriteELFFrameSection("cfitest-" name, ".debug_frame", section); -#define PERHAPS_WRITE_EH_FRAME_FILE(name, section) \ - WriteELFFrameSection("cfitest-" name, ".eh_frame", section); -#else -#define PERHAPS_WRITE_DEBUG_FRAME_FILE(name, section) -#define PERHAPS_WRITE_EH_FRAME_FILE(name, section) -#endif - -class MockCallFrameInfoHandler: public CallFrameInfo::Handler { - public: - MOCK_METHOD6(Entry, bool(size_t offset, uint64 address, uint64 length, - uint8 version, const string &augmentation, - unsigned return_address)); - MOCK_METHOD2(UndefinedRule, bool(uint64 address, int reg)); - MOCK_METHOD2(SameValueRule, bool(uint64 address, int reg)); - MOCK_METHOD4(OffsetRule, bool(uint64 address, int reg, int base_register, - long offset)); - MOCK_METHOD4(ValOffsetRule, bool(uint64 address, int reg, int base_register, - long offset)); - MOCK_METHOD3(RegisterRule, bool(uint64 address, int reg, int base_register)); - MOCK_METHOD3(ExpressionRule, bool(uint64 address, int reg, - const string &expression)); - MOCK_METHOD3(ValExpressionRule, bool(uint64 address, int reg, - const string &expression)); - MOCK_METHOD0(End, bool()); - MOCK_METHOD2(PersonalityRoutine, bool(uint64 address, bool indirect)); - MOCK_METHOD2(LanguageSpecificDataArea, bool(uint64 address, bool indirect)); - MOCK_METHOD0(SignalHandler, bool()); -}; - -class MockCallFrameErrorReporter: public CallFrameInfo::Reporter { - public: - MockCallFrameErrorReporter() : Reporter("mock filename", "mock section") { } - MOCK_METHOD2(Incomplete, void(uint64, CallFrameInfo::EntryKind)); - MOCK_METHOD1(EarlyEHTerminator, void(uint64)); - MOCK_METHOD2(CIEPointerOutOfRange, void(uint64, uint64)); - MOCK_METHOD2(BadCIEId, void(uint64, uint64)); - MOCK_METHOD2(UnrecognizedVersion, void(uint64, int version)); - MOCK_METHOD2(UnrecognizedAugmentation, void(uint64, const string &)); - MOCK_METHOD2(InvalidPointerEncoding, void(uint64, uint8)); - MOCK_METHOD2(UnusablePointerEncoding, void(uint64, uint8)); - MOCK_METHOD2(RestoreInCIE, void(uint64, uint64)); - MOCK_METHOD3(BadInstruction, void(uint64, CallFrameInfo::EntryKind, uint64)); - MOCK_METHOD3(NoCFARule, void(uint64, CallFrameInfo::EntryKind, uint64)); - MOCK_METHOD3(EmptyStateStack, void(uint64, CallFrameInfo::EntryKind, uint64)); -}; - -struct CFIFixture { - - enum { kCFARegister = CallFrameInfo::Handler::kCFARegister }; - - CFIFixture() { - // Default expectations for the data handler. - // - // - Leave Entry and End without expectations, as it's probably a - // good idea to set those explicitly in each test. - // - // - Expect the *Rule functions to not be called, - // so that each test can simply list the calls they expect. - // - // I gather I could use StrictMock for this, but the manual seems - // to suggest using that only as a last resort, and this isn't so - // bad. - EXPECT_CALL(handler, UndefinedRule(_, _)).Times(0); - EXPECT_CALL(handler, SameValueRule(_, _)).Times(0); - EXPECT_CALL(handler, OffsetRule(_, _, _, _)).Times(0); - EXPECT_CALL(handler, ValOffsetRule(_, _, _, _)).Times(0); - EXPECT_CALL(handler, RegisterRule(_, _, _)).Times(0); - EXPECT_CALL(handler, ExpressionRule(_, _, _)).Times(0); - EXPECT_CALL(handler, ValExpressionRule(_, _, _)).Times(0); - EXPECT_CALL(handler, PersonalityRoutine(_, _)).Times(0); - EXPECT_CALL(handler, LanguageSpecificDataArea(_, _)).Times(0); - EXPECT_CALL(handler, SignalHandler()).Times(0); - - // Default expectations for the error/warning reporer. - EXPECT_CALL(reporter, Incomplete(_, _)).Times(0); - EXPECT_CALL(reporter, EarlyEHTerminator(_)).Times(0); - EXPECT_CALL(reporter, CIEPointerOutOfRange(_, _)).Times(0); - EXPECT_CALL(reporter, BadCIEId(_, _)).Times(0); - EXPECT_CALL(reporter, UnrecognizedVersion(_, _)).Times(0); - EXPECT_CALL(reporter, UnrecognizedAugmentation(_, _)).Times(0); - EXPECT_CALL(reporter, InvalidPointerEncoding(_, _)).Times(0); - EXPECT_CALL(reporter, UnusablePointerEncoding(_, _)).Times(0); - EXPECT_CALL(reporter, RestoreInCIE(_, _)).Times(0); - EXPECT_CALL(reporter, BadInstruction(_, _, _)).Times(0); - EXPECT_CALL(reporter, NoCFARule(_, _, _)).Times(0); - EXPECT_CALL(reporter, EmptyStateStack(_, _, _)).Times(0); - } - - MockCallFrameInfoHandler handler; - MockCallFrameErrorReporter reporter; -}; - -class CFI: public CFIFixture, public Test { }; - -TEST_F(CFI, EmptyRegion) { - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - static const uint8_t data[] = { 42 }; - - ByteReader byte_reader(ENDIANNESS_BIG); - CallFrameInfo parser(data, 0, &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -TEST_F(CFI, IncompleteLength32) { - CFISection section(kBigEndian, 8); - section - // Not even long enough for an initial length. - .D16(0xa0f) - // Padding to keep valgrind happy. We subtract these off when we - // construct the parser. - .D16(0); - - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - - EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown)) - .WillOnce(Return()); - - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(8); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size() - 2, - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -TEST_F(CFI, IncompleteLength64) { - CFISection section(kLittleEndian, 4); - section - // An incomplete 64-bit DWARF initial length. - .D32(0xffffffff).D32(0x71fbaec2) - // Padding to keep valgrind happy. We subtract these off when we - // construct the parser. - .D32(0); - - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - - EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown)) - .WillOnce(Return()); - - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - - ByteReader byte_reader(ENDIANNESS_LITTLE); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size() - 4, - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -TEST_F(CFI, IncompleteId32) { - CFISection section(kBigEndian, 8); - section - .D32(3) // Initial length, not long enough for id - .D8(0xd7).D8(0xe5).D8(0xf1) // incomplete id - .CIEHeader(8727, 3983, 8889, 3, "") - .FinishEntry(); - - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - - EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown)) - .WillOnce(Return()); - - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(8); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -TEST_F(CFI, BadId32) { - CFISection section(kBigEndian, 8); - section - .D32(0x100) // Initial length - .D32(0xe802fade) // bogus ID - .Append(0x100 - 4, 0x42); // make the length true - section - .CIEHeader(1672, 9872, 8529, 3, "") - .FinishEntry(); - - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - - EXPECT_CALL(reporter, CIEPointerOutOfRange(_, 0xe802fade)) - .WillOnce(Return()); - - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(8); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -// A lone CIE shouldn't cause any handler calls. -TEST_F(CFI, SingleCIE) { - CFISection section(kLittleEndian, 4); - section.CIEHeader(0xffe799a8, 0x3398dcdd, 0x6e9683de, 3, ""); - section.Append(10, dwarf2reader::DW_CFA_nop); - section.FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("SingleCIE", section); - - EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); - EXPECT_CALL(handler, End()).Times(0); - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_LITTLE); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -// One FDE, one CIE. -TEST_F(CFI, OneFDE) { - CFISection section(kBigEndian, 4); - Label cie; - section - .Mark(&cie) - .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "") - .FinishEntry() - .FDEHeader(cie, 0x7714740d, 0x3d5a10cd) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("OneFDE", section); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, 0x7714740d, 0x3d5a10cd, 3, "", 0x6b6efb87)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -// Two FDEs share a CIE. -TEST_F(CFI, TwoFDEsOneCIE) { - CFISection section(kBigEndian, 4); - Label cie; - section - // First FDE. readelf complains about this one because it makes - // a forward reference to its CIE. - .FDEHeader(cie, 0xa42744df, 0xa3b42121) - .FinishEntry() - // CIE. - .Mark(&cie) - .CIEHeader(0x04f7dc7b, 0x3d00c05f, 0xbd43cb59, 3, "") - .FinishEntry() - // Second FDE. - .FDEHeader(cie, 0x6057d391, 0x700f608d) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsOneCIE", section); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, 0xa42744df, 0xa3b42121, 3, "", 0xbd43cb59)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, 0x6057d391, 0x700f608d, 3, "", 0xbd43cb59)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -// Two FDEs, two CIEs. -TEST_F(CFI, TwoFDEsTwoCIEs) { - CFISection section(kLittleEndian, 8); - Label cie1, cie2; - section - // First CIE. - .Mark(&cie1) - .CIEHeader(0x694d5d45, 0x4233221b, 0xbf45e65a, 3, "") - .FinishEntry() - // First FDE which cites second CIE. readelf complains about - // this one because it makes a forward reference to its CIE. - .FDEHeader(cie2, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL) - .FinishEntry() - // Second FDE, which cites first CIE. - .FDEHeader(cie1, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL) - .FinishEntry() - // Second CIE. - .Mark(&cie2) - .CIEHeader(0xfba3fad7, 0x6287e1fd, 0x61d2c581, 2, "") - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsTwoCIEs", section); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL, 2, - "", 0x61d2c581)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL, 3, - "", 0xbf45e65a)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_LITTLE); - byte_reader.SetAddressSize(8); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -// An FDE whose CIE specifies a version we don't recognize. -TEST_F(CFI, BadVersion) { - CFISection section(kBigEndian, 4); - Label cie1, cie2; - section - .Mark(&cie1) - .CIEHeader(0xca878cf0, 0x7698ec04, 0x7b616f54, 0x52, "") - .FinishEntry() - // We should skip this entry, as its CIE specifies a version we - // don't recognize. - .FDEHeader(cie1, 0x08852292, 0x2204004a) - .FinishEntry() - // Despite the above, we should visit this entry. - .Mark(&cie2) - .CIEHeader(0x7c3ae7c9, 0xb9b9a512, 0x96cb3264, 3, "") - .FinishEntry() - .FDEHeader(cie2, 0x2094735a, 0x6e875501) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("BadVersion", section); - - EXPECT_CALL(reporter, UnrecognizedVersion(_, 0x52)) - .WillOnce(Return()); - - { - InSequence s; - // We should see no mention of the first FDE, but we should get - // a call to Entry for the second. - EXPECT_CALL(handler, Entry(_, 0x2094735a, 0x6e875501, 3, "", - 0x96cb3264)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -// An FDE whose CIE specifies an augmentation we don't recognize. -TEST_F(CFI, BadAugmentation) { - CFISection section(kBigEndian, 4); - Label cie1, cie2; - section - .Mark(&cie1) - .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "spaniels!") - .FinishEntry() - // We should skip this entry, as its CIE specifies an - // augmentation we don't recognize. - .FDEHeader(cie1, 0x7714740d, 0x3d5a10cd) - .FinishEntry() - // Despite the above, we should visit this entry. - .Mark(&cie2) - .CIEHeader(0xf8bc4399, 0x8cf09931, 0xf2f519b2, 3, "") - .FinishEntry() - .FDEHeader(cie2, 0x7bf0fda0, 0xcbcd28d8) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("BadAugmentation", section); - - EXPECT_CALL(reporter, UnrecognizedAugmentation(_, "spaniels!")) - .WillOnce(Return()); - - { - InSequence s; - // We should see no mention of the first FDE, but we should get - // a call to Entry for the second. - EXPECT_CALL(handler, Entry(_, 0x7bf0fda0, 0xcbcd28d8, 3, "", - 0xf2f519b2)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_FALSE(parser.Start()); -} - -// The return address column field is a byte in CFI version 1 -// (DWARF2), but a ULEB128 value in version 3 (DWARF3). -TEST_F(CFI, CIEVersion1ReturnColumn) { - CFISection section(kBigEndian, 4); - Label cie; - section - // CIE, using the version 1 format: return column is a ubyte. - .Mark(&cie) - // Use a value for the return column that is parsed differently - // as a ubyte and as a ULEB128. - .CIEHeader(0xbcdea24f, 0x5be28286, 0x9f, 1, "") - .FinishEntry() - // FDE, citing that CIE. - .FDEHeader(cie, 0xb8d347b5, 0x825e55dc) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion1ReturnColumn", section); - - { - InSequence s; - EXPECT_CALL(handler, Entry(_, 0xb8d347b5, 0x825e55dc, 1, "", 0x9f)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -// The return address column field is a byte in CFI version 1 -// (DWARF2), but a ULEB128 value in version 3 (DWARF3). -TEST_F(CFI, CIEVersion3ReturnColumn) { - CFISection section(kBigEndian, 4); - Label cie; - section - // CIE, using the version 3 format: return column is a ULEB128. - .Mark(&cie) - // Use a value for the return column that is parsed differently - // as a ubyte and as a ULEB128. - .CIEHeader(0x0ab4758d, 0xc010fdf7, 0x89, 3, "") - .FinishEntry() - // FDE, citing that CIE. - .FDEHeader(cie, 0x86763f2b, 0x2a66dc23) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion3ReturnColumn", section); - - { - InSequence s; - EXPECT_CALL(handler, Entry(_, 0x86763f2b, 0x2a66dc23, 3, "", 0x89)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - string contents; - EXPECT_TRUE(section.GetContents(&contents)); - ByteReader byte_reader(ENDIANNESS_BIG); - byte_reader.SetAddressSize(4); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - EXPECT_TRUE(parser.Start()); -} - -struct CFIInsnFixture: public CFIFixture { - CFIInsnFixture() : CFIFixture() { - data_factor = 0xb6f; - return_register = 0x9be1ed9f; - version = 3; - cfa_base_register = 0x383a3aa; - cfa_offset = 0xf748; - } - - // Prepare SECTION to receive FDE instructions. - // - // - Append a stock CIE header that establishes the fixture's - // code_factor, data_factor, return_register, version, and - // augmentation values. - // - Have the CIE set up a CFA rule using cfa_base_register and - // cfa_offset. - // - Append a stock FDE header, referring to the above CIE, for the - // fde_size bytes at fde_start. Choose fde_start and fde_size - // appropriately for the section's address size. - // - Set appropriate expectations on handler in sequence s for the - // frame description entry and the CIE's CFA rule. - // - // On return, SECTION is ready to have FDE instructions appended to - // it, and its FinishEntry member called. - void StockCIEAndFDE(CFISection *section) { - // Choose appropriate constants for our address size. - if (section->AddressSize() == 4) { - fde_start = 0xc628ecfbU; - fde_size = 0x5dee04a2; - code_factor = 0x60b; - } else { - assert(section->AddressSize() == 8); - fde_start = 0x0005c57ce7806bd3ULL; - fde_size = 0x2699521b5e333100ULL; - code_factor = 0x01008e32855274a8ULL; - } - - // Create the CIE. - (*section) - .Mark(&cie_label) - .CIEHeader(code_factor, data_factor, return_register, version, - "") - .D8(dwarf2reader::DW_CFA_def_cfa) - .ULEB128(cfa_base_register) - .ULEB128(cfa_offset) - .FinishEntry(); - - // Create the FDE. - section->FDEHeader(cie_label, fde_start, fde_size); - - // Expect an Entry call for the FDE and a ValOffsetRule call for the - // CIE's CFA rule. - EXPECT_CALL(handler, Entry(_, fde_start, fde_size, version, "", - return_register)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(fde_start, kCFARegister, - cfa_base_register, cfa_offset)) - .InSequence(s) - .WillOnce(Return(true)); - } - - // Run the contents of SECTION through a CallFrameInfo parser, - // expecting parser.Start to return SUCCEEDS - void ParseSection(CFISection *section, bool succeeds = true) { - string contents; - EXPECT_TRUE(section->GetContents(&contents)); - dwarf2reader::Endianness endianness; - if (section->endianness() == kBigEndian) - endianness = ENDIANNESS_BIG; - else { - assert(section->endianness() == kLittleEndian); - endianness = ENDIANNESS_LITTLE; - } - ByteReader byte_reader(endianness); - byte_reader.SetAddressSize(section->AddressSize()); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter); - if (succeeds) - EXPECT_TRUE(parser.Start()); - else - EXPECT_FALSE(parser.Start()); - } - - Label cie_label; - Sequence s; - uint64 code_factor; - int data_factor; - unsigned return_register; - unsigned version; - unsigned cfa_base_register; - int cfa_offset; - uint64 fde_start, fde_size; -}; - -class CFIInsn: public CFIInsnFixture, public Test { }; - -TEST_F(CFIInsn, DW_CFA_set_loc) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_set_loc).D32(0xb1ee3e7a) - // Use DW_CFA_def_cfa to force a handler call that we can use to - // check the effect of the DW_CFA_set_loc. - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x4defb431).ULEB128(0x6d17b0ee) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_set_loc", section); - - EXPECT_CALL(handler, - ValOffsetRule(0xb1ee3e7a, kCFARegister, 0x4defb431, 0x6d17b0ee)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_advance_loc) { - CFISection section(kBigEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_advance_loc | 0x2a) - // Use DW_CFA_def_cfa to force a handler call that we can use to - // check the effect of the DW_CFA_advance_loc. - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x5bbb3715).ULEB128(0x0186c7bf) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc", section); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start + 0x2a * code_factor, - kCFARegister, 0x5bbb3715, 0x0186c7bf)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_advance_loc1) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_advance_loc1).D8(0xd8) - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x69d5696a).ULEB128(0x1eb7fc93) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc1", section); - - EXPECT_CALL(handler, - ValOffsetRule((fde_start + 0xd8 * code_factor), - kCFARegister, 0x69d5696a, 0x1eb7fc93)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_advance_loc2) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_advance_loc2).D16(0x3adb) - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x3a368bed).ULEB128(0x3194ee37) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc2", section); - - EXPECT_CALL(handler, - ValOffsetRule((fde_start + 0x3adb * code_factor), - kCFARegister, 0x3a368bed, 0x3194ee37)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_advance_loc4) { - CFISection section(kBigEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_advance_loc4).D32(0x15813c88) - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x135270c5).ULEB128(0x24bad7cb) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc4", section); - - EXPECT_CALL(handler, - ValOffsetRule((fde_start + 0x15813c88ULL * code_factor), - kCFARegister, 0x135270c5, 0x24bad7cb)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_MIPS_advance_loc8) { - code_factor = 0x2d; - CFISection section(kBigEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_MIPS_advance_loc8).D64(0x3c4f3945b92c14ULL) - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0xe17ed602).ULEB128(0x3d162e7f) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc8", section); - - EXPECT_CALL(handler, - ValOffsetRule((fde_start + 0x3c4f3945b92c14ULL * code_factor), - kCFARegister, 0xe17ed602, 0x3d162e7f)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x4e363a85).ULEB128(0x815f9aa7) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_def_cfa", section); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x4e363a85, 0x815f9aa7)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa_sf) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_sf).ULEB128(0x8ccb32b7).LEB128(0x9ea) - .D8(dwarf2reader::DW_CFA_def_cfa_sf).ULEB128(0x9b40f5da).LEB128(-0x40a2) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x8ccb32b7, - 0x9ea * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x9b40f5da, - -0x40a2 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa_register) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_register).ULEB128(0x3e7e9363) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x3e7e9363, cfa_offset)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -// DW_CFA_def_cfa_register should have no effect when applied to a -// non-base/offset rule. -TEST_F(CFIInsn, DW_CFA_def_cfa_registerBadRule) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("needle in a haystack") - .D8(dwarf2reader::DW_CFA_def_cfa_register).ULEB128(0xf1b49e49) - .FinishEntry(); - - EXPECT_CALL(handler, - ValExpressionRule(fde_start, kCFARegister, - "needle in a haystack")) - .WillRepeatedly(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa_offset) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, cfa_base_register, - 0x1e8e3b9b)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa_offset_sf) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_offset_sf).LEB128(0x970) - .D8(dwarf2reader::DW_CFA_def_cfa_offset_sf).LEB128(-0x2cd) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, cfa_base_register, - 0x970 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, cfa_base_register, - -0x2cd * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -// DW_CFA_def_cfa_offset should have no effect when applied to a -// non-base/offset rule. -TEST_F(CFIInsn, DW_CFA_def_cfa_offsetBadRule) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("six ways to Sunday") - .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b) - .FinishEntry(); - - EXPECT_CALL(handler, - ValExpressionRule(fde_start, kCFARegister, "six ways to Sunday")) - .WillRepeatedly(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_def_cfa_expression) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("eating crow") - .FinishEntry(); - - EXPECT_CALL(handler, ValExpressionRule(fde_start, kCFARegister, - "eating crow")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_undefined) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x300ce45d) - .FinishEntry(); - - EXPECT_CALL(handler, UndefinedRule(fde_start, 0x300ce45d)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_same_value) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x3865a760) - .FinishEntry(); - - EXPECT_CALL(handler, SameValueRule(fde_start, 0x3865a760)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_offset) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset | 0x2c).ULEB128(0x9f6) - .FinishEntry(); - - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x2c, kCFARegister, 0x9f6 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_offset_extended) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset_extended).ULEB128(0x402b).ULEB128(0xb48) - .FinishEntry(); - - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x402b, kCFARegister, 0xb48 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_offset_extended_sf) { - CFISection section(kBigEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset_extended_sf) - .ULEB128(0x997c23ee).LEB128(0x2d00) - .D8(dwarf2reader::DW_CFA_offset_extended_sf) - .ULEB128(0x9519eb82).LEB128(-0xa77) - .FinishEntry(); - - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x997c23ee, - kCFARegister, 0x2d00 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x9519eb82, - kCFARegister, -0xa77 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_val_offset) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x623562fe).ULEB128(0x673) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, 0x623562fe, - kCFARegister, 0x673 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_val_offset_sf) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_offset_sf).ULEB128(0x6f4f).LEB128(0xaab) - .D8(dwarf2reader::DW_CFA_val_offset_sf).ULEB128(0x2483).LEB128(-0x8a2) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, 0x6f4f, - kCFARegister, 0xaab * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, - ValOffsetRule(fde_start, 0x2483, - kCFARegister, -0x8a2 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_register) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_register).ULEB128(0x278d18f9).ULEB128(0x1a684414) - .FinishEntry(); - - EXPECT_CALL(handler, RegisterRule(fde_start, 0x278d18f9, 0x1a684414)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_expression) { - CFISection section(kBigEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0xa1619fb2) - .Block("plus ça change, plus c'est la même chose") - .FinishEntry(); - - EXPECT_CALL(handler, - ExpressionRule(fde_start, 0xa1619fb2, - "plus ça change, plus c'est la même chose")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_val_expression) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0xc5e4a9e3) - .Block("he who has the gold makes the rules") - .FinishEntry(); - - EXPECT_CALL(handler, - ValExpressionRule(fde_start, 0xc5e4a9e3, - "he who has the gold makes the rules")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_restore) { - CFISection section(kLittleEndian, 8); - code_factor = 0x01bd188a9b1fa083ULL; - data_factor = -0x1ac8; - return_register = 0x8c35b049; - version = 2; - fde_start = 0x2d70fe998298bbb1ULL; - fde_size = 0x46ccc2e63cf0b108ULL; - Label cie; - section - .Mark(&cie) - .CIEHeader(code_factor, data_factor, return_register, version, - "") - // Provide a CFA rule, because register rules require them. - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x6ca1d50e).ULEB128(0x372e38e8) - // Provide an offset(N) rule for register 0x3c. - .D8(dwarf2reader::DW_CFA_offset | 0x3c).ULEB128(0xb348) - .FinishEntry() - // In the FDE... - .FDEHeader(cie, fde_start, fde_size) - // At a second address, provide a new offset(N) rule for register 0x3c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0x13) - .D8(dwarf2reader::DW_CFA_offset | 0x3c).ULEB128(0x9a50) - // At a third address, restore the original rule for register 0x3c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0x01) - .D8(dwarf2reader::DW_CFA_restore | 0x3c) - .FinishEntry(); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, fde_start, fde_size, version, "", return_register)) - .WillOnce(Return(true)); - // CIE's CFA rule. - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x6ca1d50e, 0x372e38e8)) - .WillOnce(Return(true)); - // CIE's rule for register 0x3c. - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x3c, kCFARegister, 0xb348 * data_factor)) - .WillOnce(Return(true)); - // FDE's rule for register 0x3c. - EXPECT_CALL(handler, - OffsetRule(fde_start + 0x13 * code_factor, 0x3c, - kCFARegister, 0x9a50 * data_factor)) - .WillOnce(Return(true)); - // Restore CIE's rule for register 0x3c. - EXPECT_CALL(handler, - OffsetRule(fde_start + (0x13 + 0x01) * code_factor, 0x3c, - kCFARegister, 0xb348 * data_factor)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_restoreNoRule) { - CFISection section(kBigEndian, 4); - code_factor = 0x005f78143c1c3b82ULL; - data_factor = 0x25d0; - return_register = 0xe8; - version = 1; - fde_start = 0x4062e30f; - fde_size = 0x5302a389; - Label cie; - section - .Mark(&cie) - .CIEHeader(code_factor, data_factor, return_register, version, "") - // Provide a CFA rule, because register rules require them. - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x470aa334).ULEB128(0x099ef127) - .FinishEntry() - // In the FDE... - .FDEHeader(cie, fde_start, fde_size) - // At a second address, provide an offset(N) rule for register 0x2c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0x7) - .D8(dwarf2reader::DW_CFA_offset | 0x2c).ULEB128(0x1f47) - // At a third address, restore the (missing) CIE rule for register 0x2c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0xb) - .D8(dwarf2reader::DW_CFA_restore | 0x2c) - .FinishEntry(); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, fde_start, fde_size, version, "", return_register)) - .WillOnce(Return(true)); - // CIE's CFA rule. - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x470aa334, 0x099ef127)) - .WillOnce(Return(true)); - // FDE's rule for register 0x2c. - EXPECT_CALL(handler, - OffsetRule(fde_start + 0x7 * code_factor, 0x2c, - kCFARegister, 0x1f47 * data_factor)) - .WillOnce(Return(true)); - // Restore CIE's (missing) rule for register 0x2c. - EXPECT_CALL(handler, - SameValueRule(fde_start + (0x7 + 0xb) * code_factor, 0x2c)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_restore_extended) { - CFISection section(kBigEndian, 4); - code_factor = 0x126e; - data_factor = -0xd8b; - return_register = 0x77711787; - version = 3; - fde_start = 0x01f55a45; - fde_size = 0x452adb80; - Label cie; - section - .Mark(&cie) - .CIEHeader(code_factor, data_factor, return_register, version, - "", true /* dwarf64 */ ) - // Provide a CFA rule, because register rules require them. - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x56fa0edd).ULEB128(0x097f78a5) - // Provide an offset(N) rule for register 0x0f9b8a1c. - .D8(dwarf2reader::DW_CFA_offset_extended) - .ULEB128(0x0f9b8a1c).ULEB128(0xc979) - .FinishEntry() - // In the FDE... - .FDEHeader(cie, fde_start, fde_size) - // At a second address, provide a new offset(N) rule for reg 0x0f9b8a1c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0x3) - .D8(dwarf2reader::DW_CFA_offset_extended) - .ULEB128(0x0f9b8a1c).ULEB128(0x3b7b) - // At a third address, restore the original rule for register 0x0f9b8a1c. - .D8(dwarf2reader::DW_CFA_advance_loc | 0x04) - .D8(dwarf2reader::DW_CFA_restore_extended).ULEB128(0x0f9b8a1c) - .FinishEntry(); - - { - InSequence s; - EXPECT_CALL(handler, - Entry(_, fde_start, fde_size, version, "", return_register)) - .WillOnce(Return(true)); - // CIE's CFA rule. - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x56fa0edd, 0x097f78a5)) - .WillOnce(Return(true)); - // CIE's rule for register 0x0f9b8a1c. - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x0f9b8a1c, kCFARegister, - 0xc979 * data_factor)) - .WillOnce(Return(true)); - // FDE's rule for register 0x0f9b8a1c. - EXPECT_CALL(handler, - OffsetRule(fde_start + 0x3 * code_factor, 0x0f9b8a1c, - kCFARegister, 0x3b7b * data_factor)) - .WillOnce(Return(true)); - // Restore CIE's rule for register 0x0f9b8a1c. - EXPECT_CALL(handler, - OffsetRule(fde_start + (0x3 + 0x4) * code_factor, 0x0f9b8a1c, - kCFARegister, 0xc979 * data_factor)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - } - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_remember_and_restore_state) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - - // We create a state, save it, modify it, and then restore. We - // refer to the state that is overridden the restore as the - // "outgoing" state, and the restored state the "incoming" state. - // - // Register outgoing incoming expect - // 1 offset(N) no rule new "same value" rule - // 2 register(R) offset(N) report changed rule - // 3 offset(N) offset(M) report changed offset - // 4 offset(N) offset(N) no report - // 5 offset(N) no rule new "same value" rule - section - // Create the "incoming" state, which we will save and later restore. - .D8(dwarf2reader::DW_CFA_offset | 2).ULEB128(0x9806) - .D8(dwarf2reader::DW_CFA_offset | 3).ULEB128(0x995d) - .D8(dwarf2reader::DW_CFA_offset | 4).ULEB128(0x7055) - .D8(dwarf2reader::DW_CFA_remember_state) - // Advance to a new instruction; an implementation could legitimately - // ignore all but the final rule for a given register at a given address. - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - // Create the "outgoing" state, which we will discard. - .D8(dwarf2reader::DW_CFA_offset | 1).ULEB128(0xea1a) - .D8(dwarf2reader::DW_CFA_register).ULEB128(2).ULEB128(0x1d2a3767) - .D8(dwarf2reader::DW_CFA_offset | 3).ULEB128(0xdd29) - .D8(dwarf2reader::DW_CFA_offset | 5).ULEB128(0xf1ce) - // At a third address, restore the incoming state. - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - uint64 addr = fde_start; - - // Expect the incoming rules to be reported. - EXPECT_CALL(handler, OffsetRule(addr, 2, kCFARegister, 0x9806 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0x995d * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 4, kCFARegister, 0x7055 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - - addr += code_factor; - - // After the save, we establish the outgoing rule set. - EXPECT_CALL(handler, OffsetRule(addr, 1, kCFARegister, 0xea1a * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(addr, 2, 0x1d2a3767)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0xdd29 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 5, kCFARegister, 0xf1ce * data_factor)) - .InSequence(s).WillOnce(Return(true)); - - addr += code_factor; - - // Finally, after the restore, expect to see the differences from - // the outgoing to the incoming rules reported. - EXPECT_CALL(handler, SameValueRule(addr, 1)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 2, kCFARegister, 0x9806 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0x995d * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, SameValueRule(addr, 5)) - .InSequence(s).WillOnce(Return(true)); - - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -// Check that restoring a rule set reports changes to the CFA rule. -TEST_F(CFIInsn, DW_CFA_remember_and_restore_stateCFA) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - - section - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x90481102) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor, kCFARegister, - cfa_base_register, 0x90481102)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor * 2, kCFARegister, - cfa_base_register, cfa_offset)) - .InSequence(s).WillOnce(Return(true)); - - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_nop) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_nop) - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x3fb8d4f1).ULEB128(0x078dc67b) - .D8(dwarf2reader::DW_CFA_nop) - .FinishEntry(); - - EXPECT_CALL(handler, - ValOffsetRule(fde_start, kCFARegister, 0x3fb8d4f1, 0x078dc67b)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_GNU_window_save) { - CFISection section(kBigEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_GNU_window_save) - .FinishEntry(); - - // Don't include all the rules in any particular sequence. - - // The caller's %o0-%o7 have become the callee's %i0-%i7. This is - // the GCC register numbering. - for (int i = 8; i < 16; i++) - EXPECT_CALL(handler, RegisterRule(fde_start, i, i + 16)) - .WillOnce(Return(true)); - // The caller's %l0-%l7 and %i0-%i7 have been saved at the top of - // its frame. - for (int i = 16; i < 32; i++) - EXPECT_CALL(handler, OffsetRule(fde_start, i, kCFARegister, (i-16) * 4)) - .WillOnce(Return(true)); - - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_GNU_args_size) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_GNU_args_size).ULEB128(0xeddfa520) - // Verify that we see this, meaning we parsed the above properly. - .D8(dwarf2reader::DW_CFA_offset | 0x23).ULEB128(0x269) - .FinishEntry(); - - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x23, kCFARegister, 0x269 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIInsn, DW_CFA_GNU_negative_offset_extended) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_GNU_negative_offset_extended) - .ULEB128(0x430cc87a).ULEB128(0x613) - .FinishEntry(); - - EXPECT_CALL(handler, - OffsetRule(fde_start, 0x430cc87a, - kCFARegister, -0x613 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion); -} - -// Three FDEs: skip the second -TEST_F(CFIInsn, SkipFDE) { - CFISection section(kBigEndian, 4); - Label cie; - section - // CIE, used by all FDEs. - .Mark(&cie) - .CIEHeader(0x010269f2, 0x9177, 0xedca5849, 2, "") - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x42ed390b).ULEB128(0x98f43aad) - .FinishEntry() - // First FDE. - .FDEHeader(cie, 0xa870ebdd, 0x60f6aa4) - .D8(dwarf2reader::DW_CFA_register).ULEB128(0x3a860351).ULEB128(0x6c9a6bcf) - .FinishEntry() - // Second FDE. - .FDEHeader(cie, 0xc534f7c0, 0xf6552e9, true /* dwarf64 */) - .D8(dwarf2reader::DW_CFA_register).ULEB128(0x1b62c234).ULEB128(0x26586b18) - .FinishEntry() - // Third FDE. - .FDEHeader(cie, 0xf681cfc8, 0x7e4594e) - .D8(dwarf2reader::DW_CFA_register).ULEB128(0x26c53934).ULEB128(0x18eeb8a4) - .FinishEntry(); - - { - InSequence s; - - // Process the first FDE. - EXPECT_CALL(handler, Entry(_, 0xa870ebdd, 0x60f6aa4, 2, "", 0xedca5849)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(0xa870ebdd, kCFARegister, - 0x42ed390b, 0x98f43aad)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(0xa870ebdd, 0x3a860351, 0x6c9a6bcf)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .WillOnce(Return(true)); - - // Skip the second FDE. - EXPECT_CALL(handler, Entry(_, 0xc534f7c0, 0xf6552e9, 2, "", 0xedca5849)) - .WillOnce(Return(false)); - - // Process the third FDE. - EXPECT_CALL(handler, Entry(_, 0xf681cfc8, 0x7e4594e, 2, "", 0xedca5849)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(0xf681cfc8, kCFARegister, - 0x42ed390b, 0x98f43aad)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(0xf681cfc8, 0x26c53934, 0x18eeb8a4)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .WillOnce(Return(true)); - } - - ParseSection(§ion); -} - -// Quit processing in the middle of an entry's instructions. -TEST_F(CFIInsn, QuitMidentry) { - CFISection section(kLittleEndian, 8); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_register).ULEB128(0xe0cf850d).ULEB128(0x15aab431) - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x46750aa5).Block("meat") - .FinishEntry(); - - EXPECT_CALL(handler, RegisterRule(fde_start, 0xe0cf850d, 0x15aab431)) - .InSequence(s).WillOnce(Return(false)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseSection(§ion, false); -} - -class CFIRestore: public CFIInsnFixture, public Test { }; - -TEST_F(CFIRestore, RestoreUndefinedRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x0bac878e) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, UndefinedRule(fde_start, 0x0bac878e)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreUndefinedRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x7dedff5f) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x7dedff5f) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, UndefinedRule(fde_start, 0x7dedff5f)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, SameValueRule(fde_start + code_factor, 0x7dedff5f)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + 2 * code_factor, 0x7dedff5f)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreSameValueRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0xadbc9b3a) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, SameValueRule(fde_start, 0xadbc9b3a)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreSameValueRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x3d90dcb5) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x3d90dcb5) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, SameValueRule(fde_start, 0x3d90dcb5)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0x3d90dcb5)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, SameValueRule(fde_start + 2 * code_factor, 0x3d90dcb5)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreOffsetRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset | 0x14).ULEB128(0xb6f) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, OffsetRule(fde_start, 0x14, - kCFARegister, 0xb6f * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreOffsetRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0xeb7) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x21) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, OffsetRule(fde_start, 0x21, - kCFARegister, 0xeb7 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0x21)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(fde_start + 2 * code_factor, 0x21, - kCFARegister, 0xeb7 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreOffsetRuleChangedOffset) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0x134) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0xf4f) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, OffsetRule(fde_start, 0x21, - kCFARegister, 0x134 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(fde_start + code_factor, 0x21, - kCFARegister, 0xf4f * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, OffsetRule(fde_start + 2 * code_factor, 0x21, - kCFARegister, 0x134 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValOffsetRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x829caee6).ULEB128(0xe4c) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ValOffsetRule(fde_start, 0x829caee6, - kCFARegister, 0xe4c * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValOffsetRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0xf17c36d6).ULEB128(0xeb7) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xf17c36d6) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ValOffsetRule(fde_start, 0xf17c36d6, - kCFARegister, 0xeb7 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xf17c36d6)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(fde_start + 2 * code_factor, 0xf17c36d6, - kCFARegister, 0xeb7 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValOffsetRuleChangedValOffset) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x2cf0ab1b).ULEB128(0x562) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x2cf0ab1b).ULEB128(0xe88) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ValOffsetRule(fde_start, 0x2cf0ab1b, - kCFARegister, 0x562 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor, 0x2cf0ab1b, - kCFARegister, 0xe88 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(fde_start + 2 * code_factor, 0x2cf0ab1b, - kCFARegister, 0x562 * data_factor)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreRegisterRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_register).ULEB128(0x77514acc).ULEB128(0x464de4ce) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, RegisterRule(fde_start, 0x77514acc, 0x464de4ce)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreRegisterRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_register).ULEB128(0xe39acce5).ULEB128(0x095f1559) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xe39acce5) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, RegisterRule(fde_start, 0xe39acce5, 0x095f1559)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xe39acce5)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(fde_start + 2 * code_factor, 0xe39acce5, - 0x095f1559)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreRegisterRuleChangedRegister) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_register).ULEB128(0xd40e21b1).ULEB128(0x16607d6a) - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_register).ULEB128(0xd40e21b1).ULEB128(0xbabb4742) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, RegisterRule(fde_start, 0xd40e21b1, 0x16607d6a)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(fde_start + code_factor, 0xd40e21b1, - 0xbabb4742)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, RegisterRule(fde_start + 2 * code_factor, 0xd40e21b1, - 0x16607d6a)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreExpressionRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x666ae152).Block("dwarf") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ExpressionRule(fde_start, 0x666ae152, "dwarf")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreExpressionRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0xb5ca5c46).Block("elf") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xb5ca5c46) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ExpressionRule(fde_start, 0xb5ca5c46, "elf")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xb5ca5c46)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ExpressionRule(fde_start + 2 * code_factor, 0xb5ca5c46, - "elf")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreExpressionRuleChangedExpression) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x500f5739).Block("smurf") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x500f5739).Block("orc") - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ExpressionRule(fde_start, 0x500f5739, "smurf")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ExpressionRule(fde_start + code_factor, 0x500f5739, - "orc")) - .InSequence(s).WillOnce(Return(true)); - // Expectations are not wishes. - EXPECT_CALL(handler, ExpressionRule(fde_start + 2 * code_factor, 0x500f5739, - "smurf")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValExpressionRuleUnchanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x666ae152) - .Block("hideous") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - EXPECT_CALL(handler, ValExpressionRule(fde_start, 0x666ae152, "hideous")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValExpressionRuleChanged) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0xb5ca5c46) - .Block("revolting") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xb5ca5c46) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("RestoreValExpressionRuleChanged", section); - - EXPECT_CALL(handler, ValExpressionRule(fde_start, 0xb5ca5c46, "revolting")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xb5ca5c46)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValExpressionRule(fde_start + 2 * code_factor, 0xb5ca5c46, - "revolting")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -TEST_F(CFIRestore, RestoreValExpressionRuleChangedValExpression) { - CFISection section(kLittleEndian, 4); - StockCIEAndFDE(§ion); - section - .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x500f5739) - .Block("repulsive") - .D8(dwarf2reader::DW_CFA_remember_state) - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x500f5739) - .Block("nauseous") - .D8(dwarf2reader::DW_CFA_advance_loc | 1) - .D8(dwarf2reader::DW_CFA_restore_state) - .FinishEntry(); - - PERHAPS_WRITE_DEBUG_FRAME_FILE("RestoreValExpressionRuleChangedValExpression", - section); - - EXPECT_CALL(handler, ValExpressionRule(fde_start, 0x500f5739, "repulsive")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValExpressionRule(fde_start + code_factor, 0x500f5739, - "nauseous")) - .InSequence(s).WillOnce(Return(true)); - // Expectations are not wishes. - EXPECT_CALL(handler, ValExpressionRule(fde_start + 2 * code_factor, 0x500f5739, - "repulsive")) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()).WillOnce(Return(true)); - - ParseSection(§ion); -} - -struct EHFrameFixture: public CFIInsnFixture { - EHFrameFixture() - : CFIInsnFixture(), section(kBigEndian, 4, true) { - encoded_pointer_bases.cfi = 0x7f496cb2; - encoded_pointer_bases.text = 0x540f67b6; - encoded_pointer_bases.data = 0xe3eab768; - section.SetEncodedPointerBases(encoded_pointer_bases); - } - CFISection section; - CFISection::EncodedPointerBases encoded_pointer_bases; - - // Parse CFIInsnFixture::ParseSection, but parse the section as - // .eh_frame data, supplying stock base addresses. - void ParseEHFrameSection(CFISection *section, bool succeeds = true) { - EXPECT_TRUE(section->ContainsEHFrame()); - string contents; - EXPECT_TRUE(section->GetContents(&contents)); - dwarf2reader::Endianness endianness; - if (section->endianness() == kBigEndian) - endianness = ENDIANNESS_BIG; - else { - assert(section->endianness() == kLittleEndian); - endianness = ENDIANNESS_LITTLE; - } - ByteReader byte_reader(endianness); - byte_reader.SetAddressSize(section->AddressSize()); - byte_reader.SetCFIDataBase(encoded_pointer_bases.cfi, - reinterpret_cast(contents.data())); - byte_reader.SetTextBase(encoded_pointer_bases.text); - byte_reader.SetDataBase(encoded_pointer_bases.data); - CallFrameInfo parser(reinterpret_cast(contents.data()), - contents.size(), - &byte_reader, &handler, &reporter, true); - if (succeeds) - EXPECT_TRUE(parser.Start()); - else - EXPECT_FALSE(parser.Start()); - } - -}; - -class EHFrame: public EHFrameFixture, public Test { }; - -// A simple CIE, an FDE, and a terminator. -TEST_F(EHFrame, Terminator) { - Label cie; - section - .Mark(&cie) - .CIEHeader(9968, 2466, 67, 1, "") - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(3772).ULEB128(1372) - .FinishEntry() - .FDEHeader(cie, 0x848037a1, 0x7b30475e) - .D8(dwarf2reader::DW_CFA_set_loc).D32(0x17713850) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(5721) - .FinishEntry() - .D32(0) // Terminate the sequence. - // This FDE should be ignored. - .FDEHeader(cie, 0xf19629fe, 0x439fb09b) - .FinishEntry(); - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.Terminator", section); - - EXPECT_CALL(handler, Entry(_, 0x848037a1, 0x7b30475e, 1, "", 67)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(0x848037a1, kCFARegister, 3772, 1372)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(0x17713850, 5721)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(reporter, EarlyEHTerminator(_)) - .InSequence(s).WillOnce(Return()); - - ParseEHFrameSection(§ion); -} - -// The parser should recognize the Linux Standards Base 'z' augmentations. -TEST_F(EHFrame, SimpleFDE) { - DwarfPointerEncoding lsda_encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect - | dwarf2reader::DW_EH_PE_datarel - | dwarf2reader::DW_EH_PE_sdata2); - DwarfPointerEncoding fde_encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_textrel - | dwarf2reader::DW_EH_PE_udata2); - - section.SetPointerEncoding(fde_encoding); - section.SetEncodedPointerBases(encoded_pointer_bases); - Label cie; - section - .Mark(&cie) - .CIEHeader(4873, 7012, 100, 1, "zSLPR") - .ULEB128(7) // Augmentation data length - .D8(lsda_encoding) // LSDA pointer format - .D8(dwarf2reader::DW_EH_PE_pcrel) // personality pointer format - .EncodedPointer(0x97baa00, dwarf2reader::DW_EH_PE_pcrel) // and value - .D8(fde_encoding) // FDE pointer format - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(6706).ULEB128(31) - .FinishEntry() - .FDEHeader(cie, 0x540f6b56, 0xf686) - .ULEB128(2) // Augmentation data length - .EncodedPointer(0xe3eab475, lsda_encoding) // LSDA pointer, signed - .D8(dwarf2reader::DW_CFA_set_loc) - .EncodedPointer(0x540fa4ce, fde_encoding) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x675e) - .FinishEntry() - .D32(0); // terminator - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.SimpleFDE", section); - - EXPECT_CALL(handler, Entry(_, 0x540f6b56, 0xf686, 1, "zSLPR", 100)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, PersonalityRoutine(0x97baa00, false)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, LanguageSpecificDataArea(0xe3eab475, true)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, SignalHandler()) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(0x540f6b56, kCFARegister, 6706, 31)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(0x540fa4ce, 0x675e)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -// Check that we can handle an empty 'z' augmentation. -TEST_F(EHFrame, EmptyZ) { - Label cie; - section - .Mark(&cie) - .CIEHeader(5955, 5805, 228, 1, "z") - .ULEB128(0) // Augmentation data length - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(3629).ULEB128(247) - .FinishEntry() - .FDEHeader(cie, 0xda007738, 0xfb55c641) - .ULEB128(0) // Augmentation data length - .D8(dwarf2reader::DW_CFA_advance_loc1).D8(11) - .D8(dwarf2reader::DW_CFA_undefined).ULEB128(3769) - .FinishEntry(); - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.EmptyZ", section); - - EXPECT_CALL(handler, Entry(_, 0xda007738, 0xfb55c641, 1, "z", 228)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, ValOffsetRule(0xda007738, kCFARegister, 3629, 247)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, UndefinedRule(0xda007738 + 11 * 5955, 3769)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -// Check that we recognize bad 'z' augmentation characters. -TEST_F(EHFrame, BadZ) { - Label cie; - section - .Mark(&cie) - .CIEHeader(6937, 1045, 142, 1, "zQ") - .ULEB128(0) // Augmentation data length - .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(9006).ULEB128(7725) - .FinishEntry() - .FDEHeader(cie, 0x1293efa8, 0x236f53f2) - .ULEB128(0) // Augmentation data length - .D8(dwarf2reader::DW_CFA_advance_loc | 12) - .D8(dwarf2reader::DW_CFA_register).ULEB128(5667).ULEB128(3462) - .FinishEntry(); - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.BadZ", section); - - EXPECT_CALL(reporter, UnrecognizedAugmentation(_, "zQ")) - .WillOnce(Return()); - - ParseEHFrameSection(§ion, false); -} - -TEST_F(EHFrame, zL) { - Label cie; - DwarfPointerEncoding lsda_encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_funcrel - | dwarf2reader::DW_EH_PE_udata2); - section - .Mark(&cie) - .CIEHeader(9285, 9959, 54, 1, "zL") - .ULEB128(1) // Augmentation data length - .D8(lsda_encoding) // encoding for LSDA pointer in FDE - - .FinishEntry() - .FDEHeader(cie, 0xd40091aa, 0x9aa6e746) - .ULEB128(2) // Augmentation data length - .EncodedPointer(0xd40099cd, lsda_encoding) // LSDA pointer - .FinishEntry() - .D32(0); // terminator - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zL", section); - - EXPECT_CALL(handler, Entry(_, 0xd40091aa, 0x9aa6e746, 1, "zL", 54)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, LanguageSpecificDataArea(0xd40099cd, false)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -TEST_F(EHFrame, zP) { - Label cie; - DwarfPointerEncoding personality_encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_datarel - | dwarf2reader::DW_EH_PE_udata2); - section - .Mark(&cie) - .CIEHeader(1097, 6313, 17, 1, "zP") - .ULEB128(3) // Augmentation data length - .D8(personality_encoding) // encoding for personality routine - .EncodedPointer(0xe3eaccac, personality_encoding) // value - .FinishEntry() - .FDEHeader(cie, 0x0c8350c9, 0xbef11087) - .ULEB128(0) // Augmentation data length - .FinishEntry() - .D32(0); // terminator - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zP", section); - - EXPECT_CALL(handler, Entry(_, 0x0c8350c9, 0xbef11087, 1, "zP", 17)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, PersonalityRoutine(0xe3eaccac, false)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -TEST_F(EHFrame, zR) { - Label cie; - DwarfPointerEncoding pointer_encoding = - DwarfPointerEncoding(dwarf2reader::DW_EH_PE_textrel - | dwarf2reader::DW_EH_PE_sdata2); - section.SetPointerEncoding(pointer_encoding); - section - .Mark(&cie) - .CIEHeader(8011, 5496, 75, 1, "zR") - .ULEB128(1) // Augmentation data length - .D8(pointer_encoding) // encoding for FDE addresses - .FinishEntry() - .FDEHeader(cie, 0x540f9431, 0xbd0) - .ULEB128(0) // Augmentation data length - .FinishEntry() - .D32(0); // terminator - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zR", section); - - EXPECT_CALL(handler, Entry(_, 0x540f9431, 0xbd0, 1, "zR", 75)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -TEST_F(EHFrame, zS) { - Label cie; - section - .Mark(&cie) - .CIEHeader(9217, 7694, 57, 1, "zS") - .ULEB128(0) // Augmentation data length - .FinishEntry() - .FDEHeader(cie, 0xd40091aa, 0x9aa6e746) - .ULEB128(0) // Augmentation data length - .FinishEntry() - .D32(0); // terminator - - PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zS", section); - - EXPECT_CALL(handler, Entry(_, 0xd40091aa, 0x9aa6e746, 1, "zS", 57)) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, SignalHandler()) - .InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(handler, End()) - .InSequence(s).WillOnce(Return(true)); - - ParseEHFrameSection(§ion); -} - -// These tests require manual inspection of the test output. -struct CFIReporterFixture { - CFIReporterFixture() : reporter("test file name", "test section name") { } - CallFrameInfo::Reporter reporter; -}; - -class CFIReporter: public CFIReporterFixture, public Test { }; - -TEST_F(CFIReporter, Incomplete) { - reporter.Incomplete(0x0102030405060708ULL, CallFrameInfo::kUnknown); -} - -TEST_F(CFIReporter, EarlyEHTerminator) { - reporter.EarlyEHTerminator(0x0102030405060708ULL); -} - -TEST_F(CFIReporter, CIEPointerOutOfRange) { - reporter.CIEPointerOutOfRange(0x0123456789abcdefULL, 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, BadCIEId) { - reporter.BadCIEId(0x0123456789abcdefULL, 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, UnrecognizedVersion) { - reporter.UnrecognizedVersion(0x0123456789abcdefULL, 43); -} - -TEST_F(CFIReporter, UnrecognizedAugmentation) { - reporter.UnrecognizedAugmentation(0x0123456789abcdefULL, "poodles"); -} - -TEST_F(CFIReporter, InvalidPointerEncoding) { - reporter.InvalidPointerEncoding(0x0123456789abcdefULL, 0x42); -} - -TEST_F(CFIReporter, UnusablePointerEncoding) { - reporter.UnusablePointerEncoding(0x0123456789abcdefULL, 0x42); -} - -TEST_F(CFIReporter, RestoreInCIE) { - reporter.RestoreInCIE(0x0123456789abcdefULL, 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, BadInstruction) { - reporter.BadInstruction(0x0123456789abcdefULL, CallFrameInfo::kFDE, - 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, NoCFARule) { - reporter.NoCFARule(0x0123456789abcdefULL, CallFrameInfo::kCIE, - 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, EmptyStateStack) { - reporter.EmptyStateStack(0x0123456789abcdefULL, CallFrameInfo::kTerminator, - 0xfedcba9876543210ULL); -} - -TEST_F(CFIReporter, ClearingCFARule) { - reporter.ClearingCFARule(0x0123456789abcdefULL, CallFrameInfo::kFDE, - 0xfedcba9876543210ULL); -} - -#ifdef WRITE_ELF -// See comments at the top of the file mentioning WRITE_ELF for details. - -using google_breakpad::test_assembler::Section; - -struct ELFSectionHeader { - ELFSectionHeader(unsigned int set_type) - : type(set_type), flags(0), address(0), link(0), info(0), - alignment(1), entry_size(0) { } - Label name; - unsigned int type; - uint64_t flags; - uint64_t address; - Label file_offset; - Label file_size; - unsigned int link; - unsigned int info; - uint64_t alignment; - uint64_t entry_size; -}; - -void AppendSectionHeader(CFISection *table, const ELFSectionHeader &header) { - (*table) - .D32(header.name) // name, index in string tbl - .D32(header.type) // type - .Address(header.flags) // flags - .Address(header.address) // address in memory - .Address(header.file_offset) // offset in ELF file - .Address(header.file_size) // length in bytes - .D32(header.link) // link to related section - .D32(header.info) // miscellaneous - .Address(header.alignment) // alignment - .Address(header.entry_size); // entry size -} - -void WriteELFFrameSection(const char *filename, const char *cfi_name, - const CFISection &cfi) { - int elf_class = cfi.AddressSize() == 4 ? ELFCLASS32 : ELFCLASS64; - int elf_data = (cfi.endianness() == kBigEndian - ? ELFDATA2MSB : ELFDATA2LSB); - CFISection elf(cfi.endianness(), cfi.AddressSize()); - Label elf_header_size, section_table_offset; - elf - .Append("\x7f" "ELF") - .D8(elf_class) // 32-bit or 64-bit ELF - .D8(elf_data) // endianness - .D8(1) // ELF version - .D8(ELFOSABI_LINUX) // Operating System/ABI indication - .D8(0) // ABI version - .Append(7, 0xda) // padding - .D16(ET_EXEC) // file type: executable file - .D16(EM_386) // architecture: Intel IA-32 - .D32(EV_CURRENT); // ELF version - elf - .Address(0x0123456789abcdefULL) // program entry point - .Address(0) // program header offset - .Address(section_table_offset) // section header offset - .D32(0) // processor-specific flags - .D16(elf_header_size) // ELF header size in bytes */ - .D16(elf_class == ELFCLASS32 ? 32 : 56) // program header entry size - .D16(0) // program header table entry count - .D16(elf_class == ELFCLASS32 ? 40 : 64) // section header entry size - .D16(3) // section count - .D16(1) // section name string table - .Mark(&elf_header_size); - - // The null section. Every ELF file has one, as the first entry in - // the section header table. - ELFSectionHeader null_header(SHT_NULL); - null_header.file_offset = 0; - null_header.file_size = 0; - - // The CFI section. The whole reason for writing out this ELF file - // is to put this in it so that we can run other dumping programs on - // it to check its contents. - ELFSectionHeader cfi_header(SHT_PROGBITS); - cfi_header.file_size = cfi.Size(); - - // The section holding the names of the sections. This is the - // section whose index appears in the e_shstrndx member of the ELF - // header. - ELFSectionHeader section_names_header(SHT_STRTAB); - CFISection section_names(cfi.endianness(), cfi.AddressSize()); - section_names - .Mark(&null_header.name) - .AppendCString("") - .Mark(§ion_names_header.name) - .AppendCString(".shstrtab") - .Mark(&cfi_header.name) - .AppendCString(cfi_name) - .Mark(§ion_names_header.file_size); - - // Create the section table. The ELF header's e_shoff member refers - // to this, and the e_shnum member gives the number of entries it - // contains. - CFISection section_table(cfi.endianness(), cfi.AddressSize()); - AppendSectionHeader(§ion_table, null_header); - AppendSectionHeader(§ion_table, section_names_header); - AppendSectionHeader(§ion_table, cfi_header); - - // Append the section table and the section contents to the ELF file. - elf - .Mark(§ion_table_offset) - .Append(section_table) - .Mark(§ion_names_header.file_offset) - .Append(section_names) - .Mark(&cfi_header.file_offset) - .Append(cfi); - - string contents; - if (!elf.GetContents(&contents)) { - fprintf(stderr, "failed to get ELF file contents\n"); - exit(1); - } - - FILE *out = fopen(filename, "w"); - if (!out) { - fprintf(stderr, "error opening ELF file '%s': %s\n", - filename, strerror(errno)); - exit(1); - } - - if (fwrite(contents.data(), 1, contents.size(), out) != contents.size()) { - fprintf(stderr, "error writing ELF data to '%s': %s\n", - filename, strerror(errno)); - exit(1); - } - - if (fclose(out) == EOF) { - fprintf(stderr, "error closing ELF file '%s': %s\n", - filename, strerror(errno)); - exit(1); - } -} -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc deleted file mode 100644 index 71418eb8d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit - -#include -#include - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/dwarf2reader_test_common.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -using google_breakpad::test_assembler::Endianness; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; - -using dwarf2reader::ByteReader; -using dwarf2reader::CompilationUnit; -using dwarf2reader::Dwarf2Handler; -using dwarf2reader::DwarfAttribute; -using dwarf2reader::DwarfForm; -using dwarf2reader::DwarfHasChild; -using dwarf2reader::DwarfTag; -using dwarf2reader::ENDIANNESS_BIG; -using dwarf2reader::ENDIANNESS_LITTLE; -using dwarf2reader::SectionMap; - -using std::vector; -using testing::InSequence; -using testing::Pointee; -using testing::Return; -using testing::Sequence; -using testing::Test; -using testing::TestWithParam; -using testing::_; - -class MockDwarf2Handler: public Dwarf2Handler { - public: - MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version)); - MOCK_METHOD2(StartDIE, bool(uint64 offset, enum DwarfTag tag)); - MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset, - DwarfAttribute attr, - enum DwarfForm form, - uint64 data)); - MOCK_METHOD4(ProcessAttributeSigned, void(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data)); - MOCK_METHOD4(ProcessAttributeReference, void(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data)); - MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const uint8_t *data, - uint64 len)); - MOCK_METHOD4(ProcessAttributeString, void(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string& data)); - MOCK_METHOD4(ProcessAttributeSignature, void(uint64 offset, - DwarfAttribute attr, - enum DwarfForm form, - uint64 signature)); - MOCK_METHOD1(EndDIE, void(uint64 offset)); -}; - -struct DIEFixture { - - DIEFixture() { - // Fix the initial offset of the .debug_info and .debug_abbrev sections. - info.start() = 0; - abbrevs.start() = 0; - - // Default expectations for the data handler. - EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0); - EXPECT_CALL(handler, StartDIE(_, _)).Times(0); - EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0); - EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0); - EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0); - EXPECT_CALL(handler, ProcessAttributeBuffer(_, _, _, _, _)).Times(0); - EXPECT_CALL(handler, ProcessAttributeString(_, _, _, _)).Times(0); - EXPECT_CALL(handler, EndDIE(_)).Times(0); - } - - // Return a reference to a section map whose .debug_info section refers - // to |info|, and whose .debug_abbrev section refers to |abbrevs|. This - // function returns a reference to the same SectionMap each time; new - // calls wipe out maps established by earlier calls. - const SectionMap &MakeSectionMap() { - // Copy the sections' contents into strings that will live as long as - // the map itself. - assert(info.GetContents(&info_contents)); - assert(abbrevs.GetContents(&abbrevs_contents)); - section_map.clear(); - section_map[".debug_info"].first - = reinterpret_cast(info_contents.data()); - section_map[".debug_info"].second = info_contents.size(); - section_map[".debug_abbrev"].first - = reinterpret_cast(abbrevs_contents.data()); - section_map[".debug_abbrev"].second = abbrevs_contents.size(); - return section_map; - } - - TestCompilationUnit info; - TestAbbrevTable abbrevs; - MockDwarf2Handler handler; - string abbrevs_contents, info_contents; - SectionMap section_map; -}; - -struct DwarfHeaderParams { - DwarfHeaderParams(Endianness endianness, size_t format_size, - int version, size_t address_size) - : endianness(endianness), format_size(format_size), - version(version), address_size(address_size) { } - Endianness endianness; - size_t format_size; // 4-byte or 8-byte DWARF offsets - int version; - size_t address_size; -}; - -class DwarfHeader: public DIEFixture, - public TestWithParam { }; - -TEST_P(DwarfHeader, Header) { - Label abbrev_table = abbrevs.Here(); - abbrevs.Abbrev(1, dwarf2reader::DW_TAG_compile_unit, - dwarf2reader::DW_children_yes) - .Attribute(dwarf2reader::DW_AT_name, dwarf2reader::DW_FORM_string) - .EndAbbrev() - .EndTable(); - - info.set_format_size(GetParam().format_size); - info.set_endianness(GetParam().endianness); - - info.Header(GetParam().version, abbrev_table, GetParam().address_size) - .ULEB128(1) // DW_TAG_compile_unit, with children - .AppendCString("sam") // DW_AT_name, DW_FORM_string - .D8(0); // end of children - info.Finish(); - - { - InSequence s; - EXPECT_CALL(handler, - StartCompilationUnit(0, GetParam().address_size, - GetParam().format_size, _, - GetParam().version)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit)) - .WillOnce(Return(true)); - EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_string, - "sam")) - .WillOnce(Return()); - EXPECT_CALL(handler, EndDIE(_)) - .WillOnce(Return()); - } - - ByteReader byte_reader(GetParam().endianness == kLittleEndian ? - ENDIANNESS_LITTLE : ENDIANNESS_BIG); - CompilationUnit parser("", MakeSectionMap(), 0, &byte_reader, &handler); - EXPECT_EQ(parser.Start(), info_contents.size()); -} - -INSTANTIATE_TEST_CASE_P( - HeaderVariants, DwarfHeader, - ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4), - DwarfHeaderParams(kLittleEndian, 4, 2, 8), - DwarfHeaderParams(kLittleEndian, 4, 3, 4), - DwarfHeaderParams(kLittleEndian, 4, 3, 8), - DwarfHeaderParams(kLittleEndian, 4, 4, 4), - DwarfHeaderParams(kLittleEndian, 4, 4, 8), - DwarfHeaderParams(kLittleEndian, 8, 2, 4), - DwarfHeaderParams(kLittleEndian, 8, 2, 8), - DwarfHeaderParams(kLittleEndian, 8, 3, 4), - DwarfHeaderParams(kLittleEndian, 8, 3, 8), - DwarfHeaderParams(kLittleEndian, 8, 4, 4), - DwarfHeaderParams(kLittleEndian, 8, 4, 8), - DwarfHeaderParams(kBigEndian, 4, 2, 4), - DwarfHeaderParams(kBigEndian, 4, 2, 8), - DwarfHeaderParams(kBigEndian, 4, 3, 4), - DwarfHeaderParams(kBigEndian, 4, 3, 8), - DwarfHeaderParams(kBigEndian, 4, 4, 4), - DwarfHeaderParams(kBigEndian, 4, 4, 8), - DwarfHeaderParams(kBigEndian, 8, 2, 4), - DwarfHeaderParams(kBigEndian, 8, 2, 8), - DwarfHeaderParams(kBigEndian, 8, 3, 4), - DwarfHeaderParams(kBigEndian, 8, 3, 8), - DwarfHeaderParams(kBigEndian, 8, 4, 4), - DwarfHeaderParams(kBigEndian, 8, 4, 8))); - -struct DwarfFormsFixture: public DIEFixture { - // Start a compilation unit, as directed by |params|, containing one - // childless DIE of the given tag, with one attribute of the given name - // and form. The 'info' fixture member is left just after the abbrev - // code, waiting for the attribute value to be appended. - void StartSingleAttributeDIE(const DwarfHeaderParams ¶ms, - DwarfTag tag, DwarfAttribute name, - DwarfForm form) { - // Create the abbreviation table. - Label abbrev_table = abbrevs.Here(); - abbrevs.Abbrev(1, tag, dwarf2reader::DW_children_no) - .Attribute(name, form) - .EndAbbrev() - .EndTable(); - - // Create the compilation unit, up to the attribute value. - info.set_format_size(params.format_size); - info.set_endianness(params.endianness); - info.Header(params.version, abbrev_table, params.address_size) - .ULEB128(1); // abbrev code - } - - // Set up handler to expect a compilation unit matching |params|, - // containing one childless DIE of the given tag, in the sequence s. Stop - // just before the expectations. - void ExpectBeginCompilationUnit(const DwarfHeaderParams ¶ms, - DwarfTag tag, uint64 offset=0) { - EXPECT_CALL(handler, - StartCompilationUnit(offset, params.address_size, - params.format_size, _, - params.version)) - .InSequence(s) - .WillOnce(Return(true)); - EXPECT_CALL(handler, StartDIE(_, tag)) - .InSequence(s) - .WillOnce(Return(true)); - } - - void ExpectEndCompilationUnit() { - EXPECT_CALL(handler, EndDIE(_)) - .InSequence(s) - .WillOnce(Return()); - } - - void ParseCompilationUnit(const DwarfHeaderParams ¶ms, uint64 offset=0) { - ByteReader byte_reader(params.endianness == kLittleEndian ? - ENDIANNESS_LITTLE : ENDIANNESS_BIG); - CompilationUnit parser("", MakeSectionMap(), offset, &byte_reader, &handler); - EXPECT_EQ(offset + parser.Start(), info_contents.size()); - } - - // The sequence to which the fixture's methods append expectations. - Sequence s; -}; - -struct DwarfForms: public DwarfFormsFixture, - public TestWithParam { }; - -TEST_P(DwarfForms, addr) { - StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit, - dwarf2reader::DW_AT_low_pc, - dwarf2reader::DW_FORM_addr); - uint64_t value; - if (GetParam().address_size == 4) { - value = 0xc8e9ffcc; - info.D32(value); - } else { - value = 0xe942517fc2768564ULL; - info.D64(value); - } - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), dwarf2reader::DW_TAG_compile_unit); - EXPECT_CALL(handler, ProcessAttributeUnsigned(_, dwarf2reader::DW_AT_low_pc, - dwarf2reader::DW_FORM_addr, - value)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, block2_empty) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7, - (DwarfAttribute) 0xe52c4463, - dwarf2reader::DW_FORM_block2); - info.D16(0); - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7); - EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463, - dwarf2reader::DW_FORM_block2, - _, 0)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, block2) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7, - (DwarfAttribute) 0xe52c4463, - dwarf2reader::DW_FORM_block2); - unsigned char data[258]; - memset(data, '*', sizeof(data)); - info.D16(sizeof(data)) - .Append(data, sizeof(data)); - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7); - EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463, - dwarf2reader::DW_FORM_block2, - Pointee('*'), 258)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, flag_present) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x3e449ac2, - (DwarfAttribute) 0x359d1972, - dwarf2reader::DW_FORM_flag_present); - // DW_FORM_flag_present occupies no space in the DIE. - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x3e449ac2); - EXPECT_CALL(handler, - ProcessAttributeUnsigned(_, (DwarfAttribute) 0x359d1972, - dwarf2reader::DW_FORM_flag_present, - 1)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, sec_offset) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689, - (DwarfAttribute) 0xa060bfd1, - dwarf2reader::DW_FORM_sec_offset); - uint64_t value; - if (GetParam().format_size == 4) { - value = 0xacc9c388; - info.D32(value); - } else { - value = 0xcffe5696ffe3ed0aULL; - info.D64(value); - } - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x1d971689); - EXPECT_CALL(handler, ProcessAttributeUnsigned(_, (DwarfAttribute) 0xa060bfd1, - dwarf2reader::DW_FORM_sec_offset, - value)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, exprloc) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0xb6d167bb, - (DwarfAttribute) 0xba3ae5cb, - dwarf2reader::DW_FORM_exprloc); - info.ULEB128(29) - .Append(29, 173); - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0xb6d167bb); - EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xba3ae5cb, - dwarf2reader::DW_FORM_exprloc, - Pointee(173), 29)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -TEST_P(DwarfForms, ref_sig8) { - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, - (DwarfAttribute) 0xd708d908, - dwarf2reader::DW_FORM_ref_sig8); - info.D64(0xf72fa0cb6ddcf9d6ULL); - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b); - EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, - dwarf2reader::DW_FORM_ref_sig8, - 0xf72fa0cb6ddcf9d6ULL)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam()); -} - -// A value passed to ProcessAttributeSignature is just an absolute number, -// not an offset within the compilation unit as most of the other -// DW_FORM_ref forms are. Check that the reader doesn't try to apply any -// offset to the signature, by reading it from a compilation unit that does -// not start at the beginning of the section. -TEST_P(DwarfForms, ref_sig8_not_first) { - info.Append(98, '*'); - StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, - (DwarfAttribute) 0xd708d908, - dwarf2reader::DW_FORM_ref_sig8); - info.D64(0xf72fa0cb6ddcf9d6ULL); - info.Finish(); - - ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b, 98); - EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, - dwarf2reader::DW_FORM_ref_sig8, - 0xf72fa0cb6ddcf9d6ULL)) - .InSequence(s) - .WillOnce(Return()); - ExpectEndCompilationUnit(); - - ParseCompilationUnit(GetParam(), 98); -} - -// Tests for the other attribute forms could go here. - -INSTANTIATE_TEST_CASE_P( - HeaderVariants, DwarfForms, - ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4), - DwarfHeaderParams(kLittleEndian, 4, 2, 8), - DwarfHeaderParams(kLittleEndian, 4, 3, 4), - DwarfHeaderParams(kLittleEndian, 4, 3, 8), - DwarfHeaderParams(kLittleEndian, 4, 4, 4), - DwarfHeaderParams(kLittleEndian, 4, 4, 8), - DwarfHeaderParams(kLittleEndian, 8, 2, 4), - DwarfHeaderParams(kLittleEndian, 8, 2, 8), - DwarfHeaderParams(kLittleEndian, 8, 3, 4), - DwarfHeaderParams(kLittleEndian, 8, 3, 8), - DwarfHeaderParams(kLittleEndian, 8, 4, 4), - DwarfHeaderParams(kLittleEndian, 8, 4, 8), - DwarfHeaderParams(kBigEndian, 4, 2, 4), - DwarfHeaderParams(kBigEndian, 4, 2, 8), - DwarfHeaderParams(kBigEndian, 4, 3, 4), - DwarfHeaderParams(kBigEndian, 4, 3, 8), - DwarfHeaderParams(kBigEndian, 4, 4, 4), - DwarfHeaderParams(kBigEndian, 4, 4, 8), - DwarfHeaderParams(kBigEndian, 8, 2, 4), - DwarfHeaderParams(kBigEndian, 8, 2, 8), - DwarfHeaderParams(kBigEndian, 8, 3, 4), - DwarfHeaderParams(kBigEndian, 8, 3, 8), - DwarfHeaderParams(kBigEndian, 8, 4, 4), - DwarfHeaderParams(kBigEndian, 8, 4, 8))); diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_test_common.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_test_common.h deleted file mode 100644 index e91de9061..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_test_common.h +++ /dev/null @@ -1,149 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf2reader_test_common.h: Define TestCompilationUnit and -// TestAbbrevTable, classes for creating properly (and improperly) -// formatted DWARF compilation unit data for unit tests. - -#ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ -#define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ - -#include "common/test_assembler.h" -#include "common/dwarf/dwarf2enums.h" - -// A subclass of test_assembler::Section, specialized for constructing -// DWARF compilation units. -class TestCompilationUnit: public google_breakpad::test_assembler::Section { - public: - typedef dwarf2reader::DwarfTag DwarfTag; - typedef dwarf2reader::DwarfAttribute DwarfAttribute; - typedef dwarf2reader::DwarfForm DwarfForm; - typedef google_breakpad::test_assembler::Label Label; - - // Set the section's DWARF format size (the 32-bit DWARF format or the - // 64-bit DWARF format, for lengths and section offsets --- not the - // address size) to format_size. - void set_format_size(size_t format_size) { - assert(format_size == 4 || format_size == 8); - format_size_ = format_size; - } - - // Append a DWARF section offset value, of the appropriate size for this - // compilation unit. - template - void SectionOffset(T offset) { - if (format_size_ == 4) - D32(offset); - else - D64(offset); - } - - // Append a DWARF compilation unit header to the section, with the given - // DWARF version, abbrev table offset, and address size. - TestCompilationUnit &Header(int version, const Label &abbrev_offset, - size_t address_size) { - if (format_size_ == 4) { - D32(length_); - } else { - D32(0xffffffff); - D64(length_); - } - post_length_offset_ = Size(); - D16(version); - SectionOffset(abbrev_offset); - D8(address_size); - return *this; - } - - // Mark the end of this header's DIEs. - TestCompilationUnit &Finish() { - length_ = Size() - post_length_offset_; - return *this; - } - - private: - // The DWARF format size for this compilation unit. - size_t format_size_; - - // The offset of the point in the compilation unit header immediately - // after the initial length field. - uint64_t post_length_offset_; - - // The length of the compilation unit, not including the initial length field. - Label length_; -}; - -// A subclass of test_assembler::Section specialized for constructing DWARF -// abbreviation tables. -class TestAbbrevTable: public google_breakpad::test_assembler::Section { - public: - typedef dwarf2reader::DwarfTag DwarfTag; - typedef dwarf2reader::DwarfAttribute DwarfAttribute; - typedef dwarf2reader::DwarfForm DwarfForm; - typedef dwarf2reader::DwarfHasChild DwarfHasChild; - typedef google_breakpad::test_assembler::Label Label; - - // Start a new abbreviation table entry for abbreviation code |code|, - // encoding a DIE whose tag is |tag|, and which has children if and only - // if |has_children| is true. - TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) { - assert(code != 0); - ULEB128(code); - ULEB128(static_cast(tag)); - D8(static_cast(has_children)); - return *this; - }; - - // Add an attribute to the current abbreviation code whose name is |name| - // and whose form is |form|. - TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) { - ULEB128(static_cast(name)); - ULEB128(static_cast(form)); - return *this; - } - - // Finish the current abbreviation code. - TestAbbrevTable &EndAbbrev() { - ULEB128(0); - ULEB128(0); - return *this; - } - - // Finish the current abbreviation table. - TestAbbrevTable &EndTable() { - ULEB128(0); - return *this; - } -}; - -#endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.cc deleted file mode 100644 index 4135a51a9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.cc +++ /dev/null @@ -1,1273 +0,0 @@ -// Copyright 2005 Google Inc. All Rights Reserved. -// Author: chatham@google.com (Andrew Chatham) -// Author: satorux@google.com (Satoru Takabayashi) -// -// Code for reading in ELF files. -// -// For information on the ELF format, see -// http://www.x86.org/ftp/manuals/tools/elf.pdf -// -// I also liked: -// http://www.caldera.com/developers/gabi/1998-04-29/contents.html -// -// A note about types: When dealing with the file format, we use types -// like Elf32_Word, but in the public interfaces we treat all -// addresses as uint64. As a result, we should be able to symbolize -// 64-bit binaries from a 32-bit process (which we don't do, -// anyway). size_t should therefore be avoided, except where required -// by things like mmap(). -// -// Although most of this code can deal with arbitrary ELF files of -// either word size, the public ElfReader interface only examines -// files loaded into the current address space, which must all match -// __WORDSIZE. This code cannot handle ELF files with a non-native -// byte ordering. -// -// TODO(chatham): It would be nice if we could accomplish this task -// without using malloc(), so we could use it as the process is dying. - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE // needed for pread() -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -// TODO(saugustine): Add support for compressed debug. -// Also need to add configure tests for zlib. -//#include "zlib.h" - -#include "third_party/musl/include/elf.h" -#include "elf_reader.h" -#include "common/using_std_string.h" - -// EM_AARCH64 is not defined by elf.h of GRTE v3 on x86. -// TODO(dougkwan): Remove this when v17 is retired. -#if !defined(EM_AARCH64) -#define EM_AARCH64 183 /* ARM AARCH64 */ -#endif - -// Map Linux macros to their Apple equivalents. -#if __APPLE__ -#ifndef __LITTLE_ENDIAN -#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ -#endif // __LITTLE_ENDIAN -#ifndef __BIG_ENDIAN -#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__ -#endif // __BIG_ENDIAN -#ifndef __BYTE_ORDER -#define __BYTE_ORDER __BYTE_ORDER__ -#endif // __BYTE_ORDER -#endif // __APPLE__ - -// TODO(dthomson): Can be removed once all Java code is using the Google3 -// launcher. We need to avoid processing PLT functions as it causes memory -// fragmentation in malloc, which is fixed in tcmalloc - and if the Google3 -// launcher is used the JVM will then use tcmalloc. b/13735638 -//DEFINE_bool(elfreader_process_dynsyms, true, -// "Activate PLT function processing"); - -using std::vector; - -namespace { - -// The lowest bit of an ARM symbol value is used to indicate a Thumb address. -const int kARMThumbBitOffset = 0; - -// Converts an ARM Thumb symbol value to a true aligned address value. -template -T AdjustARMThumbSymbolValue(const T& symbol_table_value) { - return symbol_table_value & ~(1 << kARMThumbBitOffset); -} - -// Names of PLT-related sections. -const char kElfPLTRelSectionName[] = ".rel.plt"; // Use Rel struct. -const char kElfPLTRelaSectionName[] = ".rela.plt"; // Use Rela struct. -const char kElfPLTSectionName[] = ".plt"; -const char kElfDynSymSectionName[] = ".dynsym"; - -const int kX86PLTCodeSize = 0x10; // Size of one x86 PLT function in bytes. -const int kARMPLTCodeSize = 0xc; -const int kAARCH64PLTCodeSize = 0x10; - -const int kX86PLT0Size = 0x10; // Size of the special PLT0 entry. -const int kARMPLT0Size = 0x14; -const int kAARCH64PLT0Size = 0x20; - -// Suffix for PLT functions when it needs to be explicitly identified as such. -const char kPLTFunctionSuffix[] = "@plt"; - -} // namespace - -namespace dwarf2reader { - -template class ElfReaderImpl; - -// 32-bit and 64-bit ELF files are processed exactly the same, except -// for various field sizes. Elf32 and Elf64 encompass all of the -// differences between the two formats, and all format-specific code -// in this file is templated on one of them. -class Elf32 { - public: - typedef Elf32_Ehdr Ehdr; - typedef Elf32_Shdr Shdr; - typedef Elf32_Phdr Phdr; - typedef Elf32_Word Word; - typedef Elf32_Sym Sym; - typedef Elf32_Rel Rel; - typedef Elf32_Rela Rela; - - // What should be in the EI_CLASS header. - static const int kElfClass = ELFCLASS32; - - // Given a symbol pointer, return the binding type (eg STB_WEAK). - static char Bind(const Elf32_Sym *sym) { - return ELF32_ST_BIND(sym->st_info); - } - // Given a symbol pointer, return the symbol type (eg STT_FUNC). - static char Type(const Elf32_Sym *sym) { - return ELF32_ST_TYPE(sym->st_info); - } - - // Extract the symbol index from the r_info field of a relocation. - static int r_sym(const Elf32_Word r_info) { - return ELF32_R_SYM(r_info); - } -}; - - -class Elf64 { - public: - typedef Elf64_Ehdr Ehdr; - typedef Elf64_Shdr Shdr; - typedef Elf64_Phdr Phdr; - typedef Elf64_Word Word; - typedef Elf64_Sym Sym; - typedef Elf64_Rel Rel; - typedef Elf64_Rela Rela; - - // What should be in the EI_CLASS header. - static const int kElfClass = ELFCLASS64; - - static char Bind(const Elf64_Sym *sym) { - return ELF64_ST_BIND(sym->st_info); - } - static char Type(const Elf64_Sym *sym) { - return ELF64_ST_TYPE(sym->st_info); - } - static int r_sym(const Elf64_Xword r_info) { - return ELF64_R_SYM(r_info); - } -}; - - -// ElfSectionReader mmaps a section of an ELF file ("section" is ELF -// terminology). The ElfReaderImpl object providing the section header -// must exist for the lifetime of this object. -// -// The motivation for mmaping individual sections of the file is that -// many Google executables are large enough when unstripped that we -// have to worry about running out of virtual address space. -// -// For compressed sections we have no choice but to allocate memory. -template -class ElfSectionReader { - public: - ElfSectionReader(const char *name, const string &path, int fd, - const typename ElfArch::Shdr §ion_header) - : contents_aligned_(NULL), - contents_(NULL), - header_(section_header) { - // Back up to the beginning of the page we're interested in. - const size_t additional = header_.sh_offset % getpagesize(); - const size_t offset_aligned = header_.sh_offset - additional; - section_size_ = header_.sh_size; - size_aligned_ = section_size_ + additional; - // If the section has been stripped or is empty, do not attempt - // to process its contents. - if (header_.sh_type == SHT_NOBITS || header_.sh_size == 0) - return; - contents_aligned_ = mmap(NULL, size_aligned_, PROT_READ, MAP_SHARED, - fd, offset_aligned); - // Set where the offset really should begin. - contents_ = reinterpret_cast(contents_aligned_) + - (header_.sh_offset - offset_aligned); - - // Check for and handle any compressed contents. - //if (strncmp(name, ".zdebug_", strlen(".zdebug_")) == 0) - // DecompressZlibContents(); - // TODO(saugustine): Add support for proposed elf-section flag - // "SHF_COMPRESS". - } - - ~ElfSectionReader() { - if (contents_aligned_ != NULL) - munmap(contents_aligned_, size_aligned_); - else - delete[] contents_; - } - - // Return the section header for this section. - typename ElfArch::Shdr const &header() const { return header_; } - - // Return memory at the given offset within this section. - const char *GetOffset(typename ElfArch::Word bytes) const { - return contents_ + bytes; - } - - const char *contents() const { return contents_; } - size_t section_size() const { return section_size_; } - - private: - // page-aligned file contents - void *contents_aligned_; - // contents as usable by the client. For non-compressed sections, - // pointer within contents_aligned_ to where the section data - // begins; for compressed sections, pointer to the decompressed - // data. - char *contents_; - // size of contents_aligned_ - size_t size_aligned_; - // size of contents. - size_t section_size_; - const typename ElfArch::Shdr header_; -}; - -// An iterator over symbols in a given section. It handles walking -// through the entries in the specified section and mapping symbol -// entries to their names in the appropriate string table (in -// another section). -template -class SymbolIterator { - public: - SymbolIterator(ElfReaderImpl *reader, - typename ElfArch::Word section_type) - : symbol_section_(reader->GetSectionByType(section_type)), - string_section_(NULL), - num_symbols_in_section_(0), - symbol_within_section_(0) { - - // If this section type doesn't exist, leave - // num_symbols_in_section_ as zero, so this iterator is already - // done(). - if (symbol_section_ != NULL) { - num_symbols_in_section_ = symbol_section_->header().sh_size / - symbol_section_->header().sh_entsize; - - // Symbol sections have sh_link set to the section number of - // the string section containing the symbol names. - string_section_ = reader->GetSection(symbol_section_->header().sh_link); - } - } - - // Return true iff we have passed all symbols in this section. - bool done() const { - return symbol_within_section_ >= num_symbols_in_section_; - } - - // Advance to the next symbol in this section. - // REQUIRES: !done() - void Next() { ++symbol_within_section_; } - - // Return a pointer to the current symbol. - // REQUIRES: !done() - const typename ElfArch::Sym *GetSymbol() const { - return reinterpret_cast( - symbol_section_->GetOffset(symbol_within_section_ * - symbol_section_->header().sh_entsize)); - } - - // Return the name of the current symbol, NULL if it has none. - // REQUIRES: !done() - const char *GetSymbolName() const { - int name_offset = GetSymbol()->st_name; - if (name_offset == 0) - return NULL; - return string_section_->GetOffset(name_offset); - } - - int GetCurrentSymbolIndex() const { - return symbol_within_section_; - } - - private: - const ElfSectionReader *const symbol_section_; - const ElfSectionReader *string_section_; - int num_symbols_in_section_; - int symbol_within_section_; -}; - - -// Copied from strings/strutil.h. Per chatham, -// this library should not depend on strings. - -static inline bool MyHasSuffixString(const string& str, const string& suffix) { - int len = str.length(); - int suflen = suffix.length(); - return (suflen <= len) && (str.compare(len-suflen, suflen, suffix) == 0); -} - - -// ElfReader loads an ELF binary and can provide information about its -// contents. It is most useful for matching addresses to function -// names. It does not understand debugging formats (eg dwarf2), so it -// can't print line numbers. It takes a path to an elf file and a -// readable file descriptor for that file, which it does not assume -// ownership of. -template -class ElfReaderImpl { - public: - explicit ElfReaderImpl(const string &path, int fd) - : path_(path), - fd_(fd), - section_headers_(NULL), - program_headers_(NULL), - opd_section_(NULL), - base_for_text_(0), - plts_supported_(false), - plt_code_size_(0), - plt0_size_(0), - visited_relocation_entries_(false) { - string error; - is_dwp_ = MyHasSuffixString(path, ".dwp"); - ParseHeaders(fd, path); - // Currently we need some extra information for PowerPC64 binaries - // including a way to read the .opd section for function descriptors and a - // way to find the linked base for function symbols. - if (header_.e_machine == EM_PPC64) { - // "opd_section_" must always be checked for NULL before use. - opd_section_ = GetSectionInfoByName(".opd", &opd_info_); - for (unsigned int k = 0u; k < GetNumSections(); ++k) { - const char *name = GetSectionName(section_headers_[k].sh_name); - if (strncmp(name, ".text", strlen(".text")) == 0) { - base_for_text_ = - section_headers_[k].sh_addr - section_headers_[k].sh_offset; - break; - } - } - } - // Turn on PLTs. - if (header_.e_machine == EM_386 || header_.e_machine == EM_X86_64) { - plt_code_size_ = kX86PLTCodeSize; - plt0_size_ = kX86PLT0Size; - plts_supported_ = true; - } else if (header_.e_machine == EM_ARM) { - plt_code_size_ = kARMPLTCodeSize; - plt0_size_ = kARMPLT0Size; - plts_supported_ = true; - } else if (header_.e_machine == EM_AARCH64) { - plt_code_size_ = kAARCH64PLTCodeSize; - plt0_size_ = kAARCH64PLT0Size; - plts_supported_ = true; - } - } - - ~ElfReaderImpl() { - for (unsigned int i = 0u; i < sections_.size(); ++i) - delete sections_[i]; - delete [] section_headers_; - delete [] program_headers_; - } - - // Examine the headers of the file and return whether the file looks - // like an ELF file for this architecture. Takes an already-open - // file descriptor for the candidate file, reading in the prologue - // to see if the ELF file appears to match the current - // architecture. If error is non-NULL, it will be set with a reason - // in case of failure. - static bool IsArchElfFile(int fd, string *error) { - unsigned char header[EI_NIDENT]; - if (pread(fd, header, sizeof(header), 0) != sizeof(header)) { - if (error != NULL) *error = "Could not read header"; - return false; - } - - if (memcmp(header, ELFMAG, SELFMAG) != 0) { - if (error != NULL) *error = "Missing ELF magic"; - return false; - } - - if (header[EI_CLASS] != ElfArch::kElfClass) { - if (error != NULL) *error = "Different word size"; - return false; - } - - int endian = 0; - if (header[EI_DATA] == ELFDATA2LSB) - endian = __LITTLE_ENDIAN; - else if (header[EI_DATA] == ELFDATA2MSB) - endian = __BIG_ENDIAN; - if (endian != __BYTE_ORDER) { - if (error != NULL) *error = "Different byte order"; - return false; - } - - return true; - } - - // Return true if we can use this symbol in Address-to-Symbol map. - bool CanUseSymbol(const char *name, const typename ElfArch::Sym *sym) { - // For now we only save FUNC and NOTYPE symbols. For now we just - // care about functions, but some functions written in assembler - // don't have a proper ELF type attached to them, so we store - // NOTYPE symbols as well. The remaining significant type is - // OBJECT (eg global variables), which represent about 25% of - // the symbols in a typical google3 binary. - if (ElfArch::Type(sym) != STT_FUNC && - ElfArch::Type(sym) != STT_NOTYPE) { - return false; - } - - // Target specific filtering. - switch (header_.e_machine) { - case EM_AARCH64: - case EM_ARM: - // Filter out '$x' special local symbols used by tools - return name[0] != '$' || ElfArch::Bind(sym) != STB_LOCAL; - case EM_X86_64: - // Filter out read-only constants like .LC123. - return name[0] != '.' || ElfArch::Bind(sym) != STB_LOCAL; - default: - return true; - } - } - - // Iterate over the symbols in a section, either SHT_DYNSYM or - // SHT_SYMTAB. Add all symbols to the given SymbolMap. - /* - void GetSymbolPositions(SymbolMap *symbols, - typename ElfArch::Word section_type, - uint64 mem_offset, - uint64 file_offset) { - // This map is used to filter out "nested" functions. - // See comment below. - AddrToSymMap addr_to_sym_map; - for (SymbolIterator it(this, section_type); - !it.done(); it.Next()) { - const char *name = it.GetSymbolName(); - if (name == NULL) - continue; - const typename ElfArch::Sym *sym = it.GetSymbol(); - if (CanUseSymbol(name, sym)) { - const int sec = sym->st_shndx; - - // We don't support special section indices. The most common - // is SHN_ABS, for absolute symbols used deep in the bowels of - // glibc. Also ignore any undefined symbols. - if (sec == SHN_UNDEF || - (sec >= SHN_LORESERVE && sec <= SHN_HIRESERVE)) { - continue; - } - - const typename ElfArch::Shdr& hdr = section_headers_[sec]; - - // Adjust for difference between where we expected to mmap - // this section, and where it was actually mmapped. - const int64 expected_base = hdr.sh_addr - hdr.sh_offset; - const int64 real_base = mem_offset - file_offset; - const int64 adjust = real_base - expected_base; - - uint64 start = sym->st_value + adjust; - - // Adjust function symbols for PowerPC64 by dereferencing and adjusting - // the function descriptor to get the function address. - if (header_.e_machine == EM_PPC64 && ElfArch::Type(sym) == STT_FUNC) { - const uint64 opd_addr = - AdjustPPC64FunctionDescriptorSymbolValue(sym->st_value); - // Only adjust the returned value if the function address was found. - if (opd_addr != sym->st_value) { - const int64 adjust_function_symbols = - real_base - base_for_text_; - start = opd_addr + adjust_function_symbols; - } - } - - addr_to_sym_map.push_back(std::make_pair(start, sym)); - } - } - std::sort(addr_to_sym_map.begin(), addr_to_sym_map.end(), &AddrToSymSorter); - addr_to_sym_map.erase(std::unique(addr_to_sym_map.begin(), - addr_to_sym_map.end(), &AddrToSymEquals), - addr_to_sym_map.end()); - - // Squeeze out any "nested functions". - // Nested functions are not allowed in C, but libc plays tricks. - // - // For example, here is disassembly of /lib64/tls/libc-2.3.5.so: - // 0x00000000000aa380 : cmpl $0x0,0x2781b9(%rip) - // 0x00000000000aa387 : jne 0xaa39b - // 0x00000000000aa389 <__read_nocancel+0>: mov $0x0,%rax - // 0x00000000000aa390 <__read_nocancel+7>: syscall - // 0x00000000000aa392 <__read_nocancel+9>: cmp $0xfffffffffffff001,%rax - // 0x00000000000aa398 <__read_nocancel+15>: jae 0xaa3ef - // 0x00000000000aa39a <__read_nocancel+17>: retq - // 0x00000000000aa39b : sub $0x28,%rsp - // 0x00000000000aa39f : mov %rdi,0x8(%rsp) - // ... - // Without removing __read_nocancel, symbolizer will return NULL - // given e.g. 0xaa39f (because the lower bound is __read_nocancel, - // but 0xaa39f is beyond its end. - if (addr_to_sym_map.empty()) { - return; - } - const ElfSectionReader *const symbol_section = - this->GetSectionByType(section_type); - const ElfSectionReader *const string_section = - this->GetSection(symbol_section->header().sh_link); - - typename AddrToSymMap::iterator curr = addr_to_sym_map.begin(); - // Always insert the first symbol. - symbols->AddSymbol(string_section->GetOffset(curr->second->st_name), - curr->first, curr->second->st_size); - typename AddrToSymMap::iterator prev = curr++; - for (; curr != addr_to_sym_map.end(); ++curr) { - const uint64 prev_addr = prev->first; - const uint64 curr_addr = curr->first; - const typename ElfArch::Sym *const prev_sym = prev->second; - const typename ElfArch::Sym *const curr_sym = curr->second; - if (prev_addr + prev_sym->st_size <= curr_addr || - // The next condition is true if two symbols overlap like this: - // - // Previous symbol |----------------------------| - // Current symbol |-------------------------------| - // - // These symbols are not found in google3 codebase, but in - // jdk1.6.0_01_gg1/jre/lib/i386/server/libjvm.so. - // - // 0619e040 00000046 t CardTableModRefBS::write_region_work() - // 0619e070 00000046 t CardTableModRefBS::write_ref_array_work() - // - // We allow overlapped symbols rather than ignore these. - // Due to the way SymbolMap::GetSymbolAtPosition() works, - // lookup for any address in [curr_addr, curr_addr + its size) - // (e.g. 0619e071) will produce the current symbol, - // which is the desired outcome. - prev_addr + prev_sym->st_size < curr_addr + curr_sym->st_size) { - const char *name = string_section->GetOffset(curr_sym->st_name); - symbols->AddSymbol(name, curr_addr, curr_sym->st_size); - prev = curr; - } else { - // Current symbol is "nested" inside previous one like this: - // - // Previous symbol |----------------------------| - // Current symbol |---------------------| - // - // This happens within glibc, e.g. __read_nocancel is nested - // "inside" __read. Ignore "inner" symbol. - //DCHECK_LE(curr_addr + curr_sym->st_size, - // prev_addr + prev_sym->st_size); - ; - } - } - } -*/ - - void VisitSymbols(typename ElfArch::Word section_type, - ElfReader::SymbolSink *sink) { - VisitSymbols(section_type, sink, -1, -1, false); - } - - void VisitSymbols(typename ElfArch::Word section_type, - ElfReader::SymbolSink *sink, - int symbol_binding, - int symbol_type, - bool get_raw_symbol_values) { - for (SymbolIterator it(this, section_type); - !it.done(); it.Next()) { - const char *name = it.GetSymbolName(); - if (!name) continue; - const typename ElfArch::Sym *sym = it.GetSymbol(); - if ((symbol_binding < 0 || ElfArch::Bind(sym) == symbol_binding) && - (symbol_type < 0 || ElfArch::Type(sym) == symbol_type)) { - typename ElfArch::Sym symbol = *sym; - // Add a PLT symbol in addition to the main undefined symbol. - // Only do this for SHT_DYNSYM, because PLT symbols are dynamic. - int symbol_index = it.GetCurrentSymbolIndex(); - // TODO(dthomson): Can be removed once all Java code is using the - // Google3 launcher. - if (section_type == SHT_DYNSYM && - static_cast(symbol_index) < symbols_plt_offsets_.size() && - symbols_plt_offsets_[symbol_index] != 0) { - string plt_name = string(name) + kPLTFunctionSuffix; - if (plt_function_names_[symbol_index].empty()) { - plt_function_names_[symbol_index] = plt_name; - } else if (plt_function_names_[symbol_index] != plt_name) { - ; - } - sink->AddSymbol(plt_function_names_[symbol_index].c_str(), - symbols_plt_offsets_[it.GetCurrentSymbolIndex()], - plt_code_size_); - } - if (!get_raw_symbol_values) - AdjustSymbolValue(&symbol); - sink->AddSymbol(name, symbol.st_value, symbol.st_size); - } - } - } - - void VisitRelocationEntries() { - if (visited_relocation_entries_) { - return; - } - visited_relocation_entries_ = true; - - if (!plts_supported_) { - return; - } - // First determine if PLTs exist. If not, then there is nothing to do. - ElfReader::SectionInfo plt_section_info; - const char* plt_section = - GetSectionInfoByName(kElfPLTSectionName, &plt_section_info); - if (!plt_section) { - return; - } - if (plt_section_info.size == 0) { - return; - } - - // The PLTs could be referenced by either a Rel or Rela (Rel with Addend) - // section. - ElfReader::SectionInfo rel_section_info; - ElfReader::SectionInfo rela_section_info; - const char* rel_section = - GetSectionInfoByName(kElfPLTRelSectionName, &rel_section_info); - const char* rela_section = - GetSectionInfoByName(kElfPLTRelaSectionName, &rela_section_info); - - const typename ElfArch::Rel* rel = - reinterpret_cast(rel_section); - const typename ElfArch::Rela* rela = - reinterpret_cast(rela_section); - - if (!rel_section && !rela_section) { - return; - } - - // Use either Rel or Rela section, depending on which one exists. - size_t section_size = rel_section ? rel_section_info.size - : rela_section_info.size; - size_t entry_size = rel_section ? sizeof(typename ElfArch::Rel) - : sizeof(typename ElfArch::Rela); - - // Determine the number of entries in the dynamic symbol table. - ElfReader::SectionInfo dynsym_section_info; - const char* dynsym_section = - GetSectionInfoByName(kElfDynSymSectionName, &dynsym_section_info); - // The dynsym section might not exist, or it might be empty. In either case - // there is nothing to be done so return. - if (!dynsym_section || dynsym_section_info.size == 0) { - return; - } - size_t num_dynamic_symbols = - dynsym_section_info.size / dynsym_section_info.entsize; - symbols_plt_offsets_.resize(num_dynamic_symbols, 0); - - // TODO(dthomson): Can be removed once all Java code is using the - // Google3 launcher. - // Make storage room for PLT function name strings. - plt_function_names_.resize(num_dynamic_symbols); - - for (size_t i = 0; i < section_size / entry_size; ++i) { - // Determine symbol index from the |r_info| field. - int sym_index = ElfArch::r_sym(rel_section ? rel[i].r_info - : rela[i].r_info); - if (static_cast(sym_index) >= symbols_plt_offsets_.size()) { - continue; - } - symbols_plt_offsets_[sym_index] = - plt_section_info.addr + plt0_size_ + i * plt_code_size_; - } - } - - // Return an ElfSectionReader for the first section of the given - // type by iterating through all section headers. Returns NULL if - // the section type is not found. - const ElfSectionReader *GetSectionByType( - typename ElfArch::Word section_type) { - for (unsigned int k = 0u; k < GetNumSections(); ++k) { - if (section_headers_[k].sh_type == section_type) { - return GetSection(k); - } - } - return NULL; - } - - // Return the name of section "shndx". Returns NULL if the section - // is not found. - const char *GetSectionNameByIndex(int shndx) { - return GetSectionName(section_headers_[shndx].sh_name); - } - - // Return a pointer to section "shndx", and store the size in - // "size". Returns NULL if the section is not found. - const char *GetSectionContentsByIndex(int shndx, size_t *size) { - const ElfSectionReader *section = GetSection(shndx); - if (section != NULL) { - *size = section->section_size(); - return section->contents(); - } - return NULL; - } - - // Return a pointer to the first section of the given name by - // iterating through all section headers, and store the size in - // "size". Returns NULL if the section name is not found. - const char *GetSectionContentsByName(const string §ion_name, - size_t *size) { - for (unsigned int k = 0u; k < GetNumSections(); ++k) { - // When searching for sections in a .dwp file, the sections - // we're looking for will always be at the end of the section - // table, so reverse the direction of iteration. - int shndx = is_dwp_ ? GetNumSections() - k - 1 : k; - const char *name = GetSectionName(section_headers_[shndx].sh_name); - if (name != NULL && ElfReader::SectionNamesMatch(section_name, name)) { - const ElfSectionReader *section = GetSection(shndx); - if (section == NULL) { - return NULL; - } else { - *size = section->section_size(); - return section->contents(); - } - } - } - return NULL; - } - - // This is like GetSectionContentsByName() but it returns a lot of extra - // information about the section. - const char *GetSectionInfoByName(const string §ion_name, - ElfReader::SectionInfo *info) { - for (unsigned int k = 0u; k < GetNumSections(); ++k) { - // When searching for sections in a .dwp file, the sections - // we're looking for will always be at the end of the section - // table, so reverse the direction of iteration. - int shndx = is_dwp_ ? GetNumSections() - k - 1 : k; - const char *name = GetSectionName(section_headers_[shndx].sh_name); - if (name != NULL && ElfReader::SectionNamesMatch(section_name, name)) { - const ElfSectionReader *section = GetSection(shndx); - if (section == NULL) { - return NULL; - } else { - info->type = section->header().sh_type; - info->flags = section->header().sh_flags; - info->addr = section->header().sh_addr; - info->offset = section->header().sh_offset; - info->size = section->header().sh_size; - info->link = section->header().sh_link; - info->info = section->header().sh_info; - info->addralign = section->header().sh_addralign; - info->entsize = section->header().sh_entsize; - return section->contents(); - } - } - } - return NULL; - } - - // p_vaddr of the first PT_LOAD segment (if any), or 0 if no PT_LOAD - // segments are present. This is the address an ELF image was linked - // (by static linker) to be loaded at. Usually (but not always) 0 for - // shared libraries and position-independent executables. - uint64 VaddrOfFirstLoadSegment() const { - // Relocatable objects (of type ET_REL) do not have LOAD segments. - if (header_.e_type == ET_REL) { - return 0; - } - for (int i = 0; i < GetNumProgramHeaders(); ++i) { - if (program_headers_[i].p_type == PT_LOAD) { - return program_headers_[i].p_vaddr; - } - } - return 0; - } - - // According to the LSB ("ELF special sections"), sections with debug - // info are prefixed by ".debug". The names are not specified, but they - // look like ".debug_line", ".debug_info", etc. - bool HasDebugSections() { - // Debug sections are likely to be near the end, so reverse the - // direction of iteration. - for (int k = GetNumSections() - 1; k >= 0; --k) { - const char *name = GetSectionName(section_headers_[k].sh_name); - if (strncmp(name, ".debug", strlen(".debug")) == 0) return true; - if (strncmp(name, ".zdebug", strlen(".zdebug")) == 0) return true; - } - return false; - } - - bool IsDynamicSharedObject() const { - return header_.e_type == ET_DYN; - } - - // Return the number of sections. - uint64_t GetNumSections() const { - if (HasManySections()) - return first_section_header_.sh_size; - return header_.e_shnum; - } - - private: - typedef vector > AddrToSymMap; - - static bool AddrToSymSorter(const typename AddrToSymMap::value_type& lhs, - const typename AddrToSymMap::value_type& rhs) { - return lhs.first < rhs.first; - } - - static bool AddrToSymEquals(const typename AddrToSymMap::value_type& lhs, - const typename AddrToSymMap::value_type& rhs) { - return lhs.first == rhs.first; - } - - // Does this ELF file have too many sections to fit in the program header? - bool HasManySections() const { - return header_.e_shnum == SHN_UNDEF; - } - - // Return the number of program headers. - int GetNumProgramHeaders() const { - if (HasManySections() && header_.e_phnum == 0xffff && - first_section_header_.sh_info != 0) - return first_section_header_.sh_info; - return header_.e_phnum; - } - - // Return the index of the string table. - int GetStringTableIndex() const { - if (HasManySections()) { - if (header_.e_shstrndx == 0xffff) - return first_section_header_.sh_link; - else if (header_.e_shstrndx >= GetNumSections()) - return 0; - } - return header_.e_shstrndx; - } - - // Given an offset into the section header string table, return the - // section name. - const char *GetSectionName(typename ElfArch::Word sh_name) { - const ElfSectionReader *shstrtab = - GetSection(GetStringTableIndex()); - if (shstrtab != NULL) { - return shstrtab->GetOffset(sh_name); - } - return NULL; - } - - // Return an ElfSectionReader for the given section. The reader will - // be freed when this object is destroyed. - const ElfSectionReader *GetSection(int num) { - const char *name; - // Hard-coding the name for the section-name string table prevents - // infinite recursion. - if (num == GetStringTableIndex()) - name = ".shstrtab"; - else - name = GetSectionNameByIndex(num); - ElfSectionReader *& reader = sections_[num]; - if (reader == NULL) - reader = new ElfSectionReader(name, path_, fd_, - section_headers_[num]); - return reader; - } - - // Parse out the overall header information from the file and assert - // that it looks sane. This contains information like the magic - // number and target architecture. - bool ParseHeaders(int fd, const string &path) { - // Read in the global ELF header. - if (pread(fd, &header_, sizeof(header_), 0) != sizeof(header_)) { - return false; - } - - // Must be an executable, dynamic shared object or relocatable object - if (header_.e_type != ET_EXEC && - header_.e_type != ET_DYN && - header_.e_type != ET_REL) { - return false; - } - // Need a section header. - if (header_.e_shoff == 0) { - return false; - } - - if (header_.e_shnum == SHN_UNDEF) { - // The number of sections in the program header is only a 16-bit value. In - // the event of overflow (greater than SHN_LORESERVE sections), e_shnum - // will read SHN_UNDEF and the true number of section header table entries - // is found in the sh_size field of the first section header. - // See: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html - if (pread(fd, &first_section_header_, sizeof(first_section_header_), - header_.e_shoff) != sizeof(first_section_header_)) { - return false; - } - } - - // Dynamically allocate enough space to store the section headers - // and read them out of the file. - const int section_headers_size = - GetNumSections() * sizeof(*section_headers_); - section_headers_ = new typename ElfArch::Shdr[section_headers_size]; - if (pread(fd, section_headers_, section_headers_size, header_.e_shoff) != - section_headers_size) { - return false; - } - - // Dynamically allocate enough space to store the program headers - // and read them out of the file. - //const int program_headers_size = - // GetNumProgramHeaders() * sizeof(*program_headers_); - program_headers_ = new typename ElfArch::Phdr[GetNumProgramHeaders()]; - - // Presize the sections array for efficiency. - sections_.resize(GetNumSections(), NULL); - return true; - } - - // Given the "value" of a function descriptor return the address of the - // function (i.e. the dereferenced value). Otherwise return "value". - uint64 AdjustPPC64FunctionDescriptorSymbolValue(uint64 value) { - if (opd_section_ != NULL && - opd_info_.addr <= value && - value < opd_info_.addr + opd_info_.size) { - uint64 offset = value - opd_info_.addr; - return (*reinterpret_cast(opd_section_ + offset)); - } - return value; - } - - void AdjustSymbolValue(typename ElfArch::Sym* sym) { - switch (header_.e_machine) { - case EM_ARM: - // For ARM architecture, if the LSB of the function symbol offset is set, - // it indicates a Thumb function. This bit should not be taken literally. - // Clear it. - if (ElfArch::Type(sym) == STT_FUNC) - sym->st_value = AdjustARMThumbSymbolValue(sym->st_value); - break; - case EM_386: - // No adjustment needed for Intel x86 architecture. However, explicitly - // define this case as we use it quite often. - break; - case EM_PPC64: - // PowerPC64 currently has function descriptors as part of the ABI. - // Function symbols need to be adjusted accordingly. - if (ElfArch::Type(sym) == STT_FUNC) - sym->st_value = AdjustPPC64FunctionDescriptorSymbolValue(sym->st_value); - break; - default: - break; - } - } - - friend class SymbolIterator; - - // The file we're reading. - const string path_; - // Open file descriptor for path_. Not owned by this object. - const int fd_; - - // The global header of the ELF file. - typename ElfArch::Ehdr header_; - - // The header of the first section. This may be used to supplement the ELF - // file header. - typename ElfArch::Shdr first_section_header_; - - // Array of GetNumSections() section headers, allocated when we read - // in the global header. - typename ElfArch::Shdr *section_headers_; - - // Array of GetNumProgramHeaders() program headers, allocated when we read - // in the global header. - typename ElfArch::Phdr *program_headers_; - - // An array of pointers to ElfSectionReaders. Sections are - // mmaped as they're needed and not released until this object is - // destroyed. - vector*> sections_; - - // For PowerPC64 we need to keep track of function descriptors when looking up - // values for funtion symbols values. Function descriptors are kept in the - // .opd section and are dereferenced to find the function address. - ElfReader::SectionInfo opd_info_; - const char *opd_section_; // Must be checked for NULL before use. - int64 base_for_text_; - - // Read PLT-related sections for the current architecture. - bool plts_supported_; - // Code size of each PLT function for the current architecture. - size_t plt_code_size_; - // Size of the special first entry in the .plt section that calls the runtime - // loader resolution routine, and that all other entries jump to when doing - // lazy symbol binding. - size_t plt0_size_; - - // Maps a dynamic symbol index to a PLT offset. - // The vector entry index is the dynamic symbol index. - std::vector symbols_plt_offsets_; - - // Container for PLT function name strings. These strings are passed by - // reference to SymbolSink::AddSymbol() so they need to be stored somewhere. - std::vector plt_function_names_; - - bool visited_relocation_entries_; - - // True if this is a .dwp file. - bool is_dwp_; -}; - -ElfReader::ElfReader(const string &path) - : path_(path), fd_(-1), impl32_(NULL), impl64_(NULL) { - // linux 2.6.XX kernel can show deleted files like this: - // /var/run/nscd/dbYLJYaE (deleted) - // and the kernel-supplied vdso and vsyscall mappings like this: - // [vdso] - // [vsyscall] - if (MyHasSuffixString(path, " (deleted)")) - return; - if (path == "[vdso]") - return; - if (path == "[vsyscall]") - return; - - fd_ = open(path.c_str(), O_RDONLY); -} - -ElfReader::~ElfReader() { - if (fd_ != -1) - close(fd_); - if (impl32_ != NULL) - delete impl32_; - if (impl64_ != NULL) - delete impl64_; -} - - -// The only word-size specific part of this file is IsNativeElfFile(). -#if __WORDSIZE == 32 -#define NATIVE_ELF_ARCH Elf32 -#elif __WORDSIZE == 64 -#define NATIVE_ELF_ARCH Elf64 -#else -#error "Invalid word size" -#endif - -template -static bool IsElfFile(const int fd, const string &path) { - if (fd < 0) - return false; - if (!ElfReaderImpl::IsArchElfFile(fd, NULL)) { - // No error message here. IsElfFile gets called many times. - return false; - } - return true; -} - -bool ElfReader::IsNativeElfFile() const { - return IsElfFile(fd_, path_); -} - -bool ElfReader::IsElf32File() const { - return IsElfFile(fd_, path_); -} - -bool ElfReader::IsElf64File() const { - return IsElfFile(fd_, path_); -} - -/* -void ElfReader::AddSymbols(SymbolMap *symbols, - uint64 mem_offset, uint64 file_offset, - uint64 length) { - if (fd_ < 0) - return; - // TODO(chatham): Actually use the information about file offset and - // the length of the mapped section. On some machines the data - // section gets mapped as executable, and we'll end up reading the - // file twice and getting some of the offsets wrong. - if (IsElf32File()) { - GetImpl32()->GetSymbolPositions(symbols, SHT_SYMTAB, - mem_offset, file_offset); - GetImpl32()->GetSymbolPositions(symbols, SHT_DYNSYM, - mem_offset, file_offset); - } else if (IsElf64File()) { - GetImpl64()->GetSymbolPositions(symbols, SHT_SYMTAB, - mem_offset, file_offset); - GetImpl64()->GetSymbolPositions(symbols, SHT_DYNSYM, - mem_offset, file_offset); - } -} -*/ - -void ElfReader::VisitSymbols(ElfReader::SymbolSink *sink) { - VisitSymbols(sink, -1, -1); -} - -void ElfReader::VisitSymbols(ElfReader::SymbolSink *sink, - int symbol_binding, - int symbol_type) { - VisitSymbols(sink, symbol_binding, symbol_type, false); -} - -void ElfReader::VisitSymbols(ElfReader::SymbolSink *sink, - int symbol_binding, - int symbol_type, - bool get_raw_symbol_values) { - if (IsElf32File()) { - GetImpl32()->VisitRelocationEntries(); - GetImpl32()->VisitSymbols(SHT_SYMTAB, sink, symbol_binding, symbol_type, - get_raw_symbol_values); - GetImpl32()->VisitSymbols(SHT_DYNSYM, sink, symbol_binding, symbol_type, - get_raw_symbol_values); - } else if (IsElf64File()) { - GetImpl64()->VisitRelocationEntries(); - GetImpl64()->VisitSymbols(SHT_SYMTAB, sink, symbol_binding, symbol_type, - get_raw_symbol_values); - GetImpl64()->VisitSymbols(SHT_DYNSYM, sink, symbol_binding, symbol_type, - get_raw_symbol_values); - } -} - -uint64 ElfReader::VaddrOfFirstLoadSegment() { - if (IsElf32File()) { - return GetImpl32()->VaddrOfFirstLoadSegment(); - } else if (IsElf64File()) { - return GetImpl64()->VaddrOfFirstLoadSegment(); - } else { - return 0; - } -} - -const char *ElfReader::GetSectionName(int shndx) { - if (shndx < 0 || static_cast(shndx) >= GetNumSections()) return NULL; - if (IsElf32File()) { - return GetImpl32()->GetSectionNameByIndex(shndx); - } else if (IsElf64File()) { - return GetImpl64()->GetSectionNameByIndex(shndx); - } else { - return NULL; - } -} - -uint64 ElfReader::GetNumSections() { - if (IsElf32File()) { - return GetImpl32()->GetNumSections(); - } else if (IsElf64File()) { - return GetImpl64()->GetNumSections(); - } else { - return 0; - } -} - -const char *ElfReader::GetSectionByIndex(int shndx, size_t *size) { - if (IsElf32File()) { - return GetImpl32()->GetSectionContentsByIndex(shndx, size); - } else if (IsElf64File()) { - return GetImpl64()->GetSectionContentsByIndex(shndx, size); - } else { - return NULL; - } -} - -const char *ElfReader::GetSectionByName(const string §ion_name, - size_t *size) { - if (IsElf32File()) { - return GetImpl32()->GetSectionContentsByName(section_name, size); - } else if (IsElf64File()) { - return GetImpl64()->GetSectionContentsByName(section_name, size); - } else { - return NULL; - } -} - -const char *ElfReader::GetSectionInfoByName(const string §ion_name, - SectionInfo *info) { - if (IsElf32File()) { - return GetImpl32()->GetSectionInfoByName(section_name, info); - } else if (IsElf64File()) { - return GetImpl64()->GetSectionInfoByName(section_name, info); - } else { - return NULL; - } -} - -bool ElfReader::SectionNamesMatch(const string &name, const string &sh_name) { - if ((name.find(".debug_", 0) == 0) && (sh_name.find(".zdebug_", 0) == 0)) { - const string name_suffix(name, strlen(".debug_")); - const string sh_name_suffix(sh_name, strlen(".zdebug_")); - return name_suffix == sh_name_suffix; - } - return name == sh_name; -} - -bool ElfReader::IsDynamicSharedObject() { - if (IsElf32File()) { - return GetImpl32()->IsDynamicSharedObject(); - } else if (IsElf64File()) { - return GetImpl64()->IsDynamicSharedObject(); - } else { - return false; - } -} - -ElfReaderImpl *ElfReader::GetImpl32() { - if (impl32_ == NULL) { - impl32_ = new ElfReaderImpl(path_, fd_); - } - return impl32_; -} - -ElfReaderImpl *ElfReader::GetImpl64() { - if (impl64_ == NULL) { - impl64_ = new ElfReaderImpl(path_, fd_); - } - return impl64_; -} - -// Return true if file is an ELF binary of ElfArch, with unstripped -// debug info (debug_only=true) or symbol table (debug_only=false). -// Otherwise, return false. -template -static bool IsNonStrippedELFBinaryImpl(const string &path, const int fd, - bool debug_only) { - if (!ElfReaderImpl::IsArchElfFile(fd, NULL)) return false; - ElfReaderImpl elf_reader(path, fd); - return debug_only ? - elf_reader.HasDebugSections() - : (elf_reader.GetSectionByType(SHT_SYMTAB) != NULL); -} - -// Helper for the IsNon[Debug]StrippedELFBinary functions. -static bool IsNonStrippedELFBinaryHelper(const string &path, - bool debug_only) { - const int fd = open(path.c_str(), O_RDONLY); - if (fd == -1) { - return false; - } - - if (IsNonStrippedELFBinaryImpl(path, fd, debug_only) || - IsNonStrippedELFBinaryImpl(path, fd, debug_only)) { - close(fd); - return true; - } - close(fd); - return false; -} - -bool ElfReader::IsNonStrippedELFBinary(const string &path) { - return IsNonStrippedELFBinaryHelper(path, false); -} - -bool ElfReader::IsNonDebugStrippedELFBinary(const string &path) { - return IsNonStrippedELFBinaryHelper(path, true); -} -} // namespace dwarf2reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.h deleted file mode 100644 index 07477341f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/elf_reader.h +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2005 Google Inc. All Rights Reserved. -// Author: chatham@google.com (Andrew Chatham) -// Author: satorux@google.com (Satoru Takabayashi) -// -// ElfReader handles reading in ELF. It can extract symbols from the -// current process, which may be used to symbolize stack traces -// without having to make a potentially dangerous call to fork(). -// -// ElfReader dynamically allocates memory, so it is not appropriate to -// use once the address space might be corrupted, such as during -// process death. -// -// ElfReader supports both 32-bit and 64-bit ELF binaries. - -#ifndef COMMON_DWARF_ELF_READER_H__ -#define COMMON_DWARF_ELF_READER_H__ - -#include -#include - -#include "common/dwarf/types.h" - -using std::string; -using std::vector; -using std::pair; - -namespace dwarf2reader { - -class SymbolMap; -class Elf32; -class Elf64; -template -class ElfReaderImpl; - -class ElfReader { - public: - explicit ElfReader(const string &path); - ~ElfReader(); - - // Parse the ELF prologue of this file and return whether it was - // successfully parsed and matches the word size and byte order of - // the current process. - bool IsNativeElfFile() const; - - // Similar to IsNativeElfFile but checks if it's a 32-bit ELF file. - bool IsElf32File() const; - - // Similar to IsNativeElfFile but checks if it's a 64-bit ELF file. - bool IsElf64File() const; - - // Checks if it's an ELF file of type ET_DYN (shared object file). - bool IsDynamicSharedObject(); - - // Add symbols in the given ELF file into the provided SymbolMap, - // assuming that the file has been loaded into the specified - // offset. - // - // The remaining arguments are typically taken from a - // ProcMapsIterator (base/sysinfo.h) and describe which portions of - // the ELF file are mapped into which parts of memory: - // - // mem_offset - position at which the segment is mapped into memory - // file_offset - offset in the file where the mapping begins - // length - length of the mapped segment - void AddSymbols(SymbolMap *symbols, - uint64 mem_offset, uint64 file_offset, - uint64 length); - - class SymbolSink { - public: - virtual ~SymbolSink() {} - virtual void AddSymbol(const char *name, uint64 address, uint64 size) = 0; - }; - - // Like AddSymbols above, but with no address correction. - // Processes any SHT_SYMTAB section, followed by any SHT_DYNSYM section. - void VisitSymbols(SymbolSink *sink); - - // Like VisitSymbols above, but for a specific symbol binding/type. - // A negative value for the binding and type parameters means any - // binding or type. - void VisitSymbols(SymbolSink *sink, int symbol_binding, int symbol_type); - - // Like VisitSymbols above but can optionally export raw symbol values instead - // of adjusted ones. - void VisitSymbols(SymbolSink *sink, int symbol_binding, int symbol_type, - bool get_raw_symbol_values); - - // p_vaddr of the first PT_LOAD segment (if any), or 0 if no PT_LOAD - // segments are present. This is the address an ELF image was linked - // (by static linker) to be loaded at. Usually (but not always) 0 for - // shared libraries and position-independent executables. - uint64 VaddrOfFirstLoadSegment(); - - // Return the name of section "shndx". Returns NULL if the section - // is not found. - const char *GetSectionName(int shndx); - - // Return the number of sections in the given ELF file. - uint64 GetNumSections(); - - // Get section "shndx" from the given ELF file. On success, return - // the pointer to the section and store the size in "size". - // On error, return NULL. The returned section data is only valid - // until the ElfReader gets destroyed. - const char *GetSectionByIndex(int shndx, size_t *size); - - // Get section with "section_name" (ex. ".text", ".symtab") in the - // given ELF file. On success, return the pointer to the section - // and store the size in "size". On error, return NULL. The - // returned section data is only valid until the ElfReader gets - // destroyed. - const char *GetSectionByName(const string §ion_name, size_t *size); - - // This is like GetSectionByName() but it returns a lot of extra information - // about the section. The SectionInfo structure is almost identical to - // the typedef struct Elf64_Shdr defined in , but is redefined - // here so that the many short macro names in don't have to be - // added to our already cluttered namespace. - struct SectionInfo { - uint32 type; // Section type (SHT_xxx constant from elf.h). - uint64 flags; // Section flags (SHF_xxx constants from elf.h). - uint64 addr; // Section virtual address at execution. - uint64 offset; // Section file offset. - uint64 size; // Section size in bytes. - uint32 link; // Link to another section. - uint32 info; // Additional section information. - uint64 addralign; // Section alignment. - uint64 entsize; // Entry size if section holds a table. - }; - const char *GetSectionInfoByName(const string §ion_name, - SectionInfo *info); - - // Check if "path" is an ELF binary that has not been stripped of symbol - // tables. This function supports both 32-bit and 64-bit ELF binaries. - static bool IsNonStrippedELFBinary(const string &path); - - // Check if "path" is an ELF binary that has not been stripped of debug - // info. Unlike IsNonStrippedELFBinary, this function will return - // false for binaries passed through "strip -S". - static bool IsNonDebugStrippedELFBinary(const string &path); - - // Match a requested section name with the section name as it - // appears in the elf-file, adjusting for compressed debug section - // names. For example, returns true if name == ".debug_abbrev" and - // sh_name == ".zdebug_abbrev" - static bool SectionNamesMatch(const string &name, const string &sh_name); - - private: - // Lazily initialize impl32_ and return it. - ElfReaderImpl *GetImpl32(); - // Ditto for impl64_. - ElfReaderImpl *GetImpl64(); - - // Path of the file we're reading. - const string path_; - // Read-only file descriptor for the file. May be -1 if there was an - // error during open. - int fd_; - ElfReaderImpl *impl32_; - ElfReaderImpl *impl64_; -}; - -} // namespace dwarf2reader - -#endif // COMMON_DWARF_ELF_READER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.cc deleted file mode 100644 index 55a255eda..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.cc +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This is a client for the dwarf2reader to extract function and line -// information from the debug info. - -#include -#include -#include - -#include -#include -#include - -#include "common/dwarf/functioninfo.h" -#include "common/dwarf/bytereader.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" - -using google_breakpad::scoped_ptr; - -namespace dwarf2reader { - -CULineInfoHandler::CULineInfoHandler(std::vector* files, - std::vector* dirs, - LineMap* linemap):linemap_(linemap), - files_(files), - dirs_(dirs) { - // The dirs and files are 1 indexed, so just make sure we put - // nothing in the 0 vector. - assert(dirs->size() == 0); - assert(files->size() == 0); - dirs->push_back(""); - SourceFileInfo s; - s.name = ""; - s.lowpc = ULLONG_MAX; - files->push_back(s); -} - -void CULineInfoHandler::DefineDir(const string& name, uint32 dir_num) { - // These should never come out of order, actually - assert(dir_num == dirs_->size()); - dirs_->push_back(name); -} - -void CULineInfoHandler::DefineFile(const string& name, - int32 file_num, uint32 dir_num, - uint64 mod_time, uint64 length) { - assert(dir_num >= 0); - assert(dir_num < dirs_->size()); - - // These should never come out of order, actually. - if (file_num == (int32)files_->size() || file_num == -1) { - string dir = dirs_->at(dir_num); - - SourceFileInfo s; - s.lowpc = ULLONG_MAX; - - if (dir == "") { - s.name = name; - } else { - s.name = dir + "/" + name; - } - - files_->push_back(s); - } else { - fprintf(stderr, "error in DefineFile"); - } -} - -void CULineInfoHandler::AddLine(uint64 address, uint64 length, uint32 file_num, - uint32 line_num, uint32 column_num) { - if (file_num < files_->size()) { - linemap_->insert( - std::make_pair(address, - std::make_pair(files_->at(file_num).name.c_str(), - line_num))); - - if (address < files_->at(file_num).lowpc) { - files_->at(file_num).lowpc = address; - } - } else { - fprintf(stderr, "error in AddLine"); - } -} - -bool CUFunctionInfoHandler::StartCompilationUnit(uint64 offset, - uint8 address_size, - uint8 offset_size, - uint64 cu_length, - uint8 dwarf_version) { - current_compilation_unit_offset_ = offset; - return true; -} - - -// For function info, we only care about subprograms and inlined -// subroutines. For line info, the DW_AT_stmt_list lives in the -// compile unit tag. - -bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag) { - switch (tag) { - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: { - current_function_info_ = new FunctionInfo; - current_function_info_->lowpc = current_function_info_->highpc = 0; - current_function_info_->name = ""; - current_function_info_->line = 0; - current_function_info_->file = ""; - offset_to_funcinfo_->insert(std::make_pair(offset, - current_function_info_)); - }; - // FALLTHROUGH - case DW_TAG_compile_unit: - return true; - default: - return false; - } - return false; -} - -// Only care about the name attribute for functions - -void CUFunctionInfoHandler::ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string &data) { - if (current_function_info_) { - if (attr == DW_AT_name) - current_function_info_->name = data; - else if (attr == DW_AT_MIPS_linkage_name) - current_function_info_->mangled_name = data; - } -} - -void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - if (attr == DW_AT_stmt_list) { - SectionMap::const_iterator iter = sections_.find("__debug_line"); - assert(iter != sections_.end()); - - scoped_ptr lireader(new LineInfo(iter->second.first + data, - iter->second.second - data, - reader_, linehandler_)); - lireader->Start(); - } else if (current_function_info_) { - switch (attr) { - case DW_AT_low_pc: - current_function_info_->lowpc = data; - break; - case DW_AT_high_pc: - current_function_info_->highpc = data; - break; - case DW_AT_decl_line: - current_function_info_->line = data; - break; - case DW_AT_decl_file: - current_function_info_->file = files_->at(data).name; - break; - default: - break; - } - } -} - -void CUFunctionInfoHandler::ProcessAttributeReference(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - if (current_function_info_) { - switch (attr) { - case DW_AT_specification: { - // Some functions have a "specification" attribute - // which means they were defined elsewhere. The name - // attribute is not repeated, and must be taken from - // the specification DIE. Here we'll assume that - // any DIE referenced in this manner will already have - // been seen, but that's not really required by the spec. - FunctionMap::iterator iter = offset_to_funcinfo_->find(data); - if (iter != offset_to_funcinfo_->end()) { - current_function_info_->name = iter->second->name; - current_function_info_->mangled_name = iter->second->mangled_name; - } else { - // If you hit this, this code probably needs to be rewritten. - fprintf(stderr, - "Error: DW_AT_specification was seen before the referenced " - "DIE! (Looking for DIE at offset %08llx, in DIE at " - "offset %08llx)\n", data, offset); - } - break; - } - default: - break; - } - } -} - -void CUFunctionInfoHandler::EndDIE(uint64 offset) { - if (current_function_info_ && current_function_info_->lowpc) - address_to_funcinfo_->insert(std::make_pair(current_function_info_->lowpc, - current_function_info_)); -} - -} // namespace dwarf2reader diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.h deleted file mode 100644 index 0b08a5fc5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.h +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// This file contains the definitions for a DWARF2/3 information -// collector that uses the DWARF2/3 reader interface to build a mapping -// of addresses to files, lines, and functions. - -#ifndef COMMON_DWARF_FUNCTIONINFO_H__ -#define COMMON_DWARF_FUNCTIONINFO_H__ - -#include -#include -#include -#include - -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" - - -namespace dwarf2reader { - -struct FunctionInfo { - // Name of the function - string name; - // Mangled name of the function - string mangled_name; - // File containing this function - string file; - // Line number for start of function. - uint32 line; - // Beginning address for this function - uint64 lowpc; - // End address for this function. - uint64 highpc; -}; - -struct SourceFileInfo { - // Name of the source file name - string name; - // Low address of source file name - uint64 lowpc; -}; - -typedef std::map FunctionMap; -typedef std::map > LineMap; - -// This class is a basic line info handler that fills in the dirs, -// file, and linemap passed into it with the data produced from the -// LineInfoHandler. -class CULineInfoHandler: public LineInfoHandler { - public: - - // - CULineInfoHandler(std::vector* files, - std::vector* dirs, - LineMap* linemap); - virtual ~CULineInfoHandler() { } - - // Called when we define a directory. We just place NAME into dirs_ - // at position DIR_NUM. - virtual void DefineDir(const string& name, uint32 dir_num); - - // Called when we define a filename. We just place - // concat(dirs_[DIR_NUM], NAME) into files_ at position FILE_NUM. - virtual void DefineFile(const string& name, int32 file_num, - uint32 dir_num, uint64 mod_time, uint64 length); - - - // Called when the line info reader has a new line, address pair - // ready for us. ADDRESS is the address of the code, LENGTH is the - // length of its machine code in bytes, FILE_NUM is the file number - // containing the code, LINE_NUM is the line number in that file for - // the code, and COLUMN_NUM is the column number the code starts at, - // if we know it (0 otherwise). - virtual void AddLine(uint64 address, uint64 length, - uint32 file_num, uint32 line_num, uint32 column_num); - - private: - LineMap* linemap_; - std::vector* files_; - std::vector* dirs_; -}; - -class CUFunctionInfoHandler: public Dwarf2Handler { - public: - CUFunctionInfoHandler(std::vector* files, - std::vector* dirs, - LineMap* linemap, - FunctionMap* offset_to_funcinfo, - FunctionMap* address_to_funcinfo, - CULineInfoHandler* linehandler, - const SectionMap& sections, - ByteReader* reader) - : files_(files), dirs_(dirs), linemap_(linemap), - offset_to_funcinfo_(offset_to_funcinfo), - address_to_funcinfo_(address_to_funcinfo), - linehandler_(linehandler), sections_(sections), - reader_(reader), current_function_info_(NULL) { } - - virtual ~CUFunctionInfoHandler() { } - - // Start to process a compilation unit at OFFSET from the beginning of the - // .debug_info section. We want to see all compilation units, so we - // always return true. - - virtual bool StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version); - - // Start to process a DIE at OFFSET from the beginning of the - // .debug_info section. We only care about function related DIE's. - virtual bool StartDIE(uint64 offset, enum DwarfTag tag); - - // Called when we have an attribute with unsigned data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of the .debug_info section, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA. - virtual void ProcessAttributeUnsigned(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - - // Called when we have an attribute with a DIE reference to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of the .debug_info section, has a name of ATTR, a form of - // FORM, and the offset of the referenced DIE from the start of the - // .debug_info section is in DATA. - virtual void ProcessAttributeReference(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - - // Called when we have an attribute with string data to give to - // our handler. The attribute is for the DIE at OFFSET from the - // beginning of the .debug_info section, has a name of ATTR, a form of - // FORM, and the actual data of the attribute is in DATA. - virtual void ProcessAttributeString(uint64 offset, - enum DwarfAttribute attr, - enum DwarfForm form, - const string& data); - - // Called when finished processing the DIE at OFFSET. - // Because DWARF2/3 specifies a tree of DIEs, you may get starts - // before ends of the previous DIE, as we process children before - // ending the parent. - virtual void EndDIE(uint64 offset); - - private: - std::vector* files_; - std::vector* dirs_; - LineMap* linemap_; - FunctionMap* offset_to_funcinfo_; - FunctionMap* address_to_funcinfo_; - CULineInfoHandler* linehandler_; - const SectionMap& sections_; - ByteReader* reader_; - FunctionInfo* current_function_info_; - uint64 current_compilation_unit_offset_; -}; - -} // namespace dwarf2reader -#endif // COMMON_DWARF_FUNCTIONINFO_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/line_state_machine.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/line_state_machine.h deleted file mode 100644 index 0ff72abcf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/line_state_machine.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#ifndef COMMON_DWARF_LINE_STATE_MACHINE_H__ -#define COMMON_DWARF_LINE_STATE_MACHINE_H__ - -namespace dwarf2reader { - -// This is the format of a DWARF2/3 line state machine that we process -// opcodes using. There is no need for anything outside the lineinfo -// processor to know how this works. -struct LineStateMachine { - void Reset(bool default_is_stmt) { - file_num = 1; - address = 0; - line_num = 1; - column_num = 0; - is_stmt = default_is_stmt; - basic_block = false; - end_sequence = false; - } - - uint32 file_num; - uint64 address; - uint32 line_num; - uint32 column_num; - bool is_stmt; // stmt means statement. - bool basic_block; - bool end_sequence; -}; - -} // namespace dwarf2reader - - -#endif // COMMON_DWARF_LINE_STATE_MACHINE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/moz.build b/toolkit/crashreporter/google-breakpad/src/common/dwarf/moz.build deleted file mode 100644 index e1ccc65ac..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/moz.build +++ /dev/null @@ -1,35 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HostLibrary('host_breakpad_dwarf_s') -HOST_SOURCES += [ - 'bytereader.cc', - 'dwarf2diehandler.cc', - 'dwarf2reader.cc', - 'elf_reader.cc', - 'functioninfo.cc', -] -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -# need static lib -FORCE_STATIC_LIB = True - -# This code is only compiled for build-time tools, -# so enabling RTTI should be fine. -HOST_CXXFLAGS += [ - '-frtti', - '-funsigned-char', -] - -if CONFIG['OS_ARCH'] == 'Darwin': - HOST_CXXFLAGS += [ - '-stdlib=libc++', - ] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf/types.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf/types.h deleted file mode 100644 index 59dda3160..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf/types.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2008 Google, Inc. All Rights reserved -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// This file contains some typedefs for basic types - - -#ifndef _COMMON_DWARF_TYPES_H__ -#define _COMMON_DWARF_TYPES_H__ - -#include - -typedef signed char int8; -typedef short int16; -typedef int int32; -typedef long long int64; - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef intptr_t intptr; -typedef uintptr_t uintptr; - -#endif // _COMMON_DWARF_TYPES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.cc deleted file mode 100644 index 1bf1d96d5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.cc +++ /dev/null @@ -1,295 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// Implementation of google_breakpad::DwarfCFIToModule. -// See dwarf_cfi_to_module.h for details. - -#include - -#include "common/dwarf_cfi_to_module.h" - -namespace google_breakpad { - -using std::ostringstream; - -vector DwarfCFIToModule::RegisterNames::MakeVector( - const char * const *strings, - size_t size) { - vector names(strings, strings + size); - return names; -} - -vector DwarfCFIToModule::RegisterNames::I386() { - static const char *const names[] = { - "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi", - "$eip", "$eflags", "$unused1", - "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7", - "$unused2", "$unused3", - "$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7", - "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7", - "$fcw", "$fsw", "$mxcsr", - "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5", - "$tr", "$ldtr" - }; - - return MakeVector(names, sizeof(names) / sizeof(names[0])); -} - -vector DwarfCFIToModule::RegisterNames::X86_64() { - static const char *const names[] = { - "$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp", - "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", - "$rip", - "$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7", - "$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15", - "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7", - "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7", - "$rflags", - "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused1", "$unused2", - "$fs.base", "$gs.base", "$unused3", "$unused4", - "$tr", "$ldtr", - "$mxcsr", "$fcw", "$fsw" - }; - - return MakeVector(names, sizeof(names) / sizeof(names[0])); -} - -// Per ARM IHI 0040A, section 3.1 -vector DwarfCFIToModule::RegisterNames::ARM() { - static const char *const names[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "fps", "cpsr", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", - "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", - "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7" - }; - - return MakeVector(names, sizeof(names) / sizeof(names[0])); -} - -// Per ARM IHI 0057A, section 3.1 -vector DwarfCFIToModule::RegisterNames::ARM64() { - static const char *const names[] = { - "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", - "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", - "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", - "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" - }; - - return MakeVector(names, sizeof(names) / sizeof(names[0])); -} - -vector DwarfCFIToModule::RegisterNames::MIPS() { - static const char* const kRegisterNames[] = { - "$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", - "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", - "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", - "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra", - "$lo", "$hi", "$pc", "$f0", "$f2", "$f3", "$f4", "$f5", - "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", - "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", - "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", - "$f28", "$f29", "$f30", "$f31", "$fcsr", "$fir" - }; - - return MakeVector(kRegisterNames, - sizeof(kRegisterNames) / sizeof(kRegisterNames[0])); -} - -bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length, - uint8 version, const string &augmentation, - unsigned return_address) { - assert(!entry_); - - // If dwarf2reader::CallFrameInfo can handle this version and - // augmentation, then we should be okay with that, so there's no - // need to check them here. - - // Get ready to collect entries. - entry_ = new Module::StackFrameEntry; - entry_->address = address; - entry_->size = length; - entry_offset_ = offset; - return_address_ = return_address; - - // Breakpad STACK CFI records must provide a .ra rule, but DWARF CFI - // may not establish any rule for .ra if the return address column - // is an ordinary register, and that register holds the return - // address on entry to the function. So establish an initial .ra - // rule citing the return address register. - if (return_address_ < register_names_.size()) - entry_->initial_rules[ra_name_] = register_names_[return_address_]; - - return true; -} - -string DwarfCFIToModule::RegisterName(int i) { - assert(entry_); - if (i < 0) { - assert(i == kCFARegister); - return cfa_name_; - } - unsigned reg = i; - if (reg == return_address_) - return ra_name_; - - // Ensure that a non-empty name exists for this register value. - if (reg < register_names_.size() && !register_names_[reg].empty()) - return register_names_[reg]; - - reporter_->UnnamedRegister(entry_offset_, reg); - char buf[30]; - sprintf(buf, "unnamed_register%u", reg); - return buf; -} - -void DwarfCFIToModule::Record(Module::Address address, int reg, - const string &rule) { - assert(entry_); - - // Place the name in our global set of strings, and then use the string - // from the set. Even though the assignment looks like a copy, all the - // major std::string implementations use reference counting internally, - // so the effect is to have all our data structures share copies of rules - // whenever possible. Since register names are drawn from a - // vector, register names are already shared. - string shared_rule = *common_strings_.insert(rule).first; - - // Is this one of this entry's initial rules? - if (address == entry_->address) - entry_->initial_rules[RegisterName(reg)] = shared_rule; - // File it under the appropriate address. - else - entry_->rule_changes[address][RegisterName(reg)] = shared_rule; -} - -bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) { - reporter_->UndefinedNotSupported(entry_offset_, RegisterName(reg)); - // Treat this as a non-fatal error. - return true; -} - -bool DwarfCFIToModule::SameValueRule(uint64 address, int reg) { - ostringstream s; - s << RegisterName(reg); - Record(address, reg, s.str()); - return true; -} - -bool DwarfCFIToModule::OffsetRule(uint64 address, int reg, - int base_register, long offset) { - ostringstream s; - s << RegisterName(base_register) << " " << offset << " + ^"; - Record(address, reg, s.str()); - return true; -} - -bool DwarfCFIToModule::ValOffsetRule(uint64 address, int reg, - int base_register, long offset) { - ostringstream s; - s << RegisterName(base_register) << " " << offset << " +"; - Record(address, reg, s.str()); - return true; -} - -bool DwarfCFIToModule::RegisterRule(uint64 address, int reg, - int base_register) { - ostringstream s; - s << RegisterName(base_register); - Record(address, reg, s.str()); - return true; -} - -bool DwarfCFIToModule::ExpressionRule(uint64 address, int reg, - const string &expression) { - reporter_->ExpressionsNotSupported(entry_offset_, RegisterName(reg)); - // Treat this as a non-fatal error. - return true; -} - -bool DwarfCFIToModule::ValExpressionRule(uint64 address, int reg, - const string &expression) { - reporter_->ExpressionsNotSupported(entry_offset_, RegisterName(reg)); - // Treat this as a non-fatal error. - return true; -} - -bool DwarfCFIToModule::End() { - module_->AddStackFrameEntry(entry_); - entry_ = NULL; - return true; -} - -void DwarfCFIToModule::Reporter::UnnamedRegister(size_t offset, int reg) { - fprintf(stderr, "%s, section '%s': " - "the call frame entry at offset 0x%zx refers to register %d," - " whose name we don't know\n", - file_.c_str(), section_.c_str(), offset, reg); -} - -void DwarfCFIToModule::Reporter::UndefinedNotSupported(size_t offset, - const string ®) { - fprintf(stderr, "%s, section '%s': " - "the call frame entry at offset 0x%zx sets the rule for " - "register '%s' to 'undefined', but the Breakpad symbol file format" - " cannot express this\n", - file_.c_str(), section_.c_str(), offset, reg.c_str()); -} - -void DwarfCFIToModule::Reporter::ExpressionsNotSupported(size_t offset, - const string ®) { - fprintf(stderr, "%s, section '%s': " - "the call frame entry at offset 0x%zx uses a DWARF expression to" - " describe how to recover register '%s', " - " but this translator cannot yet translate DWARF expressions to" - " Breakpad postfix expressions\n", - file_.c_str(), section_.c_str(), offset, reg.c_str()); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h deleted file mode 100644 index 084b8f5a7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h +++ /dev/null @@ -1,202 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf_cfi_to_module.h: Define the DwarfCFIToModule class, which -// accepts parsed DWARF call frame info and adds it to a -// google_breakpad::Module object, which can write that information to -// a Breakpad symbol file. - -#ifndef COMMON_LINUX_DWARF_CFI_TO_MODULE_H -#define COMMON_LINUX_DWARF_CFI_TO_MODULE_H - -#include -#include - -#include -#include -#include - -#include "common/module.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -using dwarf2reader::CallFrameInfo; -using google_breakpad::Module; -using std::set; -using std::vector; - -// A class that accepts parsed call frame information from the DWARF -// CFI parser and populates a google_breakpad::Module object with the -// contents. -class DwarfCFIToModule: public CallFrameInfo::Handler { - public: - - // DwarfCFIToModule uses an instance of this class to report errors - // detected while converting DWARF CFI to Breakpad STACK CFI records. - class Reporter { - public: - // Create a reporter that writes messages to the standard error - // stream. FILE is the name of the file we're processing, and - // SECTION is the name of the section within that file that we're - // looking at (.debug_frame, .eh_frame, etc.). - Reporter(const string &file, const string §ion) - : file_(file), section_(section) { } - virtual ~Reporter() { } - - // The DWARF CFI entry at OFFSET cites register REG, but REG is not - // covered by the vector of register names passed to the - // DwarfCFIToModule constructor, nor does it match the return - // address column number for this entry. - virtual void UnnamedRegister(size_t offset, int reg); - - // The DWARF CFI entry at OFFSET says that REG is undefined, but the - // Breakpad symbol file format cannot express this. - virtual void UndefinedNotSupported(size_t offset, const string ®); - - // The DWARF CFI entry at OFFSET says that REG uses a DWARF - // expression to find its value, but DwarfCFIToModule is not - // capable of translating DWARF expressions to Breakpad postfix - // expressions. - virtual void ExpressionsNotSupported(size_t offset, const string ®); - - protected: - string file_, section_; - }; - - // Register name tables. If TABLE is a vector returned by one of these - // functions, then TABLE[R] is the name of the register numbered R in - // DWARF call frame information. - class RegisterNames { - public: - // Intel's "x86" or IA-32. - static vector I386(); - - // AMD x86_64, AMD64, Intel EM64T, or Intel 64 - static vector X86_64(); - - // ARM. - static vector ARM(); - - // ARM64, aka AARCH64. - static vector ARM64(); - - // MIPS. - static vector MIPS(); - - private: - // Given STRINGS, an array of C strings with SIZE elements, return an - // equivalent vector. - static vector MakeVector(const char * const *strings, size_t size); - }; - - // Create a handler for the dwarf2reader::CallFrameInfo parser that - // records the stack unwinding information it receives in MODULE. - // - // Use REGISTER_NAMES[I] as the name of register number I; *this - // keeps a reference to the vector, so the vector should remain - // alive for as long as the DwarfCFIToModule does. - // - // Use REPORTER for reporting problems encountered in the conversion - // process. - DwarfCFIToModule(Module *module, const vector ®ister_names, - Reporter *reporter) - : module_(module), register_names_(register_names), reporter_(reporter), - entry_(NULL), return_address_(-1), cfa_name_(".cfa"), ra_name_(".ra") { - } - virtual ~DwarfCFIToModule() { delete entry_; } - - virtual bool Entry(size_t offset, uint64 address, uint64 length, - uint8 version, const string &augmentation, - unsigned return_address); - virtual bool UndefinedRule(uint64 address, int reg); - virtual bool SameValueRule(uint64 address, int reg); - virtual bool OffsetRule(uint64 address, int reg, - int base_register, long offset); - virtual bool ValOffsetRule(uint64 address, int reg, - int base_register, long offset); - virtual bool RegisterRule(uint64 address, int reg, int base_register); - virtual bool ExpressionRule(uint64 address, int reg, - const string &expression); - virtual bool ValExpressionRule(uint64 address, int reg, - const string &expression); - virtual bool End(); - - private: - // Return the name to use for register REG. - string RegisterName(int i); - - // Record RULE for register REG at ADDRESS. - void Record(Module::Address address, int reg, const string &rule); - - // The module to which we should add entries. - Module *module_; - - // Map from register numbers to register names. - const vector ®ister_names_; - - // The reporter to use to report problems. - Reporter *reporter_; - - // The current entry we're constructing. - Module::StackFrameEntry *entry_; - - // The section offset of the current frame description entry, for - // use in error messages. - size_t entry_offset_; - - // The return address column for that entry. - unsigned return_address_; - - // The names of the return address and canonical frame address. Putting - // these here instead of using string literals allows us to share their - // texts in reference-counted std::string implementations (all the - // popular ones). Many, many rules cite these strings. - string cfa_name_, ra_name_; - - // A set of strings used by this CFI. Before storing a string in one of - // our data structures, insert it into this set, and then use the string - // from the set. - // - // Because std::string uses reference counting internally, simply using - // strings from this set, even if passed by value, assigned, or held - // directly in structures and containers (map, for example), - // causes those strings to share a single instance of each distinct piece - // of text. - set common_strings_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_DWARF_CFI_TO_MODULE_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module_unittest.cc deleted file mode 100644 index 807d1b20c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module_unittest.cc +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf_cfi_to_module_unittest.cc: Tests for google_breakpad::DwarfCFIToModule. - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/dwarf_cfi_to_module.h" -#include "common/using_std_string.h" - -using std::vector; - -using google_breakpad::Module; -using google_breakpad::DwarfCFIToModule; -using testing::ContainerEq; -using testing::Test; -using testing::_; - -struct MockCFIReporter: public DwarfCFIToModule::Reporter { - MockCFIReporter(const string &file, const string §ion) - : Reporter(file, section) { } - MOCK_METHOD2(UnnamedRegister, void(size_t offset, int reg)); - MOCK_METHOD2(UndefinedNotSupported, void(size_t offset, const string ®)); - MOCK_METHOD2(ExpressionsNotSupported, void(size_t offset, const string ®)); -}; - -struct DwarfCFIToModuleFixture { - DwarfCFIToModuleFixture() - : module("module name", "module os", "module arch", "module id"), - reporter("reporter file", "reporter section"), - handler(&module, register_names, &reporter) { - register_names.push_back("reg0"); - register_names.push_back("reg1"); - register_names.push_back("reg2"); - register_names.push_back("reg3"); - register_names.push_back("reg4"); - register_names.push_back("reg5"); - register_names.push_back("reg6"); - register_names.push_back("reg7"); - register_names.push_back("sp"); - register_names.push_back("pc"); - register_names.push_back(""); - - EXPECT_CALL(reporter, UnnamedRegister(_, _)).Times(0); - EXPECT_CALL(reporter, UndefinedNotSupported(_, _)).Times(0); - EXPECT_CALL(reporter, ExpressionsNotSupported(_, _)).Times(0); - } - - Module module; - vector register_names; - MockCFIReporter reporter; - DwarfCFIToModule handler; - vector entries; -}; - -class Entry: public DwarfCFIToModuleFixture, public Test { }; - -TEST_F(Entry, Accept) { - ASSERT_TRUE(handler.Entry(0x3b8961b8, 0xa21069698096fc98ULL, - 0xb440ce248169c8d6ULL, 3, "", 0xea93c106)); - ASSERT_TRUE(handler.End()); - module.GetStackFrameEntries(&entries); - EXPECT_EQ(1U, entries.size()); - EXPECT_EQ(0xa21069698096fc98ULL, entries[0]->address); - EXPECT_EQ(0xb440ce248169c8d6ULL, entries[0]->size); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Entry, AcceptOldVersion) { - ASSERT_TRUE(handler.Entry(0xeb60e0fc, 0x75b8806bb09eab78ULL, - 0xc771f44958d40bbcULL, 1, "", 0x093c945e)); - ASSERT_TRUE(handler.End()); - module.GetStackFrameEntries(&entries); - EXPECT_EQ(1U, entries.size()); - EXPECT_EQ(0x75b8806bb09eab78ULL, entries[0]->address); - EXPECT_EQ(0xc771f44958d40bbcULL, entries[0]->size); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -struct RuleFixture: public DwarfCFIToModuleFixture { - RuleFixture() : DwarfCFIToModuleFixture() { - entry_address = 0x89327ebf86b47492ULL; - entry_size = 0x2f8cd573072fe02aULL; - return_reg = 0x7886a346; - } - void StartEntry() { - ASSERT_TRUE(handler.Entry(0x4445c05c, entry_address, entry_size, - 3, "", return_reg)); - } - void CheckEntry() { - module.GetStackFrameEntries(&entries); - EXPECT_EQ(1U, entries.size()); - EXPECT_EQ(entry_address, entries[0]->address); - EXPECT_EQ(entry_size, entries[0]->size); - } - uint64 entry_address, entry_size; - unsigned return_reg; -}; - -class Rule: public RuleFixture, public Test { }; - -TEST_F(Rule, UndefinedRule) { - EXPECT_CALL(reporter, UndefinedNotSupported(_, "reg7")); - StartEntry(); - ASSERT_TRUE(handler.UndefinedRule(entry_address, 7)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, RegisterWithEmptyName) { - EXPECT_CALL(reporter, UnnamedRegister(_, 10)); - EXPECT_CALL(reporter, UndefinedNotSupported(_, "unnamed_register10")); - StartEntry(); - ASSERT_TRUE(handler.UndefinedRule(entry_address, 10)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, SameValueRule) { - StartEntry(); - ASSERT_TRUE(handler.SameValueRule(entry_address, 6)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - Module::RuleMap expected_initial; - expected_initial["reg6"] = "reg6"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, OffsetRule) { - StartEntry(); - ASSERT_TRUE(handler.OffsetRule(entry_address + 1, return_reg, - DwarfCFIToModule::kCFARegister, - 16927065)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - Module::RuleChangeMap expected_changes; - expected_changes[entry_address + 1][".ra"] = ".cfa 16927065 + ^"; - EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); -} - -TEST_F(Rule, OffsetRuleNegative) { - StartEntry(); - ASSERT_TRUE(handler.OffsetRule(entry_address + 1, - DwarfCFIToModule::kCFARegister, 4, -34530721)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - Module::RuleChangeMap expected_changes; - expected_changes[entry_address + 1][".cfa"] = "reg4 -34530721 + ^"; - EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); -} - -TEST_F(Rule, ValOffsetRule) { - // Use an unnamed register number, to exercise that branch of RegisterName. - EXPECT_CALL(reporter, UnnamedRegister(_, 11)); - StartEntry(); - ASSERT_TRUE(handler.ValOffsetRule(entry_address + 0x5ab7, - DwarfCFIToModule::kCFARegister, - 11, 61812979)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - Module::RuleChangeMap expected_changes; - expected_changes[entry_address + 0x5ab7][".cfa"] = - "unnamed_register11 61812979 +"; - EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); -} - -TEST_F(Rule, RegisterRule) { - StartEntry(); - ASSERT_TRUE(handler.RegisterRule(entry_address, return_reg, 3)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - Module::RuleMap expected_initial; - expected_initial[".ra"] = "reg3"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, ExpressionRule) { - EXPECT_CALL(reporter, ExpressionsNotSupported(_, "reg2")); - StartEntry(); - ASSERT_TRUE(handler.ExpressionRule(entry_address + 0xf326, 2, - "it takes two to tango")); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, ValExpressionRule) { - EXPECT_CALL(reporter, ExpressionsNotSupported(_, "reg0")); - StartEntry(); - ASSERT_TRUE(handler.ValExpressionRule(entry_address + 0x6367, 0, - "bit off more than he could chew")); - ASSERT_TRUE(handler.End()); - CheckEntry(); - EXPECT_EQ(0U, entries[0]->initial_rules.size()); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, DefaultReturnAddressRule) { - return_reg = 2; - StartEntry(); - ASSERT_TRUE(handler.RegisterRule(entry_address, 0, 1)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - Module::RuleMap expected_initial; - expected_initial[".ra"] = "reg2"; - expected_initial["reg0"] = "reg1"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, DefaultReturnAddressRuleOverride) { - return_reg = 2; - StartEntry(); - ASSERT_TRUE(handler.RegisterRule(entry_address, return_reg, 1)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - Module::RuleMap expected_initial; - expected_initial[".ra"] = "reg1"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); - EXPECT_EQ(0U, entries[0]->rule_changes.size()); -} - -TEST_F(Rule, DefaultReturnAddressRuleLater) { - return_reg = 2; - StartEntry(); - ASSERT_TRUE(handler.RegisterRule(entry_address + 1, return_reg, 1)); - ASSERT_TRUE(handler.End()); - CheckEntry(); - Module::RuleMap expected_initial; - expected_initial[".ra"] = "reg2"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); - Module::RuleChangeMap expected_changes; - expected_changes[entry_address + 1][".ra"] = "reg1"; - EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); -} - -TEST(RegisterNames, I386) { - vector names = DwarfCFIToModule::RegisterNames::I386(); - - EXPECT_EQ("$eax", names[0]); - EXPECT_EQ("$ecx", names[1]); - EXPECT_EQ("$esp", names[4]); - EXPECT_EQ("$eip", names[8]); -} - -TEST(RegisterNames, ARM) { - vector names = DwarfCFIToModule::RegisterNames::ARM(); - - EXPECT_EQ("r0", names[0]); - EXPECT_EQ("r10", names[10]); - EXPECT_EQ("sp", names[13]); - EXPECT_EQ("lr", names[14]); - EXPECT_EQ("pc", names[15]); -} - -TEST(RegisterNames, X86_64) { - vector names = DwarfCFIToModule::RegisterNames::X86_64(); - - EXPECT_EQ("$rax", names[0]); - EXPECT_EQ("$rdx", names[1]); - EXPECT_EQ("$rbp", names[6]); - EXPECT_EQ("$rsp", names[7]); - EXPECT_EQ("$rip", names[16]); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc deleted file mode 100644 index 479e39b22..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.cc +++ /dev/null @@ -1,1075 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// Implement the DwarfCUToModule class; see dwarf_cu_to_module.h. - -// For PRI* macros, before anything else might #include it. -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif /* __STDC_FORMAT_MACROS */ - -#include "common/dwarf_cu_to_module.h" - -#include -#if !defined(__ANDROID__) -#include -#endif -#include -#include -#include - -#include -#include - -#include "common/dwarf_line_to_module.h" -#include "common/unordered.h" - -namespace google_breakpad { - -using std::map; -using std::pair; -using std::sort; -using std::vector; - -// Data provided by a DWARF specification DIE. -// -// In DWARF, the DIE for a definition may contain a DW_AT_specification -// attribute giving the offset of the corresponding declaration DIE, and -// the definition DIE may omit information given in the declaration. For -// example, it's common for a function's address range to appear only in -// its definition DIE, but its name to appear only in its declaration -// DIE. -// -// The dumper needs to be able to follow DW_AT_specification links to -// bring all this information together in a FUNC record. Conveniently, -// DIEs that are the target of such links have a DW_AT_declaration flag -// set, so we can identify them when we first see them, and record their -// contents for later reference. -// -// A Specification holds information gathered from a declaration DIE that -// we may need if we find a DW_AT_specification link pointing to it. -struct DwarfCUToModule::Specification { - // The qualified name that can be found by demangling DW_AT_MIPS_linkage_name. - string qualified_name; - - // The name of the enclosing scope, or the empty string if there is none. - string enclosing_name; - - // The name for the specification DIE itself, without any enclosing - // name components. - string unqualified_name; -}; - -// An abstract origin -- base definition of an inline function. -struct AbstractOrigin { - AbstractOrigin() : name() {} - explicit AbstractOrigin(const string& name) : name(name) {} - - string name; -}; - -typedef map AbstractOriginByOffset; - -// Data global to the DWARF-bearing file that is private to the -// DWARF-to-Module process. -struct DwarfCUToModule::FilePrivate { - // A set of strings used in this CU. Before storing a string in one of - // our data structures, insert it into this set, and then use the string - // from the set. - // - // In some STL implementations, strings are reference-counted internally, - // meaning that simply using strings from this set, even if passed by - // value, assigned, or held directly in structures and containers - // (map, for example), causes those strings to share a - // single instance of each distinct piece of text. GNU's libstdc++ uses - // reference counts, and I believe MSVC did as well, at some point. - // However, C++ '11 implementations are moving away from reference - // counting. - // - // In other implementations, string assignments copy the string's text, - // so this set will actually hold yet another copy of the string (although - // everything will still work). To improve memory consumption portably, - // we will probably need to use pointers to strings held in this set. - unordered_set common_strings; - - // A map from offsets of DIEs within the .debug_info section to - // Specifications describing those DIEs. Specification references can - // cross compilation unit boundaries. - SpecificationByOffset specifications; - - AbstractOriginByOffset origins; -}; - -DwarfCUToModule::FileContext::FileContext(const string &filename, - Module *module, - bool handle_inter_cu_refs) - : filename_(filename), - module_(module), - handle_inter_cu_refs_(handle_inter_cu_refs), - file_private_(new FilePrivate()) { -} - -DwarfCUToModule::FileContext::~FileContext() { -} - -void DwarfCUToModule::FileContext::AddSectionToSectionMap( - const string& name, const uint8_t *contents, uint64 length) { - section_map_[name] = std::make_pair(contents, length); -} - -void DwarfCUToModule::FileContext::ClearSectionMapForTest() { - section_map_.clear(); -} - -const dwarf2reader::SectionMap& -DwarfCUToModule::FileContext::section_map() const { - return section_map_; -} - -void DwarfCUToModule::FileContext::ClearSpecifications() { - if (!handle_inter_cu_refs_) - file_private_->specifications.clear(); -} - -bool DwarfCUToModule::FileContext::IsUnhandledInterCUReference( - uint64 offset, uint64 compilation_unit_start) const { - if (handle_inter_cu_refs_) - return false; - return offset < compilation_unit_start; -} - -// Information global to the particular compilation unit we're -// parsing. This is for data shared across the CU's entire DIE tree, -// and parameters from the code invoking the CU parser. -struct DwarfCUToModule::CUContext { - CUContext(FileContext *file_context_arg, WarningReporter *reporter_arg) - : file_context(file_context_arg), - reporter(reporter_arg), - language(Language::CPlusPlus) {} - - ~CUContext() { - for (vector::iterator it = functions.begin(); - it != functions.end(); ++it) { - delete *it; - } - }; - - // The DWARF-bearing file into which this CU was incorporated. - FileContext *file_context; - - // For printing error messages. - WarningReporter *reporter; - - // The source language of this compilation unit. - const Language *language; - - // The functions defined in this compilation unit. We accumulate - // them here during parsing. Then, in DwarfCUToModule::Finish, we - // assign them lines and add them to file_context->module. - // - // Destroying this destroys all the functions this vector points to. - vector functions; -}; - -// Information about the context of a particular DIE. This is for -// information that changes as we descend the tree towards the leaves: -// the containing classes/namespaces, etc. -struct DwarfCUToModule::DIEContext { - // The fully-qualified name of the context. For example, for a - // tree like: - // - // DW_TAG_namespace Foo - // DW_TAG_class Bar - // DW_TAG_subprogram Baz - // - // in a C++ compilation unit, the DIEContext's name for the - // DW_TAG_subprogram DIE would be "Foo::Bar". The DIEContext's - // name for the DW_TAG_namespace DIE would be "". - string name; -}; - -// An abstract base class for all the dumper's DIE handlers. -class DwarfCUToModule::GenericDIEHandler: public dwarf2reader::DIEHandler { - public: - // Create a handler for the DIE at OFFSET whose compilation unit is - // described by CU_CONTEXT, and whose immediate context is described - // by PARENT_CONTEXT. - GenericDIEHandler(CUContext *cu_context, DIEContext *parent_context, - uint64 offset) - : cu_context_(cu_context), - parent_context_(parent_context), - offset_(offset), - declaration_(false), - specification_(NULL) { } - - // Derived classes' ProcessAttributeUnsigned can defer to this to - // handle DW_AT_declaration, or simply not override it. - void ProcessAttributeUnsigned(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - - // Derived classes' ProcessAttributeReference can defer to this to - // handle DW_AT_specification, or simply not override it. - void ProcessAttributeReference(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - - // Derived classes' ProcessAttributeReference can defer to this to - // handle DW_AT_specification, or simply not override it. - void ProcessAttributeString(enum DwarfAttribute attr, - enum DwarfForm form, - const string &data); - - protected: - // Compute and return the fully-qualified name of the DIE. If this - // DIE is a declaration DIE, to be cited by other DIEs' - // DW_AT_specification attributes, record its enclosing name and - // unqualified name in the specification table. - // - // Use this from EndAttributes member functions, not ProcessAttribute* - // functions; only the former can be sure that all the DIE's attributes - // have been seen. - string ComputeQualifiedName(); - - CUContext *cu_context_; - DIEContext *parent_context_; - uint64 offset_; - - // Place the name in the global set of strings. Even though this looks - // like a copy, all the major std::string implementations use reference - // counting internally, so the effect is to have all the data structures - // share copies of strings whenever possible. - // FIXME: Should this return something like a string_ref to avoid the - // assumption about how strings are implemented? - string AddStringToPool(const string &str); - - // If this DIE has a DW_AT_declaration attribute, this is its value. - // It is false on DIEs with no DW_AT_declaration attribute. - bool declaration_; - - // If this DIE has a DW_AT_specification attribute, this is the - // Specification structure for the DIE the attribute refers to. - // Otherwise, this is NULL. - Specification *specification_; - - // The value of the DW_AT_name attribute, or the empty string if the - // DIE has no such attribute. - string name_attribute_; - - // The demangled value of the DW_AT_MIPS_linkage_name attribute, or the empty - // string if the DIE has no such attribute or its content could not be - // demangled. - string demangled_name_; -}; - -void DwarfCUToModule::GenericDIEHandler::ProcessAttributeUnsigned( - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - switch (attr) { - case dwarf2reader::DW_AT_declaration: declaration_ = (data != 0); break; - default: break; - } -} - -void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference( - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - switch (attr) { - case dwarf2reader::DW_AT_specification: { - FileContext *file_context = cu_context_->file_context; - if (file_context->IsUnhandledInterCUReference( - data, cu_context_->reporter->cu_offset())) { - cu_context_->reporter->UnhandledInterCUReference(offset_, data); - break; - } - // Find the Specification to which this attribute refers, and - // set specification_ appropriately. We could do more processing - // here, but it's better to leave the real work to our - // EndAttribute member function, at which point we know we have - // seen all the DIE's attributes. - SpecificationByOffset *specifications = - &file_context->file_private_->specifications; - SpecificationByOffset::iterator spec = specifications->find(data); - if (spec != specifications->end()) { - specification_ = &spec->second; - } else { - // Technically, there's no reason a DW_AT_specification - // couldn't be a forward reference, but supporting that would - // be a lot of work (changing to a two-pass structure), and I - // don't think any producers we care about ever emit such - // things. - cu_context_->reporter->UnknownSpecification(offset_, data); - } - break; - } - default: break; - } -} - -string DwarfCUToModule::GenericDIEHandler::AddStringToPool(const string &str) { - pair::iterator, bool> result = - cu_context_->file_context->file_private_->common_strings.insert(str); - return *result.first; -} - -void DwarfCUToModule::GenericDIEHandler::ProcessAttributeString( - enum DwarfAttribute attr, - enum DwarfForm form, - const string &data) { - switch (attr) { - case dwarf2reader::DW_AT_name: - name_attribute_ = AddStringToPool(data); - break; - case dwarf2reader::DW_AT_MIPS_linkage_name: { - char* demangled = NULL; - int status = -1; -#if !defined(__ANDROID__) // Android NDK doesn't provide abi::__cxa_demangle. - demangled = abi::__cxa_demangle(data.c_str(), NULL, NULL, &status); -#endif - if (status != 0) { - cu_context_->reporter->DemangleError(data, status); - demangled_name_ = ""; - break; - } - if (demangled) { - demangled_name_ = AddStringToPool(demangled); - free(reinterpret_cast(demangled)); - } - break; - } - default: break; - } -} - -string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() { - // Use the demangled name, if one is available. Demangled names are - // preferable to those inferred from the DWARF structure because they - // include argument types. - const string *qualified_name = NULL; - if (!demangled_name_.empty()) { - // Found it is this DIE. - qualified_name = &demangled_name_; - } else if (specification_ && !specification_->qualified_name.empty()) { - // Found it on the specification. - qualified_name = &specification_->qualified_name; - } - - const string *unqualified_name = NULL; - const string *enclosing_name; - if (!qualified_name) { - // Find the unqualified name. If the DIE has its own DW_AT_name - // attribute, then use that; otherwise, check the specification. - if (!name_attribute_.empty()) - unqualified_name = &name_attribute_; - else if (specification_) - unqualified_name = &specification_->unqualified_name; - - // Find the name of the enclosing context. If this DIE has a - // specification, it's the specification's enclosing context that - // counts; otherwise, use this DIE's context. - if (specification_) - enclosing_name = &specification_->enclosing_name; - else - enclosing_name = &parent_context_->name; - } - - // Prepare the return value before upcoming mutations possibly invalidate the - // existing pointers. - string return_value; - if (qualified_name) { - return_value = *qualified_name; - } else if (unqualified_name && enclosing_name) { - // Combine the enclosing name and unqualified name to produce our - // own fully-qualified name. - return_value = cu_context_->language->MakeQualifiedName(*enclosing_name, - *unqualified_name); - } - - // If this DIE was marked as a declaration, record its names in the - // specification table. - if ((declaration_ && qualified_name) || - (unqualified_name && enclosing_name)) { - Specification spec; - if (qualified_name) { - spec.qualified_name = *qualified_name; - } else { - spec.enclosing_name = *enclosing_name; - spec.unqualified_name = *unqualified_name; - } - cu_context_->file_context->file_private_->specifications[offset_] = spec; - } - - return return_value; -} - -// A handler class for DW_TAG_subprogram DIEs. -class DwarfCUToModule::FuncHandler: public GenericDIEHandler { - public: - FuncHandler(CUContext *cu_context, DIEContext *parent_context, - uint64 offset) - : GenericDIEHandler(cu_context, parent_context, offset), - low_pc_(0), high_pc_(0), high_pc_form_(dwarf2reader::DW_FORM_addr), - abstract_origin_(NULL), inline_(false) { } - void ProcessAttributeUnsigned(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - void ProcessAttributeSigned(enum DwarfAttribute attr, - enum DwarfForm form, - int64 data); - void ProcessAttributeReference(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - - bool EndAttributes(); - void Finish(); - - private: - // The fully-qualified name, as derived from name_attribute_, - // specification_, parent_context_. Computed in EndAttributes. - string name_; - uint64 low_pc_, high_pc_; // DW_AT_low_pc, DW_AT_high_pc - DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address. - const AbstractOrigin* abstract_origin_; - bool inline_; -}; - -void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned( - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - switch (attr) { - // If this attribute is present at all --- even if its value is - // DW_INL_not_inlined --- then GCC may cite it as someone else's - // DW_AT_abstract_origin attribute. - case dwarf2reader::DW_AT_inline: inline_ = true; break; - - case dwarf2reader::DW_AT_low_pc: low_pc_ = data; break; - case dwarf2reader::DW_AT_high_pc: - high_pc_form_ = form; - high_pc_ = data; - break; - - default: - GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data); - break; - } -} - -void DwarfCUToModule::FuncHandler::ProcessAttributeSigned( - enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { - switch (attr) { - // If this attribute is present at all --- even if its value is - // DW_INL_not_inlined --- then GCC may cite it as someone else's - // DW_AT_abstract_origin attribute. - case dwarf2reader::DW_AT_inline: inline_ = true; break; - - default: - break; - } -} - -void DwarfCUToModule::FuncHandler::ProcessAttributeReference( - enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - switch (attr) { - case dwarf2reader::DW_AT_abstract_origin: { - const AbstractOriginByOffset& origins = - cu_context_->file_context->file_private_->origins; - AbstractOriginByOffset::const_iterator origin = origins.find(data); - if (origin != origins.end()) { - abstract_origin_ = &(origin->second); - } else { - cu_context_->reporter->UnknownAbstractOrigin(offset_, data); - } - break; - } - default: - GenericDIEHandler::ProcessAttributeReference(attr, form, data); - break; - } -} - -bool DwarfCUToModule::FuncHandler::EndAttributes() { - // Compute our name, and record a specification, if appropriate. - name_ = ComputeQualifiedName(); - if (name_.empty() && abstract_origin_) { - name_ = abstract_origin_->name; - } - return true; -} - -void DwarfCUToModule::FuncHandler::Finish() { - // Make high_pc_ an address, if it isn't already. - if (high_pc_form_ != dwarf2reader::DW_FORM_addr) { - high_pc_ += low_pc_; - } - - // Did we collect the information we need? Not all DWARF function - // entries have low and high addresses (for example, inlined - // functions that were never used), but all the ones we're - // interested in cover a non-empty range of bytes. - if (low_pc_ < high_pc_) { - // Malformed DWARF may omit the name, but all Module::Functions must - // have names. - string name; - if (!name_.empty()) { - name = name_; - } else { - cu_context_->reporter->UnnamedFunction(offset_); - name = ""; - } - - // Create a Module::Function based on the data we've gathered, and - // add it to the functions_ list. - scoped_ptr func(new Module::Function(name, low_pc_)); - func->size = high_pc_ - low_pc_; - func->parameter_size = 0; - if (func->address) { - // If the function address is zero this is a sign that this function - // description is just empty debug data and should just be discarded. - cu_context_->functions.push_back(func.release()); - } - } else if (inline_) { - AbstractOrigin origin(name_); - cu_context_->file_context->file_private_->origins[offset_] = origin; - } -} - -// A handler for DIEs that contain functions and contribute a -// component to their names: namespaces, classes, etc. -class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { - public: - NamedScopeHandler(CUContext *cu_context, DIEContext *parent_context, - uint64 offset) - : GenericDIEHandler(cu_context, parent_context, offset) { } - bool EndAttributes(); - DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag); - - private: - DIEContext child_context_; // A context for our children. -}; - -bool DwarfCUToModule::NamedScopeHandler::EndAttributes() { - child_context_.name = ComputeQualifiedName(); - return true; -} - -dwarf2reader::DIEHandler *DwarfCUToModule::NamedScopeHandler::FindChildHandler( - uint64 offset, - enum DwarfTag tag) { - switch (tag) { - case dwarf2reader::DW_TAG_subprogram: - return new FuncHandler(cu_context_, &child_context_, offset); - case dwarf2reader::DW_TAG_namespace: - case dwarf2reader::DW_TAG_class_type: - case dwarf2reader::DW_TAG_structure_type: - case dwarf2reader::DW_TAG_union_type: - return new NamedScopeHandler(cu_context_, &child_context_, offset); - default: - return NULL; - } -} - -void DwarfCUToModule::WarningReporter::CUHeading() { - if (printed_cu_header_) - return; - fprintf(stderr, "%s: in compilation unit '%s' (offset 0x%llx):\n", - filename_.c_str(), cu_name_.c_str(), cu_offset_); - printed_cu_header_ = true; -} - -void DwarfCUToModule::WarningReporter::UnknownSpecification(uint64 offset, - uint64 target) { - CUHeading(); - fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_specification" - " attribute referring to the die at offset 0x%llx, which either" - " was not marked as a declaration, or comes later in the file\n", - filename_.c_str(), offset, target); -} - -void DwarfCUToModule::WarningReporter::UnknownAbstractOrigin(uint64 offset, - uint64 target) { - CUHeading(); - fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_abstract_origin" - " attribute referring to the die at offset 0x%llx, which either" - " was not marked as an inline, or comes later in the file\n", - filename_.c_str(), offset, target); -} - -void DwarfCUToModule::WarningReporter::MissingSection(const string &name) { - CUHeading(); - fprintf(stderr, "%s: warning: couldn't find DWARF '%s' section\n", - filename_.c_str(), name.c_str()); -} - -void DwarfCUToModule::WarningReporter::BadLineInfoOffset(uint64 offset) { - CUHeading(); - fprintf(stderr, "%s: warning: line number data offset beyond end" - " of '.debug_line' section\n", - filename_.c_str()); -} - -void DwarfCUToModule::WarningReporter::UncoveredHeading() { - if (printed_unpaired_header_) - return; - CUHeading(); - fprintf(stderr, "%s: warning: skipping unpaired lines/functions:\n", - filename_.c_str()); - printed_unpaired_header_ = true; -} - -void DwarfCUToModule::WarningReporter::UncoveredFunction( - const Module::Function &function) { - if (!uncovered_warnings_enabled_) - return; - UncoveredHeading(); - fprintf(stderr, " function%s: %s\n", - function.size == 0 ? " (zero-length)" : "", - function.name.c_str()); -} - -void DwarfCUToModule::WarningReporter::UncoveredLine(const Module::Line &line) { - if (!uncovered_warnings_enabled_) - return; - UncoveredHeading(); - fprintf(stderr, " line%s: %s:%d at 0x%" PRIx64 "\n", - (line.size == 0 ? " (zero-length)" : ""), - line.file->name.c_str(), line.number, line.address); -} - -void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) { - CUHeading(); - fprintf(stderr, "%s: warning: function at offset 0x%llx has no name\n", - filename_.c_str(), offset); -} - -void DwarfCUToModule::WarningReporter::DemangleError( - const string &input, int error) { - CUHeading(); - fprintf(stderr, "%s: warning: failed to demangle %s with error %d\n", - filename_.c_str(), input.c_str(), error); -} - -void DwarfCUToModule::WarningReporter::UnhandledInterCUReference( - uint64 offset, uint64 target) { - CUHeading(); - fprintf(stderr, "%s: warning: the DIE at offset 0x%llx has a " - "DW_FORM_ref_addr attribute with an inter-CU reference to " - "0x%llx, but inter-CU reference handling is turned off.\n", - filename_.c_str(), offset, target); -} - -DwarfCUToModule::DwarfCUToModule(FileContext *file_context, - LineToModuleHandler *line_reader, - WarningReporter *reporter) - : line_reader_(line_reader), - cu_context_(new CUContext(file_context, reporter)), - child_context_(new DIEContext()), - has_source_line_info_(false) { -} - -DwarfCUToModule::~DwarfCUToModule() { -} - -void DwarfCUToModule::ProcessAttributeSigned(enum DwarfAttribute attr, - enum DwarfForm form, - int64 data) { - switch (attr) { - case dwarf2reader::DW_AT_language: // source language of this CU - SetLanguage(static_cast(data)); - break; - default: - break; - } -} - -void DwarfCUToModule::ProcessAttributeUnsigned(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data) { - switch (attr) { - case dwarf2reader::DW_AT_stmt_list: // Line number information. - has_source_line_info_ = true; - source_line_offset_ = data; - break; - case dwarf2reader::DW_AT_language: // source language of this CU - SetLanguage(static_cast(data)); - break; - default: - break; - } -} - -void DwarfCUToModule::ProcessAttributeString(enum DwarfAttribute attr, - enum DwarfForm form, - const string &data) { - switch (attr) { - case dwarf2reader::DW_AT_name: - cu_context_->reporter->SetCUName(data); - break; - case dwarf2reader::DW_AT_comp_dir: - line_reader_->StartCompilationUnit(data); - break; - default: - break; - } -} - -bool DwarfCUToModule::EndAttributes() { - return true; -} - -dwarf2reader::DIEHandler *DwarfCUToModule::FindChildHandler( - uint64 offset, - enum DwarfTag tag) { - switch (tag) { - case dwarf2reader::DW_TAG_subprogram: - return new FuncHandler(cu_context_.get(), child_context_.get(), offset); - case dwarf2reader::DW_TAG_namespace: - case dwarf2reader::DW_TAG_class_type: - case dwarf2reader::DW_TAG_structure_type: - case dwarf2reader::DW_TAG_union_type: - return new NamedScopeHandler(cu_context_.get(), child_context_.get(), - offset); - default: - return NULL; - } -} - -void DwarfCUToModule::SetLanguage(DwarfLanguage language) { - switch (language) { - case dwarf2reader::DW_LANG_Java: - cu_context_->language = Language::Java; - break; - - // DWARF has no generic language code for assembly language; this is - // what the GNU toolchain uses. - case dwarf2reader::DW_LANG_Mips_Assembler: - cu_context_->language = Language::Assembler; - break; - - // C++ covers so many cases that it probably has some way to cope - // with whatever the other languages throw at us. So make it the - // default. - // - // Objective C and Objective C++ seem to create entries for - // methods whose DW_AT_name values are already fully-qualified: - // "-[Classname method:]". These appear at the top level. - // - // DWARF data for C should never include namespaces or functions - // nested in struct types, but if it ever does, then C++'s - // notation is probably not a bad choice for that. - default: - case dwarf2reader::DW_LANG_ObjC: - case dwarf2reader::DW_LANG_ObjC_plus_plus: - case dwarf2reader::DW_LANG_C: - case dwarf2reader::DW_LANG_C89: - case dwarf2reader::DW_LANG_C99: - case dwarf2reader::DW_LANG_C_plus_plus: - cu_context_->language = Language::CPlusPlus; - break; - } -} - -void DwarfCUToModule::ReadSourceLines(uint64 offset) { - const dwarf2reader::SectionMap §ion_map - = cu_context_->file_context->section_map(); - dwarf2reader::SectionMap::const_iterator map_entry - = section_map.find(".debug_line"); - // Mac OS X puts DWARF data in sections whose names begin with "__" - // instead of ".". - if (map_entry == section_map.end()) - map_entry = section_map.find("__debug_line"); - if (map_entry == section_map.end()) { - cu_context_->reporter->MissingSection(".debug_line"); - return; - } - const uint8_t *section_start = map_entry->second.first; - uint64 section_length = map_entry->second.second; - if (offset >= section_length) { - cu_context_->reporter->BadLineInfoOffset(offset); - return; - } - line_reader_->ReadProgram(section_start + offset, section_length - offset, - cu_context_->file_context->module_, &lines_); -} - -namespace { -// Return true if ADDRESS falls within the range of ITEM. -template -inline bool within(const T &item, Module::Address address) { - // Because Module::Address is unsigned, and unsigned arithmetic - // wraps around, this will be false if ADDRESS falls before the - // start of ITEM, or if it falls after ITEM's end. - return address - item.address < item.size; -} -} - -void DwarfCUToModule::AssignLinesToFunctions() { - vector *functions = &cu_context_->functions; - WarningReporter *reporter = cu_context_->reporter; - - // This would be simpler if we assumed that source line entries - // don't cross function boundaries. However, there's no real reason - // to assume that (say) a series of function definitions on the same - // line wouldn't get coalesced into one line number entry. The - // DWARF spec certainly makes no such promises. - // - // So treat the functions and lines as peers, and take the trouble - // to compute their ranges' intersections precisely. In any case, - // the hair here is a constant factor for performance; the - // complexity from here on out is linear. - - // Put both our functions and lines in order by address. - std::sort(functions->begin(), functions->end(), - Module::Function::CompareByAddress); - std::sort(lines_.begin(), lines_.end(), Module::Line::CompareByAddress); - - // The last line that we used any piece of. We use this only for - // generating warnings. - const Module::Line *last_line_used = NULL; - - // The last function and line we warned about --- so we can avoid - // doing so more than once. - const Module::Function *last_function_cited = NULL; - const Module::Line *last_line_cited = NULL; - - // Make a single pass through both vectors from lower to higher - // addresses, populating each Function's lines vector with lines - // from our lines_ vector that fall within the function's address - // range. - vector::iterator func_it = functions->begin(); - vector::const_iterator line_it = lines_.begin(); - - Module::Address current; - - // Pointers to the referents of func_it and line_it, or NULL if the - // iterator is at the end of the sequence. - Module::Function *func; - const Module::Line *line; - - // Start current at the beginning of the first line or function, - // whichever is earlier. - if (func_it != functions->end() && line_it != lines_.end()) { - func = *func_it; - line = &*line_it; - current = std::min(func->address, line->address); - } else if (line_it != lines_.end()) { - func = NULL; - line = &*line_it; - current = line->address; - } else if (func_it != functions->end()) { - func = *func_it; - line = NULL; - current = (*func_it)->address; - } else { - return; - } - - while (func || line) { - // This loop has two invariants that hold at the top. - // - // First, at least one of the iterators is not at the end of its - // sequence, and those that are not refer to the earliest - // function or line that contains or starts after CURRENT. - // - // Note that every byte is in one of four states: it is covered - // or not covered by a function, and, independently, it is - // covered or not covered by a line. - // - // The second invariant is that CURRENT refers to a byte whose - // state is different from its predecessor, or it refers to the - // first byte in the address space. In other words, CURRENT is - // always the address of a transition. - // - // Note that, although each iteration advances CURRENT from one - // transition address to the next in each iteration, it might - // not advance the iterators. Suppose we have a function that - // starts with a line, has a gap, and then a second line, and - // suppose that we enter an iteration with CURRENT at the end of - // the first line. The next transition address is the start of - // the second line, after the gap, so the iteration should - // advance CURRENT to that point. At the head of that iteration, - // the invariants require that the line iterator be pointing at - // the second line. But this is also true at the head of the - // next. And clearly, the iteration must not change the function - // iterator. So neither iterator moves. - - // Assert the first invariant (see above). - assert(!func || current < func->address || within(*func, current)); - assert(!line || current < line->address || within(*line, current)); - - // The next transition after CURRENT. - Module::Address next_transition; - - // Figure out which state we're in, add lines or warn, and compute - // the next transition address. - if (func && current >= func->address) { - if (line && current >= line->address) { - // Covered by both a line and a function. - Module::Address func_left = func->size - (current - func->address); - Module::Address line_left = line->size - (current - line->address); - // This may overflow, but things work out. - next_transition = current + std::min(func_left, line_left); - Module::Line l = *line; - l.address = current; - l.size = next_transition - current; - func->lines.push_back(l); - last_line_used = line; - } else { - // Covered by a function, but no line. - if (func != last_function_cited) { - reporter->UncoveredFunction(*func); - last_function_cited = func; - } - if (line && within(*func, line->address)) - next_transition = line->address; - else - // If this overflows, we'll catch it below. - next_transition = func->address + func->size; - } - } else { - if (line && current >= line->address) { - // Covered by a line, but no function. - // - // If GCC emits padding after one function to align the start - // of the next, then it will attribute the padding - // instructions to the last source line of function (to reduce - // the size of the line number info), but omit it from the - // DW_AT_{low,high}_pc range given in .debug_info (since it - // costs nothing to be precise there). If we did use at least - // some of the line we're about to skip, and it ends at the - // start of the next function, then assume this is what - // happened, and don't warn. - if (line != last_line_cited - && !(func - && line == last_line_used - && func->address - line->address == line->size)) { - reporter->UncoveredLine(*line); - last_line_cited = line; - } - if (func && within(*line, func->address)) - next_transition = func->address; - else - // If this overflows, we'll catch it below. - next_transition = line->address + line->size; - } else { - // Covered by neither a function nor a line. By the invariant, - // both func and line begin after CURRENT. The next transition - // is the start of the next function or next line, whichever - // is earliest. - assert(func || line); - if (func && line) - next_transition = std::min(func->address, line->address); - else if (func) - next_transition = func->address; - else - next_transition = line->address; - } - } - - // If a function or line abuts the end of the address space, then - // next_transition may end up being zero, in which case we've completed - // our pass. Handle that here, instead of trying to deal with it in - // each place we compute next_transition. - if (!next_transition) - break; - - // Advance iterators as needed. If lines overlap or functions overlap, - // then we could go around more than once. We don't worry too much - // about what result we produce in that case, just as long as we don't - // hang or crash. - while (func_it != functions->end() - && next_transition >= (*func_it)->address - && !within(**func_it, next_transition)) - func_it++; - func = (func_it != functions->end()) ? *func_it : NULL; - while (line_it != lines_.end() - && next_transition >= line_it->address - && !within(*line_it, next_transition)) - line_it++; - line = (line_it != lines_.end()) ? &*line_it : NULL; - - // We must make progress. - assert(next_transition > current); - current = next_transition; - } -} - -void DwarfCUToModule::Finish() { - // Assembly language files have no function data, and that gives us - // no place to store our line numbers (even though the GNU toolchain - // will happily produce source line info for assembly language - // files). To avoid spurious warnings about lines we can't assign - // to functions, skip CUs in languages that lack functions. - if (!cu_context_->language->HasFunctions()) - return; - - // Read source line info, if we have any. - if (has_source_line_info_) - ReadSourceLines(source_line_offset_); - - vector *functions = &cu_context_->functions; - - // Dole out lines to the appropriate functions. - AssignLinesToFunctions(); - - // Add our functions, which now have source lines assigned to them, - // to module_. - cu_context_->file_context->module_->AddFunctions(functions->begin(), - functions->end()); - - // Ownership of the function objects has shifted from cu_context to - // the Module. - functions->clear(); - - cu_context_->file_context->ClearSpecifications(); -} - -bool DwarfCUToModule::StartCompilationUnit(uint64 offset, - uint8 address_size, - uint8 offset_size, - uint64 cu_length, - uint8 dwarf_version) { - return dwarf_version >= 2; -} - -bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag) { - // We don't deal with partial compilation units (the only other tag - // likely to be used for root DIE). - return tag == dwarf2reader::DW_TAG_compile_unit; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.h deleted file mode 100644 index fca92710e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.h +++ /dev/null @@ -1,320 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// Add DWARF debugging information to a Breakpad symbol file. This -// file defines the DwarfCUToModule class, which accepts parsed DWARF -// data and populates a google_breakpad::Module with the results; the -// Module can then write its contents as a Breakpad symbol file. - -#ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__ -#define COMMON_LINUX_DWARF_CU_TO_MODULE_H__ - -#include - -#include - -#include "common/language.h" -#include "common/module.h" -#include "common/dwarf/bytereader.h" -#include "common/dwarf/dwarf2diehandler.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -using dwarf2reader::DwarfAttribute; -using dwarf2reader::DwarfForm; -using dwarf2reader::DwarfLanguage; -using dwarf2reader::DwarfTag; - -// Populate a google_breakpad::Module with DWARF debugging information. -// -// An instance of this class can be provided as a handler to a -// dwarf2reader::DIEDispatcher, which can in turn be a handler for a -// dwarf2reader::CompilationUnit DWARF parser. The handler uses the results -// of parsing to populate a google_breakpad::Module with source file, -// function, and source line information. -class DwarfCUToModule: public dwarf2reader::RootDIEHandler { - struct FilePrivate; - public: - // Information global to the DWARF-bearing file we are processing, - // for use by DwarfCUToModule. Each DwarfCUToModule instance deals - // with a single compilation unit within the file, but information - // global to the whole file is held here. The client is responsible - // for filling it in appropriately (except for the 'file_private' - // field, which the constructor and destructor take care of), and - // then providing it to the DwarfCUToModule instance for each - // compilation unit we process in that file. Set HANDLE_INTER_CU_REFS - // to true to handle debugging symbols with DW_FORM_ref_addr entries. - class FileContext { - public: - FileContext(const string &filename, - Module *module, - bool handle_inter_cu_refs); - ~FileContext(); - - // Add CONTENTS of size LENGTH to the section map as NAME. - void AddSectionToSectionMap(const string& name, - const uint8_t *contents, - uint64 length); - - // Clear the section map for testing. - void ClearSectionMapForTest(); - - const dwarf2reader::SectionMap& section_map() const; - - private: - friend class DwarfCUToModule; - - // Clears all the Specifications if HANDLE_INTER_CU_REFS_ is false. - void ClearSpecifications(); - - // Given an OFFSET and a CU that starts at COMPILATION_UNIT_START, returns - // true if this is an inter-compilation unit reference that is not being - // handled. - bool IsUnhandledInterCUReference(uint64 offset, - uint64 compilation_unit_start) const; - - // The name of this file, for use in error messages. - const string filename_; - - // A map of this file's sections, used for finding other DWARF - // sections that the .debug_info section may refer to. - dwarf2reader::SectionMap section_map_; - - // The Module to which we're contributing definitions. - Module *module_; - - // True if we are handling references between compilation units. - const bool handle_inter_cu_refs_; - - // Inter-compilation unit data used internally by the handlers. - scoped_ptr file_private_; - }; - - // An abstract base class for handlers that handle DWARF line data - // for DwarfCUToModule. DwarfCUToModule could certainly just use - // dwarf2reader::LineInfo itself directly, but decoupling things - // this way makes unit testing a little easier. - class LineToModuleHandler { - public: - LineToModuleHandler() { } - virtual ~LineToModuleHandler() { } - - // Called at the beginning of a new compilation unit, prior to calling - // ReadProgram(). compilation_dir will indicate the path that the - // current compilation unit was compiled in, consistent with the - // DW_AT_comp_dir DIE. - virtual void StartCompilationUnit(const string& compilation_dir) = 0; - - // Populate MODULE and LINES with source file names and code/line - // mappings, given a pointer to some DWARF line number data - // PROGRAM, and an overestimate of its size. Add no zero-length - // lines to LINES. - virtual void ReadProgram(const uint8_t *program, uint64 length, - Module *module, vector *lines) = 0; - }; - - // The interface DwarfCUToModule uses to report warnings. The member - // function definitions for this class write messages to stderr, but - // you can override them if you'd like to detect or report these - // conditions yourself. - class WarningReporter { - public: - // Warn about problems in the DWARF file FILENAME, in the - // compilation unit at OFFSET. - WarningReporter(const string &filename, uint64 cu_offset) - : filename_(filename), cu_offset_(cu_offset), printed_cu_header_(false), - printed_unpaired_header_(false), - uncovered_warnings_enabled_(false) { } - virtual ~WarningReporter() { } - - // Set the name of the compilation unit we're processing to NAME. - virtual void SetCUName(const string &name) { cu_name_ = name; } - - // Accessor and setter for uncovered_warnings_enabled_. - // UncoveredFunction and UncoveredLine only report a problem if that is - // true. By default, these warnings are disabled, because those - // conditions occur occasionally in healthy code. - virtual bool uncovered_warnings_enabled() const { - return uncovered_warnings_enabled_; - } - virtual void set_uncovered_warnings_enabled(bool value) { - uncovered_warnings_enabled_ = value; - } - - // A DW_AT_specification in the DIE at OFFSET refers to a DIE we - // haven't processed yet, or that wasn't marked as a declaration, - // at TARGET. - virtual void UnknownSpecification(uint64 offset, uint64 target); - - // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we - // haven't processed yet, or that wasn't marked as inline, at TARGET. - virtual void UnknownAbstractOrigin(uint64 offset, uint64 target); - - // We were unable to find the DWARF section named SECTION_NAME. - virtual void MissingSection(const string §ion_name); - - // The CU's DW_AT_stmt_list offset OFFSET is bogus. - virtual void BadLineInfoOffset(uint64 offset); - - // FUNCTION includes code covered by no line number data. - virtual void UncoveredFunction(const Module::Function &function); - - // Line number NUMBER in LINE_FILE, of length LENGTH, includes code - // covered by no function. - virtual void UncoveredLine(const Module::Line &line); - - // The DW_TAG_subprogram DIE at OFFSET has no name specified directly - // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin - // link. - virtual void UnnamedFunction(uint64 offset); - - // __cxa_demangle() failed to demangle INPUT. - virtual void DemangleError(const string &input, int error); - - // The DW_FORM_ref_addr at OFFSET to TARGET was not handled because - // FilePrivate did not retain the inter-CU specification data. - virtual void UnhandledInterCUReference(uint64 offset, uint64 target); - - uint64 cu_offset() const { - return cu_offset_; - } - - protected: - const string filename_; - const uint64 cu_offset_; - string cu_name_; - bool printed_cu_header_; - bool printed_unpaired_header_; - bool uncovered_warnings_enabled_; - - private: - // Print a per-CU heading, once. - void CUHeading(); - // Print an unpaired function/line heading, once. - void UncoveredHeading(); - }; - - // Create a DWARF debugging info handler for a compilation unit - // within FILE_CONTEXT. This uses information received from the - // dwarf2reader::CompilationUnit DWARF parser to populate - // FILE_CONTEXT->module. Use LINE_READER to handle the compilation - // unit's line number data. Use REPORTER to report problems with the - // data we find. - DwarfCUToModule(FileContext *file_context, - LineToModuleHandler *line_reader, - WarningReporter *reporter); - ~DwarfCUToModule(); - - void ProcessAttributeSigned(enum DwarfAttribute attr, - enum DwarfForm form, - int64 data); - void ProcessAttributeUnsigned(enum DwarfAttribute attr, - enum DwarfForm form, - uint64 data); - void ProcessAttributeString(enum DwarfAttribute attr, - enum DwarfForm form, - const string &data); - bool EndAttributes(); - DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag); - - // Assign all our source Lines to the Functions that cover their - // addresses, and then add them to module_. - void Finish(); - - bool StartCompilationUnit(uint64 offset, uint8 address_size, - uint8 offset_size, uint64 cu_length, - uint8 dwarf_version); - bool StartRootDIE(uint64 offset, enum DwarfTag tag); - - private: - // Used internally by the handler. Full definitions are in - // dwarf_cu_to_module.cc. - struct CUContext; - struct DIEContext; - struct Specification; - class GenericDIEHandler; - class FuncHandler; - class NamedScopeHandler; - - // A map from section offsets to specifications. - typedef map SpecificationByOffset; - - // Set this compilation unit's source language to LANGUAGE. - void SetLanguage(DwarfLanguage language); - - // Read source line information at OFFSET in the .debug_line - // section. Record source files in module_, but record source lines - // in lines_; we apportion them to functions in - // AssignLinesToFunctions. - void ReadSourceLines(uint64 offset); - - // Assign the lines in lines_ to the individual line lists of the - // functions in functions_. (DWARF line information maps an entire - // compilation unit at a time, and gives no indication of which - // lines belong to which functions, beyond their addresses.) - void AssignLinesToFunctions(); - - // The only reason cu_context_ and child_context_ are pointers is - // that we want to keep their definitions private to - // dwarf_cu_to_module.cc, instead of listing them all here. They are - // owned by this DwarfCUToModule: the constructor sets them, and the - // destructor deletes them. - - // The handler to use to handle line number data. - LineToModuleHandler *line_reader_; - - // This compilation unit's context. - scoped_ptr cu_context_; - - // A context for our children. - scoped_ptr child_context_; - - // True if this compilation unit has source line information. - bool has_source_line_info_; - - // The offset of this compilation unit's line number information in - // the .debug_line section. - uint64 source_line_offset_; - - // The line numbers we have seen thus far. We accumulate these here - // during parsing. Then, in Finish, we call AssignLinesToFunctions - // to dole them out to the appropriate functions. - vector lines_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_DWARF_CU_TO_MODULE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module_unittest.cc deleted file mode 100644 index 619e90a2e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module_unittest.cc +++ /dev/null @@ -1,1804 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf_cu_to_module.cc: Unit tests for google_breakpad::DwarfCUToModule. - -#include - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/dwarf_cu_to_module.h" -#include "common/using_std_string.h" - -using std::make_pair; -using std::vector; - -using dwarf2reader::DIEHandler; -using dwarf2reader::DwarfTag; -using dwarf2reader::DwarfAttribute; -using dwarf2reader::DwarfForm; -using dwarf2reader::DwarfInline; -using dwarf2reader::RootDIEHandler; -using google_breakpad::DwarfCUToModule; -using google_breakpad::Module; - -using ::testing::_; -using ::testing::AtMost; -using ::testing::Invoke; -using ::testing::Return; -using ::testing::Test; -using ::testing::TestWithParam; -using ::testing::Values; -using ::testing::ValuesIn; - -// Mock classes. - -class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler { - public: - MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir)); - MOCK_METHOD4(ReadProgram, void(const uint8_t *program, uint64 length, - Module *module, vector *lines)); -}; - -class MockWarningReporter: public DwarfCUToModule::WarningReporter { - public: - MockWarningReporter(const string &filename, uint64 cu_offset) - : DwarfCUToModule::WarningReporter(filename, cu_offset) { } - MOCK_METHOD1(SetCUName, void(const string &name)); - MOCK_METHOD2(UnknownSpecification, void(uint64 offset, uint64 target)); - MOCK_METHOD2(UnknownAbstractOrigin, void(uint64 offset, uint64 target)); - MOCK_METHOD1(MissingSection, void(const string §ion_name)); - MOCK_METHOD1(BadLineInfoOffset, void(uint64 offset)); - MOCK_METHOD1(UncoveredFunction, void(const Module::Function &function)); - MOCK_METHOD1(UncoveredLine, void(const Module::Line &line)); - MOCK_METHOD1(UnnamedFunction, void(uint64 offset)); - MOCK_METHOD2(DemangleError, void(const string &input, int error)); - MOCK_METHOD2(UnhandledInterCUReference, void(uint64 offset, uint64 target)); -}; - -// A fixture class including all the objects needed to handle a -// compilation unit, and their entourage. It includes member functions -// for doing common kinds of setup and tests. -class CUFixtureBase { - public: - // If we have: - // - // vector lines; - // AppendLinesFunctor appender(lines); - // - // then doing: - // - // appender(line_program, length, module, line_vector); - // - // will append lines to the end of line_vector. We can use this with - // MockLineToModuleHandler like this: - // - // MockLineToModuleHandler l2m; - // EXPECT_CALL(l2m, ReadProgram(_,_,_,_)) - // .WillOnce(DoAll(Invoke(appender), Return())); - // - // in which case calling l2m with some line vector will append lines. - class AppendLinesFunctor { - public: - explicit AppendLinesFunctor( - const vector *lines) : lines_(lines) { } - void operator()(const uint8_t *program, uint64 length, - Module *module, vector *lines) { - lines->insert(lines->end(), lines_->begin(), lines_->end()); - } - private: - const vector *lines_; - }; - - CUFixtureBase() - : module_("module-name", "module-os", "module-arch", "module-id"), - file_context_("dwarf-filename", &module_, true), - language_(dwarf2reader::DW_LANG_none), - language_signed_(false), - appender_(&lines_), - reporter_("dwarf-filename", 0xcf8f9bb6443d29b5LL), - root_handler_(&file_context_, &line_reader_, &reporter_), - functions_filled_(false) { - // By default, expect no warnings to be reported, and expect the - // compilation unit's name to be provided. The test can override - // these expectations. - EXPECT_CALL(reporter_, SetCUName("compilation-unit-name")).Times(1); - EXPECT_CALL(reporter_, UnknownSpecification(_, _)).Times(0); - EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, _)).Times(0); - EXPECT_CALL(reporter_, MissingSection(_)).Times(0); - EXPECT_CALL(reporter_, BadLineInfoOffset(_)).Times(0); - EXPECT_CALL(reporter_, UncoveredFunction(_)).Times(0); - EXPECT_CALL(reporter_, UncoveredLine(_)).Times(0); - EXPECT_CALL(reporter_, UnnamedFunction(_)).Times(0); - EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(0); - - // By default, expect the line program reader not to be invoked. We - // may override this in StartCU. - EXPECT_CALL(line_reader_, StartCompilationUnit(_)).Times(0); - EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_)).Times(0); - - // The handler will consult this section map to decide what to - // pass to our line reader. - file_context_.AddSectionToSectionMap(".debug_line", - dummy_line_program_, - dummy_line_size_); - } - - // Add a line with the given address, size, filename, and line - // number to the end of the statement list the handler will receive - // when it invokes its LineToModuleHandler. Call this before calling - // StartCU. - void PushLine(Module::Address address, Module::Address size, - const string &filename, int line_number); - - // Use LANGUAGE for the compilation unit. More precisely, arrange - // for StartCU to pass the compilation unit's root DIE a - // DW_AT_language attribute whose value is LANGUAGE. - void SetLanguage(dwarf2reader::DwarfLanguage language) { - language_ = language; - } - - // If SIGNED true, have StartCU report DW_AT_language as a signed - // attribute; if false, have it report it as unsigned. - void SetLanguageSigned(bool is_signed) { language_signed_ = is_signed; } - - // Call the handler this.root_handler_'s StartCompilationUnit and - // StartRootDIE member functions, passing it appropriate attributes as - // determined by prior calls to PushLine and SetLanguage. Leave - // this.root_handler_ ready to hear about children: call - // this.root_handler_.EndAttributes, but not this.root_handler_.Finish. - void StartCU(); - - // Have HANDLER process some strange attribute/form/value triples. - void ProcessStrangeAttributes(dwarf2reader::DIEHandler *handler); - - // Start a child DIE of PARENT with the given tag and name. Leave - // the handler ready to hear about children: call EndAttributes, but - // not Finish. - DIEHandler *StartNamedDIE(DIEHandler *parent, DwarfTag tag, - const string &name); - - // Start a child DIE of PARENT with the given tag and a - // DW_AT_specification attribute whose value is SPECIFICATION. Leave - // the handler ready to hear about children: call EndAttributes, but - // not Finish. If NAME is non-zero, use it as the DW_AT_name - // attribute. - DIEHandler *StartSpecifiedDIE(DIEHandler *parent, DwarfTag tag, - uint64 specification, const char *name = NULL); - - // Define a function as a child of PARENT with the given name, address, and - // size. If high_pc_form is DW_FORM_addr then the DW_AT_high_pc attribute - // will be written as an address; otherwise it will be written as the - // function's size. Call EndAttributes and Finish; one cannot define - // children of the defined function's DIE. - void DefineFunction(DIEHandler *parent, const string &name, - Module::Address address, Module::Address size, - const char* mangled_name, - DwarfForm high_pc_form = dwarf2reader::DW_FORM_addr); - - // Create a declaration DIE as a child of PARENT with the given - // offset, tag and name. If NAME is the empty string, don't provide - // a DW_AT_name attribute. Call EndAttributes and Finish. - void DeclarationDIE(DIEHandler *parent, uint64 offset, - DwarfTag tag, const string &name, - const string &mangled_name); - - // Create a definition DIE as a child of PARENT with the given tag - // that refers to the declaration DIE at offset SPECIFICATION as its - // specification. If NAME is non-empty, pass it as the DW_AT_name - // attribute. If SIZE is non-zero, record ADDRESS and SIZE as - // low_pc/high_pc attributes. - void DefinitionDIE(DIEHandler *parent, DwarfTag tag, - uint64 specification, const string &name, - Module::Address address = 0, Module::Address size = 0); - - // Create an inline DW_TAG_subprogram DIE as a child of PARENT. If - // SPECIFICATION is non-zero, then the DIE refers to the declaration DIE at - // offset SPECIFICATION as its specification. If Name is non-empty, pass it - // as the DW_AT_name attribute. - void AbstractInstanceDIE(DIEHandler *parent, uint64 offset, - DwarfInline type, uint64 specification, - const string &name, - DwarfForm form = dwarf2reader::DW_FORM_data1); - - // Create a DW_TAG_subprogram DIE as a child of PARENT that refers to - // ORIGIN in its DW_AT_abstract_origin attribute. If NAME is the empty - // string, don't provide a DW_AT_name attribute. - void DefineInlineInstanceDIE(DIEHandler *parent, const string &name, - uint64 origin, Module::Address address, - Module::Address size); - - // The following Test* functions should be called after calling - // this.root_handler_.Finish. After that point, no further calls - // should be made on the handler. - - // Test that the number of functions defined in the module this.module_ is - // equal to EXPECTED. - void TestFunctionCount(size_t expected); - - // Test that the I'th function (ordered by address) in the module - // this.module_ has the given name, address, and size, and that its - // parameter size is zero. - void TestFunction(int i, const string &name, - Module::Address address, Module::Address size); - - // Test that the number of source lines owned by the I'th function - // in the module this.module_ is equal to EXPECTED. - void TestLineCount(int i, size_t expected); - - // Test that the J'th line (ordered by address) of the I'th function - // (again, by address) has the given address, size, filename, and - // line number. - void TestLine(int i, int j, Module::Address address, Module::Address size, - const string &filename, int number); - - // Actual objects under test. - Module module_; - DwarfCUToModule::FileContext file_context_; - - // If this is not DW_LANG_none, we'll pass it as a DW_AT_language - // attribute to the compilation unit. This defaults to DW_LANG_none. - dwarf2reader::DwarfLanguage language_; - - // If this is true, report DW_AT_language as a signed value; if false, - // report it as an unsigned value. - bool language_signed_; - - // If this is not empty, we'll give the CU a DW_AT_comp_dir attribute that - // indicates the path that this compilation unit was compiled in. - string compilation_dir_; - - // If this is not empty, we'll give the CU a DW_AT_stmt_list - // attribute that, when passed to line_reader_, adds these lines to the - // provided lines array. - vector lines_; - - // Mock line program reader. - MockLineToModuleHandler line_reader_; - AppendLinesFunctor appender_; - static const uint8_t dummy_line_program_[]; - static const size_t dummy_line_size_; - - MockWarningReporter reporter_; - DwarfCUToModule root_handler_; - - private: - // Fill functions_, if we haven't already. - void FillFunctions(); - - // If functions_filled_ is true, this is a table of functions we've - // extracted from module_, sorted by address. - vector functions_; - // True if we have filled the above vector with this.module_'s function list. - bool functions_filled_; -}; - -const uint8_t CUFixtureBase::dummy_line_program_[] = "lots of fun data"; -const size_t CUFixtureBase::dummy_line_size_ = - sizeof(CUFixtureBase::dummy_line_program_); - -void CUFixtureBase::PushLine(Module::Address address, Module::Address size, - const string &filename, int line_number) { - Module::Line l; - l.address = address; - l.size = size; - l.file = module_.FindFile(filename); - l.number = line_number; - lines_.push_back(l); -} - -void CUFixtureBase::StartCU() { - if (!compilation_dir_.empty()) - EXPECT_CALL(line_reader_, - StartCompilationUnit(compilation_dir_)).Times(1); - - // If we have lines, make the line reader expect to be invoked at - // most once. (Hey, if the handler can pass its tests without - // bothering to read the line number data, that's great.) - // Have it add the lines passed to PushLine. Otherwise, leave the - // initial expectation (no calls) in force. - if (!lines_.empty()) - EXPECT_CALL(line_reader_, - ReadProgram(&dummy_line_program_[0], dummy_line_size_, - &module_, _)) - .Times(AtMost(1)) - .WillOnce(DoAll(Invoke(appender_), Return())); - - ASSERT_TRUE(root_handler_ - .StartCompilationUnit(0x51182ec307610b51ULL, 0x81, 0x44, - 0x4241b4f33720dd5cULL, 3)); - { - ASSERT_TRUE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL, - dwarf2reader::DW_TAG_compile_unit)); - } - root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - "compilation-unit-name"); - if (!compilation_dir_.empty()) - root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_comp_dir, - dwarf2reader::DW_FORM_strp, - compilation_dir_); - if (!lines_.empty()) - root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list, - dwarf2reader::DW_FORM_ref4, - 0); - if (language_ != dwarf2reader::DW_LANG_none) { - if (language_signed_) - root_handler_.ProcessAttributeSigned(dwarf2reader::DW_AT_language, - dwarf2reader::DW_FORM_sdata, - language_); - else - root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_language, - dwarf2reader::DW_FORM_udata, - language_); - } - ASSERT_TRUE(root_handler_.EndAttributes()); -} - -void CUFixtureBase::ProcessStrangeAttributes( - dwarf2reader::DIEHandler *handler) { - handler->ProcessAttributeUnsigned((DwarfAttribute) 0xf560dead, - (DwarfForm) 0x4106e4db, - 0xa592571997facda1ULL); - handler->ProcessAttributeSigned((DwarfAttribute) 0x85380095, - (DwarfForm) 0x0f16fe87, - 0x12602a4e3bf1f446LL); - handler->ProcessAttributeReference((DwarfAttribute) 0xf7f7480f, - (DwarfForm) 0x829e038a, - 0x50fddef44734fdecULL); - static const uint8_t buffer[10] = "frobynode"; - handler->ProcessAttributeBuffer((DwarfAttribute) 0xa55ffb51, - (DwarfForm) 0x2f43b041, - buffer, sizeof(buffer)); - handler->ProcessAttributeString((DwarfAttribute) 0x2f43b041, - (DwarfForm) 0x895ffa23, - "strange string"); -} - -DIEHandler *CUFixtureBase::StartNamedDIE(DIEHandler *parent, - DwarfTag tag, - const string &name) { - dwarf2reader::DIEHandler *handler - = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag); - if (!handler) - return NULL; - handler->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - ProcessStrangeAttributes(handler); - if (!handler->EndAttributes()) { - handler->Finish(); - delete handler; - return NULL; - } - - return handler; -} - -DIEHandler *CUFixtureBase::StartSpecifiedDIE(DIEHandler *parent, - DwarfTag tag, - uint64 specification, - const char *name) { - dwarf2reader::DIEHandler *handler - = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag); - if (!handler) - return NULL; - if (name) - handler->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - handler->ProcessAttributeReference(dwarf2reader::DW_AT_specification, - dwarf2reader::DW_FORM_ref4, - specification); - if (!handler->EndAttributes()) { - handler->Finish(); - delete handler; - return NULL; - } - - return handler; -} - -void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent, - const string &name, Module::Address address, - Module::Address size, - const char* mangled_name, - DwarfForm high_pc_form) { - dwarf2reader::DIEHandler *func - = parent->FindChildHandler(0xe34797c7e68590a8LL, - dwarf2reader::DW_TAG_subprogram); - ASSERT_TRUE(func != NULL); - func->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc, - dwarf2reader::DW_FORM_addr, - address); - - Module::Address high_pc = size; - if (high_pc_form == dwarf2reader::DW_FORM_addr) { - high_pc += address; - } - func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc, - high_pc_form, - high_pc); - - if (mangled_name) - func->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name, - dwarf2reader::DW_FORM_strp, - mangled_name); - - ProcessStrangeAttributes(func); - EXPECT_TRUE(func->EndAttributes()); - func->Finish(); - delete func; -} - -void CUFixtureBase::DeclarationDIE(DIEHandler *parent, uint64 offset, - DwarfTag tag, - const string &name, - const string &mangled_name) { - dwarf2reader::DIEHandler *die = parent->FindChildHandler(offset, tag); - ASSERT_TRUE(die != NULL); - if (!name.empty()) - die->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - if (!mangled_name.empty()) - die->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name, - dwarf2reader::DW_FORM_strp, - mangled_name); - - die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_declaration, - dwarf2reader::DW_FORM_flag, - 1); - EXPECT_TRUE(die->EndAttributes()); - die->Finish(); - delete die; -} - -void CUFixtureBase::DefinitionDIE(DIEHandler *parent, - DwarfTag tag, - uint64 specification, - const string &name, - Module::Address address, - Module::Address size) { - dwarf2reader::DIEHandler *die - = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag); - ASSERT_TRUE(die != NULL); - die->ProcessAttributeReference(dwarf2reader::DW_AT_specification, - dwarf2reader::DW_FORM_ref4, - specification); - if (!name.empty()) - die->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - if (size) { - die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc, - dwarf2reader::DW_FORM_addr, - address); - die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc, - dwarf2reader::DW_FORM_addr, - address + size); - } - EXPECT_TRUE(die->EndAttributes()); - die->Finish(); - delete die; -} - -void CUFixtureBase::AbstractInstanceDIE(DIEHandler *parent, - uint64 offset, - DwarfInline type, - uint64 specification, - const string &name, - DwarfForm form) { - dwarf2reader::DIEHandler *die - = parent->FindChildHandler(offset, dwarf2reader::DW_TAG_subprogram); - ASSERT_TRUE(die != NULL); - if (specification != 0ULL) - die->ProcessAttributeReference(dwarf2reader::DW_AT_specification, - dwarf2reader::DW_FORM_ref4, - specification); - if (form == dwarf2reader::DW_FORM_sdata) { - die->ProcessAttributeSigned(dwarf2reader::DW_AT_inline, form, type); - } else { - die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_inline, form, type); - } - if (!name.empty()) - die->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - - EXPECT_TRUE(die->EndAttributes()); - die->Finish(); - delete die; -} - -void CUFixtureBase::DefineInlineInstanceDIE(DIEHandler *parent, - const string &name, - uint64 origin, - Module::Address address, - Module::Address size) { - dwarf2reader::DIEHandler *func - = parent->FindChildHandler(0x11c70f94c6e87ccdLL, - dwarf2reader::DW_TAG_subprogram); - ASSERT_TRUE(func != NULL); - if (!name.empty()) { - func->ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - name); - } - func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc, - dwarf2reader::DW_FORM_addr, - address); - func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc, - dwarf2reader::DW_FORM_addr, - address + size); - func->ProcessAttributeReference(dwarf2reader::DW_AT_abstract_origin, - dwarf2reader::DW_FORM_ref4, - origin); - ProcessStrangeAttributes(func); - EXPECT_TRUE(func->EndAttributes()); - func->Finish(); - delete func; -} - -void CUFixtureBase::FillFunctions() { - if (functions_filled_) - return; - module_.GetFunctions(&functions_, functions_.end()); - sort(functions_.begin(), functions_.end(), - Module::Function::CompareByAddress); - functions_filled_ = true; -} - -void CUFixtureBase::TestFunctionCount(size_t expected) { - FillFunctions(); - ASSERT_EQ(expected, functions_.size()); -} - -void CUFixtureBase::TestFunction(int i, const string &name, - Module::Address address, - Module::Address size) { - FillFunctions(); - ASSERT_LT((size_t) i, functions_.size()); - - Module::Function *function = functions_[i]; - EXPECT_EQ(name, function->name); - EXPECT_EQ(address, function->address); - EXPECT_EQ(size, function->size); - EXPECT_EQ(0U, function->parameter_size); -} - -void CUFixtureBase::TestLineCount(int i, size_t expected) { - FillFunctions(); - ASSERT_LT((size_t) i, functions_.size()); - - ASSERT_EQ(expected, functions_[i]->lines.size()); -} - -void CUFixtureBase::TestLine(int i, int j, - Module::Address address, Module::Address size, - const string &filename, int number) { - FillFunctions(); - ASSERT_LT((size_t) i, functions_.size()); - ASSERT_LT((size_t) j, functions_[i]->lines.size()); - - Module::Line *line = &functions_[i]->lines[j]; - EXPECT_EQ(address, line->address); - EXPECT_EQ(size, line->size); - EXPECT_EQ(filename, line->file->name.c_str()); - EXPECT_EQ(number, line->number); -} - -// Include caller locations for our test subroutines. -#define TRACE(call) do { SCOPED_TRACE("called from here"); call; } while (0) -#define PushLine(a,b,c,d) TRACE(PushLine((a),(b),(c),(d))) -#define SetLanguage(a) TRACE(SetLanguage(a)) -#define StartCU() TRACE(StartCU()) -#define DefineFunction(a,b,c,d,e) TRACE(DefineFunction((a),(b),(c),(d),(e))) -// (DefineFunction) instead of DefineFunction to avoid macro expansion. -#define DefineFunction6(a,b,c,d,e,f) \ - TRACE((DefineFunction)((a),(b),(c),(d),(e),(f))) -#define DeclarationDIE(a,b,c,d,e) TRACE(DeclarationDIE((a),(b),(c),(d),(e))) -#define DefinitionDIE(a,b,c,d,e,f) \ - TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f))) -#define TestFunctionCount(a) TRACE(TestFunctionCount(a)) -#define TestFunction(a,b,c,d) TRACE(TestFunction((a),(b),(c),(d))) -#define TestLineCount(a,b) TRACE(TestLineCount((a),(b))) -#define TestLine(a,b,c,d,e,f) TRACE(TestLine((a),(b),(c),(d),(e),(f))) - -class SimpleCU: public CUFixtureBase, public Test { -}; - -TEST_F(SimpleCU, CompilationDir) { - compilation_dir_ = "/src/build/"; - - StartCU(); - root_handler_.Finish(); -} - -TEST_F(SimpleCU, OneFunc) { - PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772); - - StartCU(); - DefineFunction(&root_handler_, "function1", - 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL); - TestLineCount(0, 1); - TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", - 246571772); -} - -// As above, only DW_AT_high_pc is a length rather than an address. -TEST_F(SimpleCU, OneFuncHighPcIsLength) { - PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772); - - StartCU(); - DefineFunction6(&root_handler_, "function1", - 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL, - dwarf2reader::DW_FORM_udata); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL); - TestLineCount(0, 1); - TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", - 246571772); -} - -TEST_F(SimpleCU, MangledName) { - PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772); - - StartCU(); - DefineFunction(&root_handler_, "function1", - 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "_ZN1n1fEi"); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "n::f(int)", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL); -} - -TEST_F(SimpleCU, IrrelevantRootChildren) { - StartCU(); - EXPECT_FALSE(root_handler_ - .FindChildHandler(0x7db32bff4e2dcfb1ULL, - dwarf2reader::DW_TAG_lexical_block)); -} - -TEST_F(SimpleCU, IrrelevantNamedScopeChildren) { - StartCU(); - DIEHandler *class_A_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A"); - EXPECT_TRUE(class_A_handler != NULL); - EXPECT_FALSE(class_A_handler - ->FindChildHandler(0x02e55999b865e4e9ULL, - dwarf2reader::DW_TAG_lexical_block)); - delete class_A_handler; -} - -// Verify that FileContexts can safely be deleted unused. -TEST_F(SimpleCU, UnusedFileContext) { - Module m("module-name", "module-os", "module-arch", "module-id"); - DwarfCUToModule::FileContext fc("dwarf-filename", &m, true); - - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); -} - -TEST_F(SimpleCU, InlineFunction) { - PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); - - StartCU(); - AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL, - dwarf2reader::DW_INL_inlined, 0, "inline-name"); - DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL, - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "inline-name", - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); -} - -TEST_F(SimpleCU, InlineFunctionSignedAttribute) { - PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); - - StartCU(); - AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL, - dwarf2reader::DW_INL_inlined, 0, "inline-name", - dwarf2reader::DW_FORM_sdata); - DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL, - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "inline-name", - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); -} - -// Any DIE with an DW_AT_inline attribute can be cited by -// DW_AT_abstract_origin attributes --- even if the value of the -// DW_AT_inline attribute is DW_INL_not_inlined. -TEST_F(SimpleCU, AbstractOriginNotInlined) { - PushLine(0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL, "line-file", 6111581); - - StartCU(); - AbstractInstanceDIE(&root_handler_, 0x93e9cdad52826b39ULL, - dwarf2reader::DW_INL_not_inlined, 0, "abstract-instance"); - DefineInlineInstanceDIE(&root_handler_, "", 0x93e9cdad52826b39ULL, - 0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "abstract-instance", - 0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL); -} - -TEST_F(SimpleCU, UnknownAbstractOrigin) { - EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, 1ULL)).WillOnce(Return()); - EXPECT_CALL(reporter_, UnnamedFunction(0x11c70f94c6e87ccdLL)) - .WillOnce(Return()); - PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); - - StartCU(); - AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL, - dwarf2reader::DW_INL_inlined, 0, "inline-name"); - DefineInlineInstanceDIE(&root_handler_, "", 1ULL, - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "", - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); -} - -TEST_F(SimpleCU, UnnamedFunction) { - EXPECT_CALL(reporter_, UnnamedFunction(0xe34797c7e68590a8LL)) - .WillOnce(Return()); - PushLine(0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, "line-file", 14044850); - - StartCU(); - DefineFunction(&root_handler_, "", - 0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, NULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "", - 0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL); -} - -// An address range. -struct Range { - Module::Address start, end; -}; - -// Test data for pairing functions and lines. -struct Situation { - // Two function intervals, and two line intervals. - Range functions[2], lines[2]; - - // The number of lines we expect to be assigned to each of the - // functions, and the address ranges. - int paired_count[2]; - Range paired[2][2]; - - // The number of functions that are not entirely covered by lines, - // and vice versa. - int uncovered_functions, uncovered_lines; -}; - -#define PAIRING(func1_start, func1_end, func2_start, func2_end, \ - line1_start, line1_end, line2_start, line2_end, \ - func1_num_lines, func2_num_lines, \ - func1_line1_start, func1_line1_end, \ - func1_line2_start, func1_line2_end, \ - func2_line1_start, func2_line1_end, \ - func2_line2_start, func2_line2_end, \ - uncovered_functions, uncovered_lines) \ - { { { func1_start, func1_end }, { func2_start, func2_end } }, \ - { { line1_start, line1_end }, { line2_start, line2_end } }, \ - { func1_num_lines, func2_num_lines }, \ - { { { func1_line1_start, func1_line1_end }, \ - { func1_line2_start, func1_line2_end } }, \ - { { func2_line1_start, func2_line1_end }, \ - { func2_line2_start, func2_line2_end } } }, \ - uncovered_functions, uncovered_lines }, - -Situation situations[] = { -#include "common/testdata/func-line-pairing.h" -}; - -#undef PAIRING - -class FuncLinePairing: public CUFixtureBase, - public TestWithParam { }; - -INSTANTIATE_TEST_CASE_P(AllSituations, FuncLinePairing, - ValuesIn(situations)); - -TEST_P(FuncLinePairing, Pairing) { - const Situation &s = GetParam(); - PushLine(s.lines[0].start, - s.lines[0].end - s.lines[0].start, - "line-file", 67636963); - PushLine(s.lines[1].start, - s.lines[1].end - s.lines[1].start, - "line-file", 67636963); - if (s.uncovered_functions) - EXPECT_CALL(reporter_, UncoveredFunction(_)) - .Times(s.uncovered_functions) - .WillRepeatedly(Return()); - if (s.uncovered_lines) - EXPECT_CALL(reporter_, UncoveredLine(_)) - .Times(s.uncovered_lines) - .WillRepeatedly(Return()); - - StartCU(); - DefineFunction(&root_handler_, "function1", - s.functions[0].start, - s.functions[0].end - s.functions[0].start, NULL); - DefineFunction(&root_handler_, "function2", - s.functions[1].start, - s.functions[1].end - s.functions[1].start, NULL); - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "function1", - s.functions[0].start, - s.functions[0].end - s.functions[0].start); - TestLineCount(0, s.paired_count[0]); - for (int i = 0; i < s.paired_count[0]; i++) - TestLine(0, i, s.paired[0][i].start, - s.paired[0][i].end - s.paired[0][i].start, - "line-file", 67636963); - TestFunction(1, "function2", - s.functions[1].start, - s.functions[1].end - s.functions[1].start); - TestLineCount(1, s.paired_count[1]); - for (int i = 0; i < s.paired_count[1]; i++) - TestLine(1, i, s.paired[1][i].start, - s.paired[1][i].end - s.paired[1][i].start, - "line-file", 67636963); -} - -TEST_F(FuncLinePairing, EmptyCU) { - StartCU(); - root_handler_.Finish(); - - TestFunctionCount(0); -} - -TEST_F(FuncLinePairing, LinesNoFuncs) { - PushLine(40, 2, "line-file", 82485646); - EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return()); - - StartCU(); - root_handler_.Finish(); - - TestFunctionCount(0); -} - -TEST_F(FuncLinePairing, FuncsNoLines) { - EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return()); - - StartCU(); - DefineFunction(&root_handler_, "function1", 0x127da12ffcf5c51fULL, 0x1000U, - NULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "function1", 0x127da12ffcf5c51fULL, 0x1000U); -} - -TEST_F(FuncLinePairing, GapThenFunction) { - PushLine(20, 2, "line-file-2", 174314698); - PushLine(10, 2, "line-file-1", 263008005); - - StartCU(); - DefineFunction(&root_handler_, "function1", 10, 2, NULL); - DefineFunction(&root_handler_, "function2", 20, 2, NULL); - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "function1", 10, 2); - TestLineCount(0, 1); - TestLine(0, 0, 10, 2, "line-file-1", 263008005); - TestFunction(1, "function2", 20, 2); - TestLineCount(1, 1); - TestLine(1, 0, 20, 2, "line-file-2", 174314698); -} - -// If GCC emits padding after one function to align the start of -// the next, then it will attribute the padding instructions to -// the last source line of function (to reduce the size of the -// line number info), but omit it from the DW_AT_{low,high}_pc -// range given in .debug_info (since it costs nothing to be -// precise there). If we did use at least some of the line -// we're about to skip, then assume this is what happened, and -// don't warn. -TEST_F(FuncLinePairing, GCCAlignmentStretch) { - PushLine(10, 10, "line-file", 63351048); - PushLine(20, 10, "line-file", 61661044); - - StartCU(); - DefineFunction(&root_handler_, "function1", 10, 5, NULL); - // five-byte gap between functions, covered by line 63351048. - // This should not elicit a warning. - DefineFunction(&root_handler_, "function2", 20, 10, NULL); - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "function1", 10, 5); - TestLineCount(0, 1); - TestLine(0, 0, 10, 5, "line-file", 63351048); - TestFunction(1, "function2", 20, 10); - TestLineCount(1, 1); - TestLine(1, 0, 20, 10, "line-file", 61661044); -} - -// Unfortunately, neither the DWARF parser's handler interface nor the -// DIEHandler interface is capable of expressing a function that abuts -// the end of the address space: the high_pc value looks like zero. - -TEST_F(FuncLinePairing, LineAtEndOfAddressSpace) { - PushLine(0xfffffffffffffff0ULL, 16, "line-file", 63351048); - EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return()); - - StartCU(); - DefineFunction(&root_handler_, "function1", 0xfffffffffffffff0ULL, 6, NULL); - DefineFunction(&root_handler_, "function2", 0xfffffffffffffffaULL, 5, NULL); - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "function1", 0xfffffffffffffff0ULL, 6); - TestLineCount(0, 1); - TestLine(0, 0, 0xfffffffffffffff0ULL, 6, "line-file", 63351048); - TestFunction(1, "function2", 0xfffffffffffffffaULL, 5); - TestLineCount(1, 1); - TestLine(1, 0, 0xfffffffffffffffaULL, 5, "line-file", 63351048); -} - -// A function with more than one uncovered area should only be warned -// about once. -TEST_F(FuncLinePairing, WarnOnceFunc) { - PushLine(20, 1, "line-file-2", 262951329); - PushLine(11, 1, "line-file-1", 219964021); - EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return()); - - StartCU(); - DefineFunction(&root_handler_, "function", 10, 11, NULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "function", 10, 11); - TestLineCount(0, 2); - TestLine(0, 0, 11, 1, "line-file-1", 219964021); - TestLine(0, 1, 20, 1, "line-file-2", 262951329); -} - -// A line with more than one uncovered area should only be warned -// about once. -TEST_F(FuncLinePairing, WarnOnceLine) { - PushLine(10, 20, "filename1", 118581871); - EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return()); - - StartCU(); - DefineFunction(&root_handler_, "function1", 11, 1, NULL); - DefineFunction(&root_handler_, "function2", 13, 1, NULL); - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "function1", 11, 1); - TestLineCount(0, 1); - TestLine(0, 0, 11, 1, "filename1", 118581871); - TestFunction(1, "function2", 13, 1); - TestLineCount(1, 1); - TestLine(1, 0, 13, 1, "filename1", 118581871); -} - -class CXXQualifiedNames: public CUFixtureBase, - public TestWithParam { }; - -INSTANTIATE_TEST_CASE_P(VersusEnclosures, CXXQualifiedNames, - Values(dwarf2reader::DW_TAG_class_type, - dwarf2reader::DW_TAG_structure_type, - dwarf2reader::DW_TAG_union_type, - dwarf2reader::DW_TAG_namespace)); - -TEST_P(CXXQualifiedNames, TwoFunctions) { - DwarfTag tag = GetParam(); - - SetLanguage(dwarf2reader::DW_LANG_C_plus_plus); - PushLine(10, 1, "filename1", 69819327); - PushLine(20, 1, "filename2", 95115701); - - StartCU(); - DIEHandler *enclosure_handler = StartNamedDIE(&root_handler_, tag, - "Enclosure"); - EXPECT_TRUE(enclosure_handler != NULL); - DefineFunction(enclosure_handler, "func_B", 10, 1, NULL); - DefineFunction(enclosure_handler, "func_C", 20, 1, NULL); - enclosure_handler->Finish(); - delete enclosure_handler; - root_handler_.Finish(); - - TestFunctionCount(2); - TestFunction(0, "Enclosure::func_B", 10, 1); - TestFunction(1, "Enclosure::func_C", 20, 1); -} - -TEST_P(CXXQualifiedNames, FuncInEnclosureInNamespace) { - DwarfTag tag = GetParam(); - - SetLanguage(dwarf2reader::DW_LANG_C_plus_plus); - PushLine(10, 1, "line-file", 69819327); - - StartCU(); - DIEHandler *namespace_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - "Namespace"); - EXPECT_TRUE(namespace_handler != NULL); - DIEHandler *enclosure_handler = StartNamedDIE(namespace_handler, tag, - "Enclosure"); - EXPECT_TRUE(enclosure_handler != NULL); - DefineFunction(enclosure_handler, "function", 10, 1, NULL); - enclosure_handler->Finish(); - delete enclosure_handler; - namespace_handler->Finish(); - delete namespace_handler; - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "Namespace::Enclosure::function", 10, 1); -} - -TEST_F(CXXQualifiedNames, FunctionInClassInStructInNamespace) { - SetLanguage(dwarf2reader::DW_LANG_C_plus_plus); - PushLine(10, 1, "filename1", 69819327); - - StartCU(); - DIEHandler *namespace_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - "namespace_A"); - EXPECT_TRUE(namespace_handler != NULL); - DIEHandler *struct_handler - = StartNamedDIE(namespace_handler, dwarf2reader::DW_TAG_structure_type, - "struct_B"); - EXPECT_TRUE(struct_handler != NULL); - DIEHandler *class_handler - = StartNamedDIE(struct_handler, dwarf2reader::DW_TAG_class_type, - "class_C"); - DefineFunction(class_handler, "function_D", 10, 1, NULL); - class_handler->Finish(); - delete class_handler; - struct_handler->Finish(); - delete struct_handler; - namespace_handler->Finish(); - delete namespace_handler; - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "namespace_A::struct_B::class_C::function_D", 10, 1); -} - -struct LanguageAndQualifiedName { - dwarf2reader::DwarfLanguage language; - const char *name; -}; - -const LanguageAndQualifiedName LanguageAndQualifiedNameCases[] = { - { dwarf2reader::DW_LANG_none, "class_A::function_B" }, - { dwarf2reader::DW_LANG_C, "class_A::function_B" }, - { dwarf2reader::DW_LANG_C89, "class_A::function_B" }, - { dwarf2reader::DW_LANG_C99, "class_A::function_B" }, - { dwarf2reader::DW_LANG_C_plus_plus, "class_A::function_B" }, - { dwarf2reader::DW_LANG_Java, "class_A.function_B" }, - { dwarf2reader::DW_LANG_Cobol74, "class_A::function_B" }, - { dwarf2reader::DW_LANG_Mips_Assembler, NULL } -}; - -class QualifiedForLanguage - : public CUFixtureBase, - public TestWithParam { }; - -INSTANTIATE_TEST_CASE_P(LanguageAndQualifiedName, QualifiedForLanguage, - ValuesIn(LanguageAndQualifiedNameCases)); - -TEST_P(QualifiedForLanguage, MemberFunction) { - const LanguageAndQualifiedName ¶m = GetParam(); - - PushLine(10, 1, "line-file", 212966758); - SetLanguage(param.language); - - StartCU(); - DIEHandler *class_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - "class_A"); - DefineFunction(class_handler, "function_B", 10, 1, NULL); - class_handler->Finish(); - delete class_handler; - root_handler_.Finish(); - - if (param.name) { - TestFunctionCount(1); - TestFunction(0, param.name, 10, 1); - } else { - TestFunctionCount(0); - } -} - -TEST_P(QualifiedForLanguage, MemberFunctionSignedLanguage) { - const LanguageAndQualifiedName ¶m = GetParam(); - - PushLine(10, 1, "line-file", 212966758); - SetLanguage(param.language); - SetLanguageSigned(true); - - StartCU(); - DIEHandler *class_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - "class_A"); - DefineFunction(class_handler, "function_B", 10, 1, NULL); - class_handler->Finish(); - delete class_handler; - root_handler_.Finish(); - - if (param.name) { - TestFunctionCount(1); - TestFunction(0, param.name, 10, 1); - } else { - TestFunctionCount(0); - } -} - -class Specifications: public CUFixtureBase, public Test { }; - -TEST_F(Specifications, Function) { - PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661); - - StartCU(); - DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL, - dwarf2reader::DW_TAG_subprogram, "declaration-name", ""); - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0xcd3c51b946fb1eeeLL, "", - 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "declaration-name", - 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL); -} - -TEST_F(Specifications, MangledName) { - PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661); - - StartCU(); - DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL, - dwarf2reader::DW_TAG_subprogram, "declaration-name", - "_ZN1C1fEi"); - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0xcd3c51b946fb1eeeLL, "", - 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "C::f(int)", - 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL); -} - -TEST_F(Specifications, MemberFunction) { - PushLine(0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL, "line-file", 18116691); - - StartCU(); - DIEHandler *class_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A"); - DeclarationDIE(class_handler, 0x7d83028c431406e8ULL, - dwarf2reader::DW_TAG_subprogram, "declaration-name", ""); - class_handler->Finish(); - delete class_handler; - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0x7d83028c431406e8ULL, "", - 0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "class_A::declaration-name", - 0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL); -} - -// This case should gather the name from both the definition and the -// declaration's parent. -TEST_F(Specifications, FunctionDeclarationParent) { - PushLine(0x463c9ddf405be227ULL, 0x6a47774af5049680ULL, "line-file", 70254922); - - StartCU(); - { - DIEHandler *class_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - "class_A"); - ASSERT_TRUE(class_handler != NULL); - DeclarationDIE(class_handler, 0x0e0e877c8404544aULL, - dwarf2reader::DW_TAG_subprogram, "declaration-name", ""); - class_handler->Finish(); - delete class_handler; - } - - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0x0e0e877c8404544aULL, "definition-name", - 0x463c9ddf405be227ULL, 0x6a47774af5049680ULL); - - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "class_A::definition-name", - 0x463c9ddf405be227ULL, 0x6a47774af5049680ULL); -} - -// Named scopes should also gather enclosing name components from -// their declarations. -TEST_F(Specifications, NamedScopeDeclarationParent) { - PushLine(0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, "line-file", 77392604); - - StartCU(); - { - DIEHandler *space_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - "space_A"); - ASSERT_TRUE(space_handler != NULL); - DeclarationDIE(space_handler, 0x419bb1d12f9a73a2ULL, - dwarf2reader::DW_TAG_class_type, "class-declaration-name", - ""); - space_handler->Finish(); - delete space_handler; - } - - { - DIEHandler *class_handler - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - 0x419bb1d12f9a73a2ULL, "class-definition-name"); - ASSERT_TRUE(class_handler != NULL); - DefineFunction(class_handler, "function", - 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, NULL); - class_handler->Finish(); - delete class_handler; - } - - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "space_A::class-definition-name::function", - 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL); -} - -// This test recreates bug 364. -TEST_F(Specifications, InlineFunction) { - PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); - - StartCU(); - DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL, - dwarf2reader::DW_TAG_subprogram, "inline-name", ""); - AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL, - dwarf2reader::DW_INL_inlined, 0xcd3c51b946fb1eeeLL, ""); - DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL, - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "inline-name", - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); -} - -// An inline function in a namespace should correctly derive its -// name from its abstract origin, and not just the namespace name. -TEST_F(Specifications, InlineFunctionInNamespace) { - PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); - - StartCU(); - DIEHandler* space_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - "Namespace"); - ASSERT_TRUE(space_handler != NULL); - AbstractInstanceDIE(space_handler, 0x1e8dac5d507ed7abULL, - dwarf2reader::DW_INL_inlined, 0LL, "func-name"); - DefineInlineInstanceDIE(space_handler, "", 0x1e8dac5d507ed7abULL, - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); - space_handler->Finish(); - delete space_handler; - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "Namespace::func-name", - 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); -} - -// Check name construction for a long chain containing each combination of: -// - struct, union, class, namespace -// - direct and definition -TEST_F(Specifications, LongChain) { - PushLine(0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL, "line-file", 21192926); - SetLanguage(dwarf2reader::DW_LANG_C_plus_plus); - - StartCU(); - // The structure we're building here is: - // space_A full definition - // space_B declaration - // space_B definition - // struct_C full definition - // struct_D declaration - // struct_D definition - // union_E full definition - // union_F declaration - // union_F definition - // class_G full definition - // class_H declaration - // class_H definition - // func_I declaration - // func_I definition - // - // So: - // - space_A, struct_C, union_E, and class_G don't use specifications; - // - space_B, struct_D, union_F, and class_H do. - // - func_I uses a specification. - // - // The full name for func_I is thus: - // - // space_A::space_B::struct_C::struct_D::union_E::union_F:: - // class_G::class_H::func_I - { - DIEHandler *space_A_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - "space_A"); - DeclarationDIE(space_A_handler, 0x2e111126496596e2ULL, - dwarf2reader::DW_TAG_namespace, "space_B", ""); - space_A_handler->Finish(); - delete space_A_handler; - } - - { - DIEHandler *space_B_handler - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace, - 0x2e111126496596e2ULL); - DIEHandler *struct_C_handler - = StartNamedDIE(space_B_handler, dwarf2reader::DW_TAG_structure_type, - "struct_C"); - DeclarationDIE(struct_C_handler, 0x20cd423bf2a25a4cULL, - dwarf2reader::DW_TAG_structure_type, "struct_D", ""); - struct_C_handler->Finish(); - delete struct_C_handler; - space_B_handler->Finish(); - delete space_B_handler; - } - - { - DIEHandler *struct_D_handler - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_structure_type, - 0x20cd423bf2a25a4cULL); - DIEHandler *union_E_handler - = StartNamedDIE(struct_D_handler, dwarf2reader::DW_TAG_union_type, - "union_E"); - DeclarationDIE(union_E_handler, 0xe25c84805aa58c32ULL, - dwarf2reader::DW_TAG_union_type, "union_F", ""); - union_E_handler->Finish(); - delete union_E_handler; - struct_D_handler->Finish(); - delete struct_D_handler; - } - - { - DIEHandler *union_F_handler - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_union_type, - 0xe25c84805aa58c32ULL); - DIEHandler *class_G_handler - = StartNamedDIE(union_F_handler, dwarf2reader::DW_TAG_class_type, - "class_G"); - DeclarationDIE(class_G_handler, 0xb70d960dcc173b6eULL, - dwarf2reader::DW_TAG_class_type, "class_H", ""); - class_G_handler->Finish(); - delete class_G_handler; - union_F_handler->Finish(); - delete union_F_handler; - } - - { - DIEHandler *class_H_handler - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - 0xb70d960dcc173b6eULL); - DeclarationDIE(class_H_handler, 0x27ff829e3bf69f37ULL, - dwarf2reader::DW_TAG_subprogram, "func_I", ""); - class_H_handler->Finish(); - delete class_H_handler; - } - - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0x27ff829e3bf69f37ULL, "", - 0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "space_A::space_B::struct_C::struct_D::union_E::union_F" - "::class_G::class_H::func_I", - 0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL); -} - -TEST_F(Specifications, InterCU) { - Module m("module-name", "module-os", "module-arch", "module-id"); - DwarfCUToModule::FileContext fc("dwarf-filename", &m, true); - EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return()); - MockLineToModuleHandler lr; - EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0); - - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - // First CU. Declares class_A. - { - DwarfCUToModule root1_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root1_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ProcessStrangeAttributes(&root1_handler); - ASSERT_TRUE(root1_handler.EndAttributes()); - DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL, - dwarf2reader::DW_TAG_class_type, "class_A", ""); - root1_handler.Finish(); - } - - // Second CU. Defines class_A, declares member_func_B. - { - DwarfCUToModule root2_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root2_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ASSERT_TRUE(root2_handler.EndAttributes()); - DIEHandler *class_A_handler - = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type, - 0xb8fbfdd5f0b26fceULL); - DeclarationDIE(class_A_handler, 0xb01fef8b380bd1a2ULL, - dwarf2reader::DW_TAG_subprogram, "member_func_B", ""); - class_A_handler->Finish(); - delete class_A_handler; - root2_handler.Finish(); - } - - // Third CU. Defines member_func_B. - { - DwarfCUToModule root3_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root3_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ASSERT_TRUE(root3_handler.EndAttributes()); - DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram, - 0xb01fef8b380bd1a2ULL, "", - 0x2618f00a1a711e53ULL, 0x4fd94b76d7c2caf5ULL); - root3_handler.Finish(); - } - - vector functions; - m.GetFunctions(&functions, functions.end()); - EXPECT_EQ(1U, functions.size()); - EXPECT_STREQ("class_A::member_func_B", functions[0]->name.c_str()); -} - -TEST_F(Specifications, UnhandledInterCU) { - Module m("module-name", "module-os", "module-arch", "module-id"); - DwarfCUToModule::FileContext fc("dwarf-filename", &m, false); - EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return()); - MockLineToModuleHandler lr; - EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0); - - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - // First CU. Declares class_A. - { - DwarfCUToModule root1_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root1_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ProcessStrangeAttributes(&root1_handler); - ASSERT_TRUE(root1_handler.EndAttributes()); - DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL, - dwarf2reader::DW_TAG_class_type, "class_A", ""); - root1_handler.Finish(); - } - - // Second CU. Defines class_A, declares member_func_B. - { - DwarfCUToModule root2_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root2_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ASSERT_TRUE(root2_handler.EndAttributes()); - EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(1); - DIEHandler *class_A_handler - = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type, - 0xb8fbfdd5f0b26fceULL); - DeclarationDIE(class_A_handler, 0xb01fef8b380bd1a2ULL, - dwarf2reader::DW_TAG_subprogram, "member_func_B", ""); - class_A_handler->Finish(); - delete class_A_handler; - root2_handler.Finish(); - } - - // Third CU. Defines member_func_B. - { - DwarfCUToModule root3_handler(&fc, &lr, &reporter_); - ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3)); - ASSERT_TRUE(root3_handler.StartRootDIE(1, - dwarf2reader::DW_TAG_compile_unit)); - ASSERT_TRUE(root3_handler.EndAttributes()); - EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(1); - EXPECT_CALL(reporter_, UnnamedFunction(_)).Times(1); - DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram, - 0xb01fef8b380bd1a2ULL, "", - 0x2618f00a1a711e53ULL, 0x4fd94b76d7c2caf5ULL); - root3_handler.Finish(); - } -} - -TEST_F(Specifications, BadOffset) { - PushLine(0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL, "line-file", 56636272); - EXPECT_CALL(reporter_, UnknownSpecification(_, 0x2be953efa6f9a996ULL)) - .WillOnce(Return()); - - StartCU(); - DeclarationDIE(&root_handler_, 0xefd7f7752c27b7e4ULL, - dwarf2reader::DW_TAG_subprogram, "", ""); - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0x2be953efa6f9a996ULL, "function", - 0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL); - root_handler_.Finish(); -} - -TEST_F(Specifications, FunctionDefinitionHasOwnName) { - PushLine(0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL, "line-file", 56792403); - - StartCU(); - DeclarationDIE(&root_handler_, 0xc34ff4786cae78bdULL, - dwarf2reader::DW_TAG_subprogram, "declaration-name", ""); - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0xc34ff4786cae78bdULL, "definition-name", - 0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL); - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "definition-name", - 0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL); -} - -TEST_F(Specifications, ClassDefinitionHasOwnName) { - PushLine(0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL, "line-file", 57119241); - - StartCU(); - DeclarationDIE(&root_handler_, 0xd0fe467ec2f1a58cULL, - dwarf2reader::DW_TAG_class_type, "class-declaration-name", ""); - - dwarf2reader::DIEHandler *class_definition - = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - 0xd0fe467ec2f1a58cULL, "class-definition-name"); - ASSERT_TRUE(class_definition); - DeclarationDIE(class_definition, 0x6d028229c15623dbULL, - dwarf2reader::DW_TAG_subprogram, - "function-declaration-name", ""); - class_definition->Finish(); - delete class_definition; - - DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram, - 0x6d028229c15623dbULL, "function-definition-name", - 0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL); - - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "class-definition-name::function-definition-name", - 0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL); -} - -// DIEs that cite a specification should prefer the specification's -// parents over their own when choosing qualified names. In this test, -// we take the name from our definition but the enclosing scope name -// from our declaration. I don't see why they'd ever be different, but -// we want to verify what DwarfCUToModule is looking at. -TEST_F(Specifications, PreferSpecificationParents) { - PushLine(0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL, "line-file", 79488694); - - StartCU(); - { - dwarf2reader::DIEHandler *declaration_class_handler = - StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - "declaration-class"); - DeclarationDIE(declaration_class_handler, 0x9ddb35517455ef7aULL, - dwarf2reader::DW_TAG_subprogram, "function-declaration", - ""); - declaration_class_handler->Finish(); - delete declaration_class_handler; - } - { - dwarf2reader::DIEHandler *definition_class_handler - = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, - "definition-class"); - DefinitionDIE(definition_class_handler, dwarf2reader::DW_TAG_subprogram, - 0x9ddb35517455ef7aULL, "function-definition", - 0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL); - definition_class_handler->Finish(); - delete definition_class_handler; - } - root_handler_.Finish(); - - TestFunctionCount(1); - TestFunction(0, "declaration-class::function-definition", - 0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL); -} - -class CUErrors: public CUFixtureBase, public Test { }; - -TEST_F(CUErrors, BadStmtList) { - EXPECT_CALL(reporter_, BadLineInfoOffset(dummy_line_size_ + 10)).Times(1); - - ASSERT_TRUE(root_handler_ - .StartCompilationUnit(0xc591d5b037543d7cULL, 0x11, 0xcd, - 0x2d7d19546cf6590cULL, 3)); - ASSERT_TRUE(root_handler_.StartRootDIE(0xae789dc102cfca54ULL, - dwarf2reader::DW_TAG_compile_unit)); - root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name, - dwarf2reader::DW_FORM_strp, - "compilation-unit-name"); - root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list, - dwarf2reader::DW_FORM_ref4, - dummy_line_size_ + 10); - root_handler_.EndAttributes(); - root_handler_.Finish(); -} - -TEST_F(CUErrors, NoLineSection) { - EXPECT_CALL(reporter_, MissingSection(".debug_line")).Times(1); - PushLine(0x88507fb678052611ULL, 0x42c8e9de6bbaa0faULL, "line-file", 64472290); - // Delete the entry for .debug_line added by the fixture class's constructor. - file_context_.ClearSectionMapForTest(); - - StartCU(); - root_handler_.Finish(); -} - -TEST_F(CUErrors, BadDwarfVersion1) { - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - ASSERT_FALSE(root_handler_ - .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90, - 0xc9de224ccb99ac3eULL, 1)); -} - -TEST_F(CUErrors, GoodDwarfVersion2) { - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - ASSERT_TRUE(root_handler_ - .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90, - 0xc9de224ccb99ac3eULL, 2)); -} - -TEST_F(CUErrors, GoodDwarfVersion3) { - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - ASSERT_TRUE(root_handler_ - .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90, - 0xc9de224ccb99ac3eULL, 3)); -} - -TEST_F(CUErrors, BadCURootDIETag) { - // Kludge: satisfy reporter_'s expectation. - reporter_.SetCUName("compilation-unit-name"); - - ASSERT_TRUE(root_handler_ - .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90, - 0xc9de224ccb99ac3eULL, 3)); - - ASSERT_FALSE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL, - dwarf2reader::DW_TAG_subprogram)); -} - -// Tests for DwarfCUToModule::Reporter. These just produce (or fail to -// produce) output, so their results need to be checked by hand. -struct Reporter: public Test { - Reporter() - : reporter("filename", 0x123456789abcdef0ULL), - function("function name", 0x19c45c30770c1eb0ULL), - file("source file name") { - reporter.SetCUName("compilation-unit-name"); - - function.size = 0x89808a5bdfa0a6a3ULL; - function.parameter_size = 0x6a329f18683dcd51ULL; - - line.address = 0x3606ac6267aebeccULL; - line.size = 0x5de482229f32556aULL; - line.file = &file; - line.number = 93400201; - } - - DwarfCUToModule::WarningReporter reporter; - Module::Function function; - Module::File file; - Module::Line line; -}; - -TEST_F(Reporter, UnknownSpecification) { - reporter.UnknownSpecification(0x123456789abcdef1ULL, 0x323456789abcdef2ULL); -} - -TEST_F(Reporter, UnknownAbstractOrigin) { - reporter.UnknownAbstractOrigin(0x123456789abcdef1ULL, 0x323456789abcdef2ULL); -} - -TEST_F(Reporter, MissingSection) { - reporter.MissingSection("section name"); -} - -TEST_F(Reporter, BadLineInfoOffset) { - reporter.BadLineInfoOffset(0x123456789abcdef1ULL); -} - -TEST_F(Reporter, UncoveredFunctionDisabled) { - reporter.UncoveredFunction(function); - EXPECT_FALSE(reporter.uncovered_warnings_enabled()); -} - -TEST_F(Reporter, UncoveredFunctionEnabled) { - reporter.set_uncovered_warnings_enabled(true); - reporter.UncoveredFunction(function); - EXPECT_TRUE(reporter.uncovered_warnings_enabled()); -} - -TEST_F(Reporter, UncoveredLineDisabled) { - reporter.UncoveredLine(line); - EXPECT_FALSE(reporter.uncovered_warnings_enabled()); -} - -TEST_F(Reporter, UncoveredLineEnabled) { - reporter.set_uncovered_warnings_enabled(true); - reporter.UncoveredLine(line); - EXPECT_TRUE(reporter.uncovered_warnings_enabled()); -} - -TEST_F(Reporter, UnnamedFunction) { - reporter.UnnamedFunction(0x90c0baff9dedb2d9ULL); -} - -// Would be nice to also test: -// - overlapping lines, functions diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.cc deleted file mode 100644 index 258b0b603..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf_line_to_module.cc: Implementation of DwarfLineToModule class. -// See dwarf_line_to_module.h for details. - -#include - -#include - -#include "common/dwarf_line_to_module.h" -#include "common/using_std_string.h" - -// Trying to support Windows paths in a reasonable way adds a lot of -// variations to test; it would be better to just put off dealing with -// it until we actually have to deal with DWARF on Windows. - -// Return true if PATH is an absolute path, false if it is relative. -static bool PathIsAbsolute(const string &path) { - return (path.size() >= 1 && path[0] == '/'); -} - -static bool HasTrailingSlash(const string &path) { - return (path.size() >= 1 && path[path.size() - 1] == '/'); -} - -// If PATH is an absolute path, return PATH. If PATH is a relative path, -// treat it as relative to BASE and return the combined path. -static string ExpandPath(const string &path, - const string &base) { - if (PathIsAbsolute(path) || base.empty()) - return path; - return base + (HasTrailingSlash(base) ? "" : "/") + path; -} - -namespace google_breakpad { - -void DwarfLineToModule::DefineDir(const string &name, uint32 dir_num) { - // Directory number zero is reserved to mean the compilation - // directory. Silently ignore attempts to redefine it. - if (dir_num != 0) - directories_[dir_num] = ExpandPath(name, compilation_dir_); -} - -void DwarfLineToModule::DefineFile(const string &name, int32 file_num, - uint32 dir_num, uint64 mod_time, - uint64 length) { - if (file_num == -1) - file_num = ++highest_file_number_; - else if (file_num > highest_file_number_) - highest_file_number_ = file_num; - - string dir_name; - if (dir_num == 0) { - // Directory number zero is the compilation directory, and is stored as - // an attribute on the compilation unit, rather than in the program table. - dir_name = compilation_dir_; - } else { - DirectoryTable::const_iterator directory_it = directories_.find(dir_num); - if (directory_it != directories_.end()) { - dir_name = directory_it->second; - } else { - if (!warned_bad_directory_number_) { - fprintf(stderr, "warning: DWARF line number data refers to undefined" - " directory numbers\n"); - warned_bad_directory_number_ = true; - } - } - } - - string full_name = ExpandPath(name, dir_name); - - // Find a Module::File object of the given name, and add it to the - // file table. - files_[file_num] = module_->FindFile(full_name); -} - -void DwarfLineToModule::AddLine(uint64 address, uint64 length, - uint32 file_num, uint32 line_num, - uint32 column_num) { - if (length == 0) - return; - - // Clip lines not to extend beyond the end of the address space. - if (address + length < address) - length = -address; - - // Should we omit this line? (See the comments for omitted_line_end_.) - if (address == 0 || address == omitted_line_end_) { - omitted_line_end_ = address + length; - return; - } else { - omitted_line_end_ = 0; - } - - // Find the source file being referred to. - Module::File *file = files_[file_num]; - if (!file) { - if (!warned_bad_file_number_) { - fprintf(stderr, "warning: DWARF line number data refers to " - "undefined file numbers\n"); - warned_bad_file_number_ = true; - } - return; - } - Module::Line line; - line.address = address; - // We set the size when we get the next line or the EndSequence call. - line.size = length; - line.file = file; - line.number = line_num; - lines_->push_back(line); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.h deleted file mode 100644 index 1fdd4cb71..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.h +++ /dev/null @@ -1,188 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// The DwarfLineToModule class accepts line number information from a -// DWARF parser and adds it to a google_breakpad::Module. The Module -// can write that data out as a Breakpad symbol file. - -#ifndef COMMON_LINUX_DWARF_LINE_TO_MODULE_H -#define COMMON_LINUX_DWARF_LINE_TO_MODULE_H - -#include - -#include "common/module.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -// A class for producing a vector of google_breakpad::Module::Line -// instances from parsed DWARF line number data. -// -// An instance of this class can be provided as a handler to a -// dwarf2reader::LineInfo DWARF line number information parser. The -// handler accepts source location information from the parser and -// uses it to produce a vector of google_breakpad::Module::Line -// objects, referring to google_breakpad::Module::File objects added -// to a particular google_breakpad::Module. -// -// GNU toolchain omitted sections support: -// ====================================== -// -// Given the right options, the GNU toolchain will omit unreferenced -// functions from the final executable. Unfortunately, when it does so, it -// does not remove the associated portions of the DWARF line number -// program; instead, it gives the DW_LNE_set_address instructions referring -// to the now-deleted code addresses of zero. Given this input, the DWARF -// line parser will call AddLine with a series of lines starting at address -// zero. For example, here is the output from 'readelf -wl' for a program -// with four functions, the first three of which have been omitted: -// -// Line Number Statements: -// Extended opcode 2: set Address to 0x0 -// Advance Line by 14 to 15 -// Copy -// Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16 -// Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18 -// Advance PC by 2 to 0xd -// Extended opcode 1: End of Sequence -// -// Extended opcode 2: set Address to 0x0 -// Advance Line by 14 to 15 -// Copy -// Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 16 -// Special opcode 119: advance Address by 8 to 0xb and Line by 2 to 18 -// Advance PC by 2 to 0xd -// Extended opcode 1: End of Sequence -// -// Extended opcode 2: set Address to 0x0 -// Advance Line by 19 to 20 -// Copy -// Special opcode 48: advance Address by 3 to 0x3 and Line by 1 to 21 -// Special opcode 76: advance Address by 5 to 0x8 and Line by 1 to 22 -// Advance PC by 2 to 0xa -// Extended opcode 1: End of Sequence -// -// Extended opcode 2: set Address to 0x80483a4 -// Advance Line by 23 to 24 -// Copy -// Special opcode 202: advance Address by 14 to 0x80483b2 and Line by 1 to 25 -// Special opcode 76: advance Address by 5 to 0x80483b7 and Line by 1 to 26 -// Advance PC by 6 to 0x80483bd -// Extended opcode 1: End of Sequence -// -// Instead of collecting runs of lines describing code that is not there, -// we try to recognize and drop them. Since the linker doesn't explicitly -// distinguish references to dropped sections from genuine references to -// code at address zero, we must use a heuristic. We have chosen: -// -// - If a line starts at address zero, omit it. (On the platforms -// breakpad targets, it is extremely unlikely that there will be code -// at address zero.) -// -// - If a line starts immediately after an omitted line, omit it too. -class DwarfLineToModule: public dwarf2reader::LineInfoHandler { - public: - // As the DWARF line info parser passes us line records, add source - // files to MODULE, and add all lines to the end of LINES. LINES - // need not be empty. If the parser hands us a zero-length line, we - // omit it. If the parser hands us a line that extends beyond the - // end of the address space, we clip it. It's up to our client to - // sort out which lines belong to which functions; we don't add them - // to any particular function in MODULE ourselves. - DwarfLineToModule(Module *module, const string& compilation_dir, - vector *lines) - : module_(module), - compilation_dir_(compilation_dir), - lines_(lines), - highest_file_number_(-1), - omitted_line_end_(0), - warned_bad_file_number_(false), - warned_bad_directory_number_(false) { } - - ~DwarfLineToModule() { } - - void DefineDir(const string &name, uint32 dir_num); - void DefineFile(const string &name, int32 file_num, - uint32 dir_num, uint64 mod_time, - uint64 length); - void AddLine(uint64 address, uint64 length, - uint32 file_num, uint32 line_num, uint32 column_num); - - private: - - typedef std::map DirectoryTable; - typedef std::map FileTable; - - // The module we're contributing debugging info to. Owned by our - // client. - Module *module_; - - // The compilation directory for the current compilation unit whose - // lines are being accumulated. - string compilation_dir_; - - // The vector of lines we're accumulating. Owned by our client. - // - // In a Module, as in a breakpad symbol file, lines belong to - // specific functions, but DWARF simply assigns lines to addresses; - // one must infer the line/function relationship using the - // functions' beginning and ending addresses. So we can't add these - // to the appropriate function from module_ until we've read the - // function info as well. Instead, we accumulate lines here, and let - // whoever constructed this sort it all out. - vector *lines_; - - // A table mapping directory numbers to paths. - DirectoryTable directories_; - - // A table mapping file numbers to Module::File pointers. - FileTable files_; - - // The highest file number we've seen so far, or -1 if we've seen - // none. Used for dynamically defined file numbers. - int32 highest_file_number_; - - // This is the ending address of the last line we omitted, or zero if we - // didn't omit the previous line. It is zero before we have received any - // AddLine calls. - uint64 omitted_line_end_; - - // True if we've warned about: - bool warned_bad_file_number_; // bad file numbers - bool warned_bad_directory_number_; // bad directory numbers -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_DWARF_LINE_TO_MODULE_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module_unittest.cc deleted file mode 100644 index 7c0fcfd35..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module_unittest.cc +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dwarf_line_to_module.cc: Unit tests for google_breakpad::DwarfLineToModule. - -#include - -#include "breakpad_googletest_includes.h" -#include "common/dwarf_line_to_module.h" - -using std::vector; - -using google_breakpad::DwarfLineToModule; -using google_breakpad::Module; -using google_breakpad::Module; - -TEST(SimpleModule, One) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("file1", 0x30bf0f27, 0, 0, 0); - h.AddLine(0x6fd126fbf74f2680LL, 0x63c9a14cf556712bLL, 0x30bf0f27, - 0x4c090cbf, 0x1cf9fe0d); - - vector files; - m.GetFiles(&files); - EXPECT_EQ(1U, files.size()); - EXPECT_STREQ("/file1", files[0]->name.c_str()); - - EXPECT_EQ(1U, lines.size()); - EXPECT_EQ(0x6fd126fbf74f2680ULL, lines[0].address); - EXPECT_EQ(0x63c9a14cf556712bULL, lines[0].size); - EXPECT_TRUE(lines[0].file == files[0]); - EXPECT_EQ(0x4c090cbf, lines[0].number); -} - -TEST(SimpleModule, Many) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory1", 0x838299ab); - h.DefineDir("directory2", 0xf85de023); - h.DefineFile("file1", 0x2b80377a, 0x838299ab, 0, 0); - h.DefineFile("file1", 0x63beb4a4, 0xf85de023, 0, 0); - h.DefineFile("file2", 0x1d161d56, 0x838299ab, 0, 0); - h.DefineFile("file2", 0x1e7a667c, 0xf85de023, 0, 0); - h.AddLine(0x69900c5d553b7274ULL, 0x90fded183f0d0d3cULL, 0x2b80377a, - 0x15b0f0a9U, 0x3ff5abd6U); - h.AddLine(0x45811219a39b7101ULL, 0x25a5e6a924afc41fULL, 0x63beb4a4, - 0x4d259ce9U, 0x41c5ee32U); - h.AddLine(0xfa90514c1dc9704bULL, 0x0063efeabc02f313ULL, 0x1d161d56, - 0x1ee9fa4fU, 0xbf70e46aU); - h.AddLine(0x556b55fb6a647b10ULL, 0x3f3089ca2bfd80f5ULL, 0x1e7a667c, - 0x77fc280eU, 0x2c4a728cU); - h.DefineFile("file3", -1, 0, 0, 0); - h.AddLine(0xe2d72a37f8d9403aULL, 0x034dfab5b0d4d236ULL, 0x63beb4a5, - 0x75047044U, 0xb6a0016cU); - - vector files; - m.GetFiles(&files); - ASSERT_EQ(5U, files.size()); - EXPECT_STREQ("/directory1/file1", files[0]->name.c_str()); - EXPECT_STREQ("/directory1/file2", files[1]->name.c_str()); - EXPECT_STREQ("/directory2/file1", files[2]->name.c_str()); - EXPECT_STREQ("/directory2/file2", files[3]->name.c_str()); - EXPECT_STREQ("/file3", files[4]->name.c_str()); - - ASSERT_EQ(5U, lines.size()); - - EXPECT_EQ(0x69900c5d553b7274ULL, lines[0].address); - EXPECT_EQ(0x90fded183f0d0d3cULL, lines[0].size); - EXPECT_TRUE(lines[0].file == files[0]); - EXPECT_EQ(0x15b0f0a9, lines[0].number); - - EXPECT_EQ(0x45811219a39b7101ULL, lines[1].address); - EXPECT_EQ(0x25a5e6a924afc41fULL, lines[1].size); - EXPECT_TRUE(lines[1].file == files[2]); - EXPECT_EQ(0x4d259ce9, lines[1].number); - - EXPECT_EQ(0xfa90514c1dc9704bULL, lines[2].address); - EXPECT_EQ(0x0063efeabc02f313ULL, lines[2].size); - EXPECT_TRUE(lines[2].file == files[1]); - EXPECT_EQ(0x1ee9fa4f, lines[2].number); - - EXPECT_EQ(0x556b55fb6a647b10ULL, lines[3].address); - EXPECT_EQ(0x3f3089ca2bfd80f5ULL, lines[3].size); - EXPECT_TRUE(lines[3].file == files[3]); - EXPECT_EQ(0x77fc280e, lines[3].number); - - EXPECT_EQ(0xe2d72a37f8d9403aULL, lines[4].address); - EXPECT_EQ(0x034dfab5b0d4d236ULL, lines[4].size); - EXPECT_TRUE(lines[4].file == files[4]); - EXPECT_EQ(0x75047044, lines[4].number); -} - -TEST(Filenames, Absolute) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory1", 1); - h.DefineFile("/absolute", 1, 1, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - vector files; - m.GetFiles(&files); - ASSERT_EQ(1U, files.size()); - EXPECT_STREQ("/absolute", files[0]->name.c_str()); - ASSERT_EQ(1U, lines.size()); - EXPECT_TRUE(lines[0].file == files[0]); -} - -TEST(Filenames, Relative) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory1", 1); - h.DefineFile("relative", 1, 1, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - vector files; - m.GetFiles(&files); - ASSERT_EQ(1U, files.size()); - EXPECT_STREQ("/directory1/relative", files[0]->name.c_str()); - ASSERT_EQ(1U, lines.size()); - EXPECT_TRUE(lines[0].file == files[0]); -} - -TEST(Filenames, StrangeFile) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory1", 1); - h.DefineFile("", 1, 1, 0, 0); - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("/directory1/", lines[0].file->name.c_str()); -} - -TEST(Filenames, StrangeDirectory) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("", 1); - h.DefineFile("file1", 1, 1, 0, 0); - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("/file1", lines[0].file->name.c_str()); -} - -TEST(Filenames, StrangeDirectoryAndFile) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("", 1); - h.DefineFile("", 1, 1, 0, 0); - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("/", lines[0].file->name.c_str()); -} - -// We should use the compilation directory when encountering a file for -// directory number zero. -TEST(Filenames, DirectoryZeroFileIsRelativeToCompilationDir) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "src/build", &lines); - - h.DefineDir("Dir", 1); - h.DefineFile("File", 1, 0, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("src/build/File", lines[0].file->name.c_str()); -} - -// We should treat non-absolute directories as relative to the compilation -// directory. -TEST(Filenames, IncludeDirectoryRelativeToDirectoryZero) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "src/build", &lines); - - h.DefineDir("Dir", 1); - h.DefineFile("File", 1, 1, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("src/build/Dir/File", lines[0].file->name.c_str()); -} - -// We should treat absolute directories as absolute, and not relative to -// the compilation dir. -TEST(Filenames, IncludeDirectoryAbsolute) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "src/build", &lines); - - h.DefineDir("/Dir", 1); - h.DefineFile("File", 1, 1, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("/Dir/File", lines[0].file->name.c_str()); -} - -// We should silently ignore attempts to define directory number zero, -// since that is always the compilation directory. -TEST(ModuleErrors, DirectoryZero) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory0", 0); // should be ignored - h.DefineFile("relative", 1, 0, 0, 0); - - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("/relative", lines[0].file->name.c_str()); -} - -// We should refuse to add lines with bogus file numbers. We should -// produce only one warning, however. -TEST(ModuleErrors, BadFileNumber) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("relative", 1, 0, 0, 0); - h.AddLine(1, 1, 2, 0, 0); // bad file number - h.AddLine(2, 1, 2, 0, 0); // bad file number (no duplicate warning) - - EXPECT_EQ(0U, lines.size()); -} - -// We should treat files with bogus directory numbers as relative to -// the compilation unit. -TEST(ModuleErrors, BadDirectoryNumber) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineDir("directory1", 1); - h.DefineFile("baddirnumber1", 1, 2, 0, 0); // bad directory number - h.DefineFile("baddirnumber2", 2, 2, 0, 0); // bad dir number (no warning) - h.AddLine(1, 1, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_STREQ("baddirnumber1", lines[0].file->name.c_str()); -} - -// We promise not to report empty lines. -TEST(ModuleErrors, EmptyLine) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(1, 0, 1, 0, 0); - - ASSERT_EQ(0U, lines.size()); -} - -// We are supposed to clip lines that extend beyond the end of the -// address space. -TEST(ModuleErrors, BigLine) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(0xffffffffffffffffULL, 2, 1, 0, 0); - - ASSERT_EQ(1U, lines.size()); - EXPECT_EQ(1U, lines[0].size); -} - -// The 'Omitted' tests verify that we correctly omit line information -// for code in sections that the linker has dropped. See "GNU -// toolchain omitted sections support" at the top of the -// DwarfLineToModule class. - -TEST(Omitted, DroppedThenGood) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(0, 10, 1, 83816211, 0); // should be omitted - h.AddLine(20, 10, 1, 13059195, 0); // should be recorded - - ASSERT_EQ(1U, lines.size()); - EXPECT_EQ(13059195, lines[0].number); -} - -TEST(Omitted, GoodThenDropped) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(0x9dd6a372, 10, 1, 41454594, 0); // should be recorded - h.AddLine(0, 10, 1, 44793413, 0); // should be omitted - - ASSERT_EQ(1U, lines.size()); - EXPECT_EQ(41454594, lines[0].number); -} - -TEST(Omitted, Mix1) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(0x679ed72f, 10, 1, 58932642, 0); // should be recorded - h.AddLine(0xdfb5a72d, 10, 1, 39847385, 0); // should be recorded - h.AddLine(0, 0x78, 1, 23053829, 0); // should be omitted - h.AddLine(0x78, 0x6a, 1, 65317783, 0); // should be omitted - h.AddLine(0x78 + 0x6a, 0x2a, 1, 77601423, 0); // should be omitted - h.AddLine(0x9fe0cea5, 10, 1, 91806582, 0); // should be recorded - h.AddLine(0x7e41a109, 10, 1, 56169221, 0); // should be recorded - - ASSERT_EQ(4U, lines.size()); - EXPECT_EQ(58932642, lines[0].number); - EXPECT_EQ(39847385, lines[1].number); - EXPECT_EQ(91806582, lines[2].number); - EXPECT_EQ(56169221, lines[3].number); -} - -TEST(Omitted, Mix2) { - Module m("name", "os", "architecture", "id"); - vector lines; - DwarfLineToModule h(&m, "/", &lines); - - h.DefineFile("filename1", 1, 0, 0, 0); - h.AddLine(0, 0xf2, 1, 58802211, 0); // should be omitted - h.AddLine(0xf2, 0xb9, 1, 78958222, 0); // should be omitted - h.AddLine(0xf2 + 0xb9, 0xf7, 1, 64861892, 0); // should be omitted - h.AddLine(0x4e4d271e, 9, 1, 67355743, 0); // should be recorded - h.AddLine(0xdfb5a72d, 30, 1, 23365776, 0); // should be recorded - h.AddLine(0, 0x64, 1, 76196762, 0); // should be omitted - h.AddLine(0x64, 0x33, 1, 71066611, 0); // should be omitted - h.AddLine(0x64 + 0x33, 0xe3, 1, 61749337, 0); // should be omitted - - ASSERT_EQ(2U, lines.size()); - EXPECT_EQ(67355743, lines[0].number); - EXPECT_EQ(23365776, lines[1].number); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/language.cc b/toolkit/crashreporter/google-breakpad/src/common/language.cc deleted file mode 100644 index c2fd81f64..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/language.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// language.cc: Subclasses and singletons for google_breakpad::Language. -// See language.h for details. - -#include "common/language.h" - -namespace google_breakpad { - -// C++ language-specific operations. -class CPPLanguage: public Language { - public: - CPPLanguage() {} - string MakeQualifiedName(const string &parent_name, - const string &name) const { - if (parent_name.empty()) - return name; - else - return parent_name + "::" + name; - } -}; - -CPPLanguage CPPLanguageSingleton; - -// Java language-specific operations. -class JavaLanguage: public Language { - public: - string MakeQualifiedName(const string &parent_name, - const string &name) const { - if (parent_name.empty()) - return name; - else - return parent_name + "." + name; - } -}; - -JavaLanguage JavaLanguageSingleton; - -// Assembler language-specific operations. -class AssemblerLanguage: public Language { - bool HasFunctions() const { return false; } - string MakeQualifiedName(const string &parent_name, - const string &name) const { - return name; - } -}; - -AssemblerLanguage AssemblerLanguageSingleton; - -const Language * const Language::CPlusPlus = &CPPLanguageSingleton; -const Language * const Language::Java = &JavaLanguageSingleton; -const Language * const Language::Assembler = &AssemblerLanguageSingleton; - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/language.h b/toolkit/crashreporter/google-breakpad/src/common/language.h deleted file mode 100644 index bbe303347..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/language.h +++ /dev/null @@ -1,88 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// language.h: Define google_breakpad::Language. Instances of -// subclasses of this class provide language-appropriate operations -// for the Breakpad symbol dumper. - -#ifndef COMMON_LINUX_LANGUAGE_H__ -#define COMMON_LINUX_LANGUAGE_H__ - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -// An abstract base class for language-specific operations. We choose -// an instance of a subclass of this when we find the CU's language. -// This class's definitions are appropriate for CUs with no specified -// language. -class Language { - public: - // A base class destructor should be either public and virtual, - // or protected and nonvirtual. - virtual ~Language() {} - - // Return true if this language has functions to which we can assign - // line numbers. (Debugging info for assembly language, for example, - // can have source location information, but does not have functions - // recorded using DW_TAG_subprogram DIEs.) - virtual bool HasFunctions() const { return true; } - - // Construct a fully-qualified, language-appropriate form of NAME, - // given that PARENT_NAME is the name of the construct enclosing - // NAME. If PARENT_NAME is the empty string, then NAME is a - // top-level name. - // - // This API sort of assumes that a fully-qualified name is always - // some simple textual composition of the unqualified name and its - // parent's name, and that we don't need to know anything else about - // the parent or the child (say, their DIEs' tags) to do the job. - // This is true for the languages we support at the moment, and - // keeps things concrete. Perhaps a more refined operation would - // take into account the parent and child DIE types, allow languages - // to use their own data type for complex parent names, etc. But if - // C++ doesn't need all that, who would? - virtual string MakeQualifiedName (const string &parent_name, - const string &name) const = 0; - - // Instances for specific languages. - static const Language * const CPlusPlus, - * const Java, - * const Assembler; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_LANGUAGE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.cc deleted file mode 100644 index 8df636ce4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/linux/crc32.h" - -namespace google_breakpad { - -// This implementation is based on the sample implementation in RFC 1952. - -// CRC32 polynomial, in reversed form. -// See RFC 1952, or http://en.wikipedia.org/wiki/Cyclic_redundancy_check -static const uint32_t kCrc32Polynomial = 0xEDB88320; -static uint32_t kCrc32Table[256] = { 0 }; - -#define arraysize(f) (sizeof(f) / sizeof(*f)) - -static void EnsureCrc32TableInited() { - if (kCrc32Table[arraysize(kCrc32Table) - 1]) - return; // already inited - for (uint32_t i = 0; i < arraysize(kCrc32Table); ++i) { - uint32_t c = i; - for (size_t j = 0; j < 8; ++j) { - if (c & 1) { - c = kCrc32Polynomial ^ (c >> 1); - } else { - c >>= 1; - } - } - kCrc32Table[i] = c; - } -} - -uint32_t UpdateCrc32(uint32_t start, const void* buf, size_t len) { - EnsureCrc32TableInited(); - - uint32_t c = start ^ 0xFFFFFFFF; - const uint8_t* u = static_cast(buf); - for (size_t i = 0; i < len; ++i) { - c = kCrc32Table[(c ^ u[i]) & 0xFF] ^ (c >> 8); - } - return c ^ 0xFFFFFFFF; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.h b/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.h deleted file mode 100644 index e3d9db92b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/crc32.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_LINUX_CRC32_H_ -#define COMMON_LINUX_CRC32_H_ - -#include - -#include - -namespace google_breakpad { - -// Updates a CRC32 checksum with |len| bytes from |buf|. |initial| holds the -// checksum result from the previous update; for the first call, it should be 0. -uint32_t UpdateCrc32(uint32_t initial, const void* buf, size_t len); - -// Computes a CRC32 checksum using |len| bytes from |buf|. -inline uint32_t ComputeCrc32(const void* buf, size_t len) { - return UpdateCrc32(0, buf, len); -} -inline uint32_t ComputeCrc32(const std::string& str) { - return ComputeCrc32(str.c_str(), str.size()); -} - -} // namespace google_breakpad - -#endif // COMMON_LINUX_CRC32_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc deleted file mode 100644 index cd99bee66..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc +++ /dev/null @@ -1,1159 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Restructured in 2009 by: Jim Blandy - -// dump_symbols.cc: implement google_breakpad::WriteSymbolFile: -// Find all the debugging info in a file and dump it as a Breakpad symbol file. - -#include "common/linux/dump_symbols.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "common/arm_ex_reader.h" -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/dwarf2diehandler.h" -#include "common/dwarf_cfi_to_module.h" -#include "common/dwarf_cu_to_module.h" -#include "common/dwarf_line_to_module.h" -#include "common/linux/crc32.h" -#include "common/linux/eintr_wrapper.h" -#include "common/linux/elfutils.h" -#include "common/linux/elfutils-inl.h" -#include "common/linux/elf_symbols_to_module.h" -#include "common/linux/file_id.h" -#include "common/memory.h" -#include "common/module.h" -#include "common/scoped_ptr.h" -#ifndef NO_STABS_SUPPORT -#include "common/stabs_reader.h" -#include "common/stabs_to_module.h" -#endif -#include "common/using_std_string.h" - -#ifndef SHT_ARM_EXIDX -// bionic and older glibc don't define this -# define SHT_ARM_EXIDX (SHT_LOPROC + 1) -#endif - -// This namespace contains helper functions. -namespace { - -using google_breakpad::DumpOptions; -using google_breakpad::DwarfCFIToModule; -using google_breakpad::DwarfCUToModule; -using google_breakpad::DwarfLineToModule; -using google_breakpad::ElfClass; -using google_breakpad::ElfClass32; -using google_breakpad::ElfClass64; -using google_breakpad::FileID; -using google_breakpad::FindElfSectionByName; -using google_breakpad::GetOffset; -using google_breakpad::IsValidElf; -using google_breakpad::kDefaultBuildIdSize; -using google_breakpad::Module; -using google_breakpad::PageAllocator; -#ifndef NO_STABS_SUPPORT -using google_breakpad::StabsToModule; -#endif -using google_breakpad::scoped_ptr; -using google_breakpad::wasteful_vector; - -// Define AARCH64 ELF architecture if host machine does not include this define. -#ifndef EM_AARCH64 -#define EM_AARCH64 183 -#endif - -// Define SHT_ANDROID_REL and SHT_ANDROID_RELA if not defined by the host. -// Sections with this type contain Android packed relocations. -#ifndef SHT_ANDROID_REL -#define SHT_ANDROID_REL (SHT_LOOS + 1) -#endif -#ifndef SHT_ANDROID_RELA -#define SHT_ANDROID_RELA (SHT_LOOS + 2) -#endif - -// -// FDWrapper -// -// Wrapper class to make sure opened file is closed. -// -class FDWrapper { - public: - explicit FDWrapper(int fd) : - fd_(fd) {} - ~FDWrapper() { - if (fd_ != -1) - close(fd_); - } - int get() { - return fd_; - } - int release() { - int fd = fd_; - fd_ = -1; - return fd; - } - private: - int fd_; -}; - -// -// MmapWrapper -// -// Wrapper class to make sure mapped regions are unmapped. -// -class MmapWrapper { - public: - MmapWrapper() : is_set_(false) {} - ~MmapWrapper() { - if (is_set_ && base_ != NULL) { - assert(size_ > 0); - munmap(base_, size_); - } - } - void set(void *mapped_address, size_t mapped_size) { - is_set_ = true; - base_ = mapped_address; - size_ = mapped_size; - } - void release() { - assert(is_set_); - is_set_ = false; - base_ = NULL; - size_ = 0; - } - - private: - bool is_set_; - void* base_; - size_t size_; -}; - -// Find the preferred loading address of the binary. -template -typename ElfClass::Addr GetLoadingAddress( - const typename ElfClass::Phdr* program_headers, - int nheader) { - typedef typename ElfClass::Phdr Phdr; - - // For non-PIC executables (e_type == ET_EXEC), the load address is - // the start address of the first PT_LOAD segment. (ELF requires - // the segments to be sorted by load address.) For PIC executables - // and dynamic libraries (e_type == ET_DYN), this address will - // normally be zero. - for (int i = 0; i < nheader; ++i) { - const Phdr& header = program_headers[i]; - if (header.p_type == PT_LOAD) - return header.p_vaddr; - } - return 0; -} - -#ifndef NO_STABS_SUPPORT -template -bool LoadStabs(const typename ElfClass::Ehdr* elf_header, - const typename ElfClass::Shdr* stab_section, - const typename ElfClass::Shdr* stabstr_section, - const bool big_endian, - Module* module) { - // A callback object to handle data from the STABS reader. - StabsToModule handler(module); - // Find the addresses of the STABS data, and create a STABS reader object. - // On Linux, STABS entries always have 32-bit values, regardless of the - // address size of the architecture whose code they're describing, and - // the strings are always "unitized". - const uint8_t* stabs = - GetOffset(elf_header, stab_section->sh_offset); - const uint8_t* stabstr = - GetOffset(elf_header, stabstr_section->sh_offset); - google_breakpad::StabsReader reader(stabs, stab_section->sh_size, - stabstr, stabstr_section->sh_size, - big_endian, 4, true, &handler); - // Read the STABS data, and do post-processing. - if (!reader.Process()) - return false; - handler.Finalize(); - return true; -} -#endif // NO_STABS_SUPPORT - -// A line-to-module loader that accepts line number info parsed by -// dwarf2reader::LineInfo and populates a Module and a line vector -// with the results. -class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler { - public: - // Create a line-to-module converter using BYTE_READER. - explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader) - : byte_reader_(byte_reader) { } - void StartCompilationUnit(const string& compilation_dir) { - compilation_dir_ = compilation_dir; - } - void ReadProgram(const uint8_t *program, uint64 length, - Module* module, std::vector* lines) { - DwarfLineToModule handler(module, compilation_dir_, lines); - dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); - parser.Start(); - } - private: - string compilation_dir_; - dwarf2reader::ByteReader *byte_reader_; -}; - -template -bool LoadDwarf(const string& dwarf_filename, - const typename ElfClass::Ehdr* elf_header, - const bool big_endian, - bool handle_inter_cu_refs, - Module* module) { - typedef typename ElfClass::Shdr Shdr; - - const dwarf2reader::Endianness endianness = big_endian ? - dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE; - dwarf2reader::ByteReader byte_reader(endianness); - - // Construct a context for this file. - DwarfCUToModule::FileContext file_context(dwarf_filename, - module, - handle_inter_cu_refs); - - // Build a map of the ELF file's sections. - const Shdr* sections = - GetOffset(elf_header, elf_header->e_shoff); - int num_sections = elf_header->e_shnum; - const Shdr* section_names = sections + elf_header->e_shstrndx; - for (int i = 0; i < num_sections; i++) { - const Shdr* section = §ions[i]; - string name = GetOffset(elf_header, - section_names->sh_offset) + - section->sh_name; - const uint8_t *contents = GetOffset(elf_header, - section->sh_offset); - file_context.AddSectionToSectionMap(name, contents, section->sh_size); - } - - // Parse all the compilation units in the .debug_info section. - DumperLineToModule line_to_module(&byte_reader); - dwarf2reader::SectionMap::const_iterator debug_info_entry = - file_context.section_map().find(".debug_info"); - assert(debug_info_entry != file_context.section_map().end()); - const std::pair& debug_info_section = - debug_info_entry->second; - // This should never have been called if the file doesn't have a - // .debug_info section. - assert(debug_info_section.first); - uint64 debug_info_length = debug_info_section.second; - for (uint64 offset = 0; offset < debug_info_length;) { - // Make a handler for the root DIE that populates MODULE with the - // data that was found. - DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset); - DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter); - // Make a Dwarf2Handler that drives the DIEHandler. - dwarf2reader::DIEDispatcher die_dispatcher(&root_handler); - // Make a DWARF parser for the compilation unit at OFFSET. - dwarf2reader::CompilationUnit reader(dwarf_filename, - file_context.section_map(), - offset, - &byte_reader, - &die_dispatcher); - // Process the entire compilation unit; get the offset of the next. - offset += reader.Start(); - } - return true; -} - -// Fill REGISTER_NAMES with the register names appropriate to the -// machine architecture given in HEADER, indexed by the register -// numbers used in DWARF call frame information. Return true on -// success, or false if HEADER's machine architecture is not -// supported. -template -bool DwarfCFIRegisterNames(const typename ElfClass::Ehdr* elf_header, - std::vector* register_names) { - switch (elf_header->e_machine) { - case EM_386: - *register_names = DwarfCFIToModule::RegisterNames::I386(); - return true; - case EM_ARM: - *register_names = DwarfCFIToModule::RegisterNames::ARM(); - return true; - case EM_AARCH64: - *register_names = DwarfCFIToModule::RegisterNames::ARM64(); - return true; - case EM_MIPS: - *register_names = DwarfCFIToModule::RegisterNames::MIPS(); - return true; - case EM_X86_64: - *register_names = DwarfCFIToModule::RegisterNames::X86_64(); - return true; - default: - return false; - } -} - -template -bool LoadDwarfCFI(const string& dwarf_filename, - const typename ElfClass::Ehdr* elf_header, - const char* section_name, - const typename ElfClass::Shdr* section, - const bool eh_frame, - const typename ElfClass::Shdr* got_section, - const typename ElfClass::Shdr* text_section, - const bool big_endian, - Module* module) { - // Find the appropriate set of register names for this file's - // architecture. - std::vector register_names; - if (!DwarfCFIRegisterNames(elf_header, ®ister_names)) { - fprintf(stderr, "%s: unrecognized ELF machine architecture '%d';" - " cannot convert DWARF call frame information\n", - dwarf_filename.c_str(), elf_header->e_machine); - return false; - } - - const dwarf2reader::Endianness endianness = big_endian ? - dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE; - - // Find the call frame information and its size. - const uint8_t *cfi = - GetOffset(elf_header, section->sh_offset); - size_t cfi_size = section->sh_size; - - // Plug together the parser, handler, and their entourages. - DwarfCFIToModule::Reporter module_reporter(dwarf_filename, section_name); - DwarfCFIToModule handler(module, register_names, &module_reporter); - dwarf2reader::ByteReader byte_reader(endianness); - - byte_reader.SetAddressSize(ElfClass::kAddrSize); - - // Provide the base addresses for .eh_frame encoded pointers, if - // possible. - byte_reader.SetCFIDataBase(section->sh_addr, cfi); - if (got_section) - byte_reader.SetDataBase(got_section->sh_addr); - if (text_section) - byte_reader.SetTextBase(text_section->sh_addr); - - dwarf2reader::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename, - section_name); - dwarf2reader::CallFrameInfo parser(cfi, cfi_size, - &byte_reader, &handler, &dwarf_reporter, - eh_frame); - parser.Start(); - return true; -} - -template -bool LoadARMexidx(const typename ElfClass::Ehdr* elf_header, - const typename ElfClass::Shdr* exidx_section, - const typename ElfClass::Shdr* extab_section, - uint32_t loading_addr, - Module* module) { - // To do this properly we need to know: - // * the bounds of the .ARM.exidx section in the mapped image - // * the bounds of the .ARM.extab section in the mapped image - // * the vma of the last byte in the text section associated with the .exidx - // The first two are easy. The third is a bit tricky. If we can't - // figure out what it is, just pass in zero. - const char *exidx_img - = GetOffset(elf_header, exidx_section->sh_offset); - size_t exidx_size = exidx_section->sh_size; - const char *extab_img - = GetOffset(elf_header, extab_section->sh_offset); - size_t extab_size = extab_section->sh_size; - - // The sh_link field of the exidx section gives the section number - // for the associated text section. - uint32_t exidx_text_last_svma = 0; - int exidx_text_sno = exidx_section->sh_link; - typedef typename ElfClass::Shdr Shdr; - // |sections| points to the section header table - const Shdr* sections - = GetOffset(elf_header, elf_header->e_shoff); - const int num_sections = elf_header->e_shnum; - if (exidx_text_sno >= 0 && exidx_text_sno < num_sections) { - const Shdr* exidx_text_shdr = §ions[exidx_text_sno]; - if (exidx_text_shdr->sh_size > 0) { - exidx_text_last_svma - = exidx_text_shdr->sh_addr + exidx_text_shdr->sh_size - 1; - } - } - - arm_ex_to_module::ARMExToModule handler(module); - arm_ex_reader::ExceptionTableInfo - parser(exidx_img, exidx_size, extab_img, extab_size, exidx_text_last_svma, - &handler, - reinterpret_cast(elf_header), - loading_addr); - parser.Start(); - return true; -} - -bool LoadELF(const string& obj_file, MmapWrapper* map_wrapper, - void** elf_header) { - int obj_fd = open(obj_file.c_str(), O_RDONLY); - if (obj_fd < 0) { - fprintf(stderr, "Failed to open ELF file '%s': %s\n", - obj_file.c_str(), strerror(errno)); - return false; - } - FDWrapper obj_fd_wrapper(obj_fd); - struct stat st; - if (fstat(obj_fd, &st) != 0 && st.st_size <= 0) { - fprintf(stderr, "Unable to fstat ELF file '%s': %s\n", - obj_file.c_str(), strerror(errno)); - return false; - } - void* obj_base = mmap(NULL, st.st_size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, obj_fd, 0); - if (obj_base == MAP_FAILED) { - fprintf(stderr, "Failed to mmap ELF file '%s': %s\n", - obj_file.c_str(), strerror(errno)); - return false; - } - map_wrapper->set(obj_base, st.st_size); - *elf_header = obj_base; - if (!IsValidElf(*elf_header)) { - fprintf(stderr, "Not a valid ELF file: %s\n", obj_file.c_str()); - return false; - } - return true; -} - -// Get the endianness of ELF_HEADER. If it's invalid, return false. -template -bool ElfEndianness(const typename ElfClass::Ehdr* elf_header, - bool* big_endian) { - if (elf_header->e_ident[EI_DATA] == ELFDATA2LSB) { - *big_endian = false; - return true; - } - if (elf_header->e_ident[EI_DATA] == ELFDATA2MSB) { - *big_endian = true; - return true; - } - - fprintf(stderr, "bad data encoding in ELF header: %d\n", - elf_header->e_ident[EI_DATA]); - return false; -} - -// Given |left_abspath|, find the absolute path for |right_path| and see if the -// two absolute paths are the same. -bool IsSameFile(const char* left_abspath, const string& right_path) { - char right_abspath[PATH_MAX]; - if (!realpath(right_path.c_str(), right_abspath)) - return false; - return strcmp(left_abspath, right_abspath) == 0; -} - -// Read the .gnu_debuglink and get the debug file name. If anything goes -// wrong, return an empty string. -string ReadDebugLink(const uint8_t *debuglink, - const size_t debuglink_size, - const bool big_endian, - const string& obj_file, - const std::vector& debug_dirs) { - // Include '\0' + CRC32 (4 bytes). - size_t debuglink_len = strlen(reinterpret_cast(debuglink)) + 5; - debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes. - - // Sanity check. - if (debuglink_len != debuglink_size) { - fprintf(stderr, "Mismatched .gnu_debuglink string / section size: " - "%zx %zx\n", debuglink_len, debuglink_size); - return string(); - } - - char obj_file_abspath[PATH_MAX]; - if (!realpath(obj_file.c_str(), obj_file_abspath)) { - fprintf(stderr, "Cannot resolve absolute path for %s\n", obj_file.c_str()); - return string(); - } - - std::vector searched_paths; - string debuglink_path; - std::vector::const_iterator it; - for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) { - const string& debug_dir = *it; - debuglink_path = debug_dir + "/" + - reinterpret_cast(debuglink); - - // There is the annoying case of /path/to/foo.so having foo.so as the - // debug link file name. Thus this may end up opening /path/to/foo.so again, - // and there is a small chance of the two files having the same CRC. - if (IsSameFile(obj_file_abspath, debuglink_path)) - continue; - - searched_paths.push_back(debug_dir); - int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY); - if (debuglink_fd < 0) - continue; - - FDWrapper debuglink_fd_wrapper(debuglink_fd); - - // The CRC is the last 4 bytes in |debuglink|. - const dwarf2reader::Endianness endianness = big_endian ? - dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE; - dwarf2reader::ByteReader byte_reader(endianness); - uint32_t expected_crc = - byte_reader.ReadFourBytes(&debuglink[debuglink_size - 4]); - - uint32_t actual_crc = 0; - while (true) { - const size_t kReadSize = 4096; - char buf[kReadSize]; - ssize_t bytes_read = HANDLE_EINTR(read(debuglink_fd, &buf, kReadSize)); - if (bytes_read < 0) { - fprintf(stderr, "Error reading debug ELF file %s.\n", - debuglink_path.c_str()); - return string(); - } - if (bytes_read == 0) - break; - actual_crc = google_breakpad::UpdateCrc32(actual_crc, buf, bytes_read); - } - if (actual_crc != expected_crc) { - fprintf(stderr, "Error reading debug ELF file - CRC32 mismatch: %s\n", - debuglink_path.c_str()); - continue; - } - - // Found debug file. - return debuglink_path; - } - - // Not found case. - fprintf(stderr, "Failed to find debug ELF file for '%s' after trying:\n", - obj_file.c_str()); - for (it = searched_paths.begin(); it < searched_paths.end(); ++it) { - const string& debug_dir = *it; - fprintf(stderr, " %s/%s\n", debug_dir.c_str(), debuglink); - } - return string(); -} - -// -// LoadSymbolsInfo -// -// Holds the state between the two calls to LoadSymbols() in case it's necessary -// to follow the .gnu_debuglink section and load debug information from a -// different file. -// -template -class LoadSymbolsInfo { - public: - typedef typename ElfClass::Addr Addr; - - explicit LoadSymbolsInfo(const std::vector& dbg_dirs) : - debug_dirs_(dbg_dirs), - has_loading_addr_(false) {} - - // Keeps track of which sections have been loaded so sections don't - // accidentally get loaded twice from two different files. - void LoadedSection(const string §ion) { - if (loaded_sections_.count(section) == 0) { - loaded_sections_.insert(section); - } else { - fprintf(stderr, "Section %s has already been loaded.\n", - section.c_str()); - } - } - - // The ELF file and linked debug file are expected to have the same preferred - // loading address. - void set_loading_addr(Addr addr, const string &filename) { - if (!has_loading_addr_) { - loading_addr_ = addr; - loaded_file_ = filename; - return; - } - - if (addr != loading_addr_) { - fprintf(stderr, - "ELF file '%s' and debug ELF file '%s' " - "have different load addresses.\n", - loaded_file_.c_str(), filename.c_str()); - assert(false); - } - } - - // Setters and getters - const std::vector& debug_dirs() const { - return debug_dirs_; - } - - string debuglink_file() const { - return debuglink_file_; - } - void set_debuglink_file(string file) { - debuglink_file_ = file; - } - - private: - const std::vector& debug_dirs_; // Directories in which to - // search for the debug ELF file. - - string debuglink_file_; // Full path to the debug ELF file. - - bool has_loading_addr_; // Indicate if LOADING_ADDR_ is valid. - - Addr loading_addr_; // Saves the preferred loading address from the - // first call to LoadSymbols(). - - string loaded_file_; // Name of the file loaded from the first call to - // LoadSymbols(). - - std::set loaded_sections_; // Tracks the Loaded ELF sections - // between calls to LoadSymbols(). -}; - -template -bool LoadSymbols(const string& obj_file, - const bool big_endian, - const typename ElfClass::Ehdr* elf_header, - const bool read_gnu_debug_link, - LoadSymbolsInfo* info, - const DumpOptions& options, - Module* module) { - typedef typename ElfClass::Addr Addr; - typedef typename ElfClass::Phdr Phdr; - typedef typename ElfClass::Shdr Shdr; - typedef typename ElfClass::Word Word; - - Addr loading_addr = GetLoadingAddress( - GetOffset(elf_header, elf_header->e_phoff), - elf_header->e_phnum); - module->SetLoadAddress(loading_addr); - info->set_loading_addr(loading_addr, obj_file); - - Word debug_section_type = - elf_header->e_machine == EM_MIPS ? SHT_MIPS_DWARF : SHT_PROGBITS; - const Shdr* sections = - GetOffset(elf_header, elf_header->e_shoff); - const Shdr* section_names = sections + elf_header->e_shstrndx; - const char* names = - GetOffset(elf_header, section_names->sh_offset); - const char *names_end = names + section_names->sh_size; - bool found_debug_info_section = false; - bool found_usable_info = false; - - // Reject files that contain Android packed relocations. The pre-packed - // version of the file should be symbolized; the packed version is only - // intended for use on the target system. - if (FindElfSectionByName(".rel.dyn", SHT_ANDROID_REL, - sections, names, - names_end, elf_header->e_shnum)) { - fprintf(stderr, "%s: file contains a \".rel.dyn\" section " - "with type SHT_ANDROID_REL\n", obj_file.c_str()); - fprintf(stderr, "Files containing Android packed relocations " - "may not be symbolized.\n"); - return false; - } - if (FindElfSectionByName(".rela.dyn", SHT_ANDROID_RELA, - sections, names, - names_end, elf_header->e_shnum)) { - fprintf(stderr, "%s: file contains a \".rela.dyn\" section " - "with type SHT_ANDROID_RELA\n", obj_file.c_str()); - fprintf(stderr, "Files containing Android packed relocations " - "may not be symbolized.\n"); - return false; - } - - if (options.symbol_data != ONLY_CFI) { -#ifndef NO_STABS_SUPPORT - // Look for STABS debugging information, and load it if present. - const Shdr* stab_section = - FindElfSectionByName(".stab", SHT_PROGBITS, - sections, names, names_end, - elf_header->e_shnum); - if (stab_section) { - const Shdr* stabstr_section = stab_section->sh_link + sections; - if (stabstr_section) { - found_debug_info_section = true; - found_usable_info = true; - info->LoadedSection(".stab"); - if (!LoadStabs(elf_header, stab_section, stabstr_section, - big_endian, module)) { - fprintf(stderr, "%s: \".stab\" section found, but failed to load" - " STABS debugging information\n", obj_file.c_str()); - } - } - } -#endif // NO_STABS_SUPPORT - - // Look for DWARF debugging information, and load it if present. - const Shdr* dwarf_section = - FindElfSectionByName(".debug_info", debug_section_type, - sections, names, names_end, - elf_header->e_shnum); - if (dwarf_section) { - found_debug_info_section = true; - found_usable_info = true; - info->LoadedSection(".debug_info"); - if (!LoadDwarf(obj_file, elf_header, big_endian, - options.handle_inter_cu_refs, module)) { - fprintf(stderr, "%s: \".debug_info\" section found, but failed to load " - "DWARF debugging information\n", obj_file.c_str()); - } - } - - // See if there are export symbols available. - const Shdr* symtab_section = - FindElfSectionByName(".symtab", SHT_SYMTAB, - sections, names, names_end, - elf_header->e_shnum); - const Shdr* strtab_section = - FindElfSectionByName(".strtab", SHT_STRTAB, - sections, names, names_end, - elf_header->e_shnum); - if (symtab_section && strtab_section) { - info->LoadedSection(".symtab"); - - const uint8_t* symtab = - GetOffset(elf_header, - symtab_section->sh_offset); - const uint8_t* strtab = - GetOffset(elf_header, - strtab_section->sh_offset); - bool result = - ELFSymbolsToModule(symtab, - symtab_section->sh_size, - strtab, - strtab_section->sh_size, - big_endian, - ElfClass::kAddrSize, - module); - found_usable_info = found_usable_info || result; - } else { - // Look in dynsym only if full symbol table was not available. - const Shdr* dynsym_section = - FindElfSectionByName(".dynsym", SHT_DYNSYM, - sections, names, names_end, - elf_header->e_shnum); - const Shdr* dynstr_section = - FindElfSectionByName(".dynstr", SHT_STRTAB, - sections, names, names_end, - elf_header->e_shnum); - if (dynsym_section && dynstr_section) { - info->LoadedSection(".dynsym"); - - const uint8_t* dynsyms = - GetOffset(elf_header, - dynsym_section->sh_offset); - const uint8_t* dynstrs = - GetOffset(elf_header, - dynstr_section->sh_offset); - bool result = - ELFSymbolsToModule(dynsyms, - dynsym_section->sh_size, - dynstrs, - dynstr_section->sh_size, - big_endian, - ElfClass::kAddrSize, - module); - found_usable_info = found_usable_info || result; - } - } - } - - if (options.symbol_data != NO_CFI) { - // Dwarf Call Frame Information (CFI) is actually independent from - // the other DWARF debugging information, and can be used alone. - const Shdr* dwarf_cfi_section = - FindElfSectionByName(".debug_frame", debug_section_type, - sections, names, names_end, - elf_header->e_shnum); - if (dwarf_cfi_section) { - // Ignore the return value of this function; even without call frame - // information, the other debugging information could be perfectly - // useful. - info->LoadedSection(".debug_frame"); - bool result = - LoadDwarfCFI(obj_file, elf_header, ".debug_frame", - dwarf_cfi_section, false, 0, 0, big_endian, - module); - found_usable_info = found_usable_info || result; - } - - // Linux C++ exception handling information can also provide - // unwinding data. - const Shdr* eh_frame_section = - FindElfSectionByName(".eh_frame", SHT_PROGBITS, - sections, names, names_end, - elf_header->e_shnum); - if (eh_frame_section) { - // Pointers in .eh_frame data may be relative to the base addresses of - // certain sections. Provide those sections if present. - const Shdr* got_section = - FindElfSectionByName(".got", SHT_PROGBITS, - sections, names, names_end, - elf_header->e_shnum); - const Shdr* text_section = - FindElfSectionByName(".text", SHT_PROGBITS, - sections, names, names_end, - elf_header->e_shnum); - info->LoadedSection(".eh_frame"); - // As above, ignore the return value of this function. - bool result = - LoadDwarfCFI(obj_file, elf_header, ".eh_frame", - eh_frame_section, true, - got_section, text_section, big_endian, module); - found_usable_info = found_usable_info || result; - } - } - - // ARM has special unwind tables that can be used. - const Shdr* arm_exidx_section = - FindElfSectionByName(".ARM.exidx", SHT_ARM_EXIDX, - sections, names, names_end, - elf_header->e_shnum); - const Shdr* arm_extab_section = - FindElfSectionByName(".ARM.extab", SHT_PROGBITS, - sections, names, names_end, - elf_header->e_shnum); - // Load information from these sections even if there is - // .debug_info, because some functions (e.g., hand-written or - // script-generated assembly) could have exidx entries but no DWARF. - // (For functions with both, the DWARF info that has already been - // parsed will take precedence.) - if (arm_exidx_section && arm_extab_section && options.symbol_data != NO_CFI) { - info->LoadedSection(".ARM.exidx"); - info->LoadedSection(".ARM.extab"); - bool result = LoadARMexidx(elf_header, - arm_exidx_section, arm_extab_section, - loading_addr, module); - found_usable_info = found_usable_info || result; - } - - if (!found_debug_info_section) { - fprintf(stderr, "%s: file contains no debugging information" - " (no \".stab\" or \".debug_info\" sections)\n", - obj_file.c_str()); - - // Failed, but maybe there's a .gnu_debuglink section? - if (read_gnu_debug_link) { - const Shdr* gnu_debuglink_section - = FindElfSectionByName(".gnu_debuglink", SHT_PROGBITS, - sections, names, - names_end, elf_header->e_shnum); - if (gnu_debuglink_section) { - if (!info->debug_dirs().empty()) { - const uint8_t *debuglink_contents = - GetOffset(elf_header, - gnu_debuglink_section->sh_offset); - string debuglink_file = - ReadDebugLink(debuglink_contents, - gnu_debuglink_section->sh_size, - big_endian, - obj_file, - info->debug_dirs()); - info->set_debuglink_file(debuglink_file); - } else { - fprintf(stderr, ".gnu_debuglink section found in '%s', " - "but no debug path specified.\n", obj_file.c_str()); - } - } else { - fprintf(stderr, "%s does not contain a .gnu_debuglink section.\n", - obj_file.c_str()); - } - } else { - // Return true if some usable information was found, since the caller - // doesn't want to use .gnu_debuglink. - return found_usable_info; - } - - // No debug info was found, let the user try again with .gnu_debuglink - // if present. - return false; - } - - return true; -} - -// Return the breakpad symbol file identifier for the architecture of -// ELF_HEADER. -template -const char* ElfArchitecture(const typename ElfClass::Ehdr* elf_header) { - typedef typename ElfClass::Half Half; - Half arch = elf_header->e_machine; - switch (arch) { - case EM_386: return "x86"; - case EM_ARM: return "arm"; - case EM_AARCH64: return "arm64"; - case EM_MIPS: return "mips"; - case EM_PPC64: return "ppc64"; - case EM_PPC: return "ppc"; - case EM_S390: return "s390"; - case EM_SPARC: return "sparc"; - case EM_SPARCV9: return "sparcv9"; - case EM_X86_64: return "x86_64"; - default: return NULL; - } -} - -// Return the non-directory portion of FILENAME: the portion after the -// last slash, or the whole filename if there are no slashes. -string BaseFileName(const string &filename) { - // Lots of copies! basename's behavior is less than ideal. - char* c_filename = strdup(filename.c_str()); - string base = basename(c_filename); - free(c_filename); - return base; -} - -template -bool SanitizeDebugFile(const typename ElfClass::Ehdr* debug_elf_header, - const string& debuglink_file, - const string& obj_filename, - const char* obj_file_architecture, - const bool obj_file_is_big_endian) { - const char* debug_architecture = - ElfArchitecture(debug_elf_header); - if (!debug_architecture) { - fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", - debuglink_file.c_str(), debug_elf_header->e_machine); - return false; - } - if (strcmp(obj_file_architecture, debug_architecture)) { - fprintf(stderr, "%s with ELF machine architecture %s does not match " - "%s with ELF architecture %s\n", - debuglink_file.c_str(), debug_architecture, - obj_filename.c_str(), obj_file_architecture); - return false; - } - bool debug_big_endian; - if (!ElfEndianness(debug_elf_header, &debug_big_endian)) - return false; - if (debug_big_endian != obj_file_is_big_endian) { - fprintf(stderr, "%s and %s does not match in endianness\n", - obj_filename.c_str(), debuglink_file.c_str()); - return false; - } - return true; -} - -template -bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, - const string& obj_filename, - scoped_ptr& module) { - PageAllocator allocator; - wasteful_vector identifier(&allocator, kDefaultBuildIdSize); - if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, identifier)) { - fprintf(stderr, "%s: unable to generate file identifier\n", - obj_filename.c_str()); - return false; - } - - const char *architecture = ElfArchitecture(elf_header); - if (!architecture) { - fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", - obj_filename.c_str(), elf_header->e_machine); - return false; - } - - string name = BaseFileName(obj_filename); - string os = "Linux"; - // Add an extra "0" at the end. PDB files on Windows have an 'age' - // number appended to the end of the file identifier; this isn't - // really used or necessary on other platforms, but be consistent. - string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0"; - // This is just the raw Build ID in hex. - string code_id = FileID::ConvertIdentifierToString(identifier); - - module.reset(new Module(name, os, architecture, id, code_id)); - - return true; -} - -template -bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, - const string& obj_filename, - const std::vector& debug_dirs, - const DumpOptions& options, - Module** out_module) { - typedef typename ElfClass::Ehdr Ehdr; - - *out_module = NULL; - - scoped_ptr module; - if (!InitModuleForElfClass(elf_header, obj_filename, module)) { - return false; - } - - // Figure out what endianness this file is. - bool big_endian; - if (!ElfEndianness(elf_header, &big_endian)) - return false; - - LoadSymbolsInfo info(debug_dirs); - if (!LoadSymbols(obj_filename, big_endian, elf_header, - !debug_dirs.empty(), &info, - options, module.get())) { - const string debuglink_file = info.debuglink_file(); - if (debuglink_file.empty()) - return false; - - // Load debuglink ELF file. - fprintf(stderr, "Found debugging info in %s\n", debuglink_file.c_str()); - MmapWrapper debug_map_wrapper; - Ehdr* debug_elf_header = NULL; - if (!LoadELF(debuglink_file, &debug_map_wrapper, - reinterpret_cast(&debug_elf_header)) || - !SanitizeDebugFile(debug_elf_header, debuglink_file, - obj_filename, - module->architecture().c_str(), - big_endian)) { - return false; - } - - if (!LoadSymbols(debuglink_file, big_endian, - debug_elf_header, false, &info, - options, module.get())) { - return false; - } - } - - *out_module = module.release(); - return true; -} - -} // namespace - -namespace google_breakpad { - -// Not explicitly exported, but not static so it can be used in unit tests. -bool ReadSymbolDataInternal(const uint8_t* obj_file, - const string& obj_filename, - const std::vector& debug_dirs, - const DumpOptions& options, - Module** module) { - if (!IsValidElf(obj_file)) { - fprintf(stderr, "Not a valid ELF file: %s\n", obj_filename.c_str()); - return false; - } - - int elfclass = ElfClass(obj_file); - if (elfclass == ELFCLASS32) { - return ReadSymbolDataElfClass( - reinterpret_cast(obj_file), obj_filename, debug_dirs, - options, module); - } - if (elfclass == ELFCLASS64) { - return ReadSymbolDataElfClass( - reinterpret_cast(obj_file), obj_filename, debug_dirs, - options, module); - } - - return false; -} - -bool WriteSymbolFile(const string &obj_file, - const std::vector& debug_dirs, - const DumpOptions& options, - std::ostream &sym_stream) { - Module* module; - if (!ReadSymbolData(obj_file, debug_dirs, options, &module)) - return false; - - bool result = module->Write(sym_stream, options.symbol_data); - delete module; - return result; -} - -// Read the selected object file's debugging information, and write out the -// header only to |stream|. Return true on success; if an error occurs, report -// it and return false. -bool WriteSymbolFileHeader(const string& obj_file, - std::ostream &sym_stream) { - MmapWrapper map_wrapper; - void* elf_header = NULL; - if (!LoadELF(obj_file, &map_wrapper, &elf_header)) { - fprintf(stderr, "Could not load ELF file: %s\n", obj_file.c_str()); - return false; - } - - if (!IsValidElf(elf_header)) { - fprintf(stderr, "Not a valid ELF file: %s\n", obj_file.c_str()); - return false; - } - - int elfclass = ElfClass(elf_header); - scoped_ptr module; - if (elfclass == ELFCLASS32) { - if (!InitModuleForElfClass( - reinterpret_cast(elf_header), obj_file, module)) { - fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); - return false; - } - } else if (elfclass == ELFCLASS64) { - if (!InitModuleForElfClass( - reinterpret_cast(elf_header), obj_file, module)) { - fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); - return false; - } - } else { - fprintf(stderr, "Unsupported module file: %s\n", obj_file.c_str()); - return false; - } - - return module->Write(sym_stream, ALL_SYMBOL_DATA); -} - -bool ReadSymbolData(const string& obj_file, - const std::vector& debug_dirs, - const DumpOptions& options, - Module** module) { - MmapWrapper map_wrapper; - void* elf_header = NULL; - if (!LoadELF(obj_file, &map_wrapper, &elf_header)) - return false; - - return ReadSymbolDataInternal(reinterpret_cast(elf_header), - obj_file, debug_dirs, options, module); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.h b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.h deleted file mode 100644 index 1f204cbad..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.h +++ /dev/null @@ -1,86 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_symbols.h: Read debugging information from an ELF file, and write -// it out as a Breakpad symbol file. - -#ifndef COMMON_LINUX_DUMP_SYMBOLS_H__ -#define COMMON_LINUX_DUMP_SYMBOLS_H__ - -#include -#include -#include - -#include "common/symbol_data.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -class Module; - -struct DumpOptions { - DumpOptions(SymbolData symbol_data, bool handle_inter_cu_refs) - : symbol_data(symbol_data), - handle_inter_cu_refs(handle_inter_cu_refs) { - } - - SymbolData symbol_data; - bool handle_inter_cu_refs; -}; - -// Find all the debugging information in OBJ_FILE, an ELF executable -// or shared library, and write it to SYM_STREAM in the Breakpad symbol -// file format. -// If OBJ_FILE has been stripped but contains a .gnu_debuglink section, -// then look for the debug file in DEBUG_DIRS. -// SYMBOL_DATA allows limiting the type of symbol data written. -bool WriteSymbolFile(const string &obj_file, - const std::vector& debug_dirs, - const DumpOptions& options, - std::ostream &sym_stream); - -// Read the selected object file's debugging information, and write out the -// header only to |stream|. Return true on success; if an error occurs, report -// it and return false. -bool WriteSymbolFileHeader(const string& obj_file, - std::ostream &sym_stream); - -// As above, but simply return the debugging information in MODULE -// instead of writing it to a stream. The caller owns the resulting -// Module object and must delete it when finished. -bool ReadSymbolData(const string& obj_file, - const std::vector& debug_dirs, - const DumpOptions& options, - Module** module); - -} // namespace google_breakpad - -#endif // COMMON_LINUX_DUMP_SYMBOLS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols_unittest.cc deleted file mode 100644 index bb7b20076..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols_unittest.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -// dump_symbols_unittest.cc: -// Unittests for google_breakpad::DumpSymbols - -#include -#include -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/elf_gnu_compat.h" -#include "common/linux/elfutils.h" -#include "common/linux/dump_symbols.h" -#include "common/linux/synth_elf.h" -#include "common/module.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -bool ReadSymbolDataInternal(const uint8_t* obj_file, - const string& obj_filename, - const std::vector& debug_dir, - const DumpOptions& options, - Module** module); - -using google_breakpad::synth_elf::ELF; -using google_breakpad::synth_elf::Notes; -using google_breakpad::synth_elf::StringTable; -using google_breakpad::synth_elf::SymbolTable; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Section; -using std::stringstream; -using std::vector; -using ::testing::Test; -using ::testing::Types; - -template -class DumpSymbols : public Test { - public: - void GetElfContents(ELF& elf) { - string contents; - ASSERT_TRUE(elf.GetContents(&contents)); - ASSERT_LT(0U, contents.size()); - - elfdata_v.clear(); - elfdata_v.insert(elfdata_v.begin(), contents.begin(), contents.end()); - elfdata = &elfdata_v[0]; - } - - vector elfdata_v; - uint8_t* elfdata; -}; - -typedef Types ElfClasses; - -TYPED_TEST_CASE(DumpSymbols, ElfClasses); - -TYPED_TEST(DumpSymbols, Invalid) { - Elf32_Ehdr header; - memset(&header, 0, sizeof(header)); - Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true); - EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast(&header), - "foo", - vector(), - options, - &module)); -} - -TYPED_TEST(DumpSymbols, SimplePublic) { - ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); - // Zero out text section for simplicity. - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - - // Add a public symbol. - StringTable table(kLittleEndian); - SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table); - syms.AddSymbol("superfunc", - (typename TypeParam::Addr)0x1000, - (typename TypeParam::Addr)0x10, - // ELF32_ST_INFO works for 32-or 64-bit. - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - SHN_UNDEF + 1); - int index = elf.AddSection(".dynstr", table, SHT_STRTAB); - elf.AddSection(".dynsym", syms, - SHT_DYNSYM, // type - SHF_ALLOC, // flags - 0, // addr - index, // link - sizeof(typename TypeParam::Sym)); // entsize - - elf.Finish(); - this->GetElfContents(elf); - - Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true); - EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, - "foo", - vector(), - options, - &module)); - - stringstream s; - module->Write(s, ALL_SYMBOL_DATA); - const string expected = - string("MODULE Linux ") + TypeParam::kMachineName - + " 000000000000000000000000000000000 foo\n" - "INFO CODE_ID 00000000000000000000000000000000\n" - "PUBLIC 1000 0 superfunc\n"; - EXPECT_EQ(expected, s.str()); - delete module; -} - -TYPED_TEST(DumpSymbols, SimpleBuildID) { - ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); - // Zero out text section for simplicity. - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - - // Add a Build ID - const uint8_t kExpectedIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13}; - Notes notes(kLittleEndian); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, - sizeof(kExpectedIdentifierBytes)); - elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); - - // Add a public symbol. - StringTable table(kLittleEndian); - SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table); - syms.AddSymbol("superfunc", - (typename TypeParam::Addr)0x1000, - (typename TypeParam::Addr)0x10, - // ELF32_ST_INFO works for 32-or 64-bit. - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - SHN_UNDEF + 1); - int index = elf.AddSection(".dynstr", table, SHT_STRTAB); - elf.AddSection(".dynsym", syms, - SHT_DYNSYM, // type - SHF_ALLOC, // flags - 0, // addr - index, // link - sizeof(typename TypeParam::Sym)); // entsize - - elf.Finish(); - this->GetElfContents(elf); - - Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true); - EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, - "foo", - vector(), - options, - &module)); - - stringstream s; - module->Write(s, ALL_SYMBOL_DATA); - const string expected = - string("MODULE Linux ") + TypeParam::kMachineName - + " 030201000504070608090A0B0C0D0E0F0 foo\n" - "INFO CODE_ID 000102030405060708090A0B0C0D0E0F10111213\n" - "PUBLIC 1000 0 superfunc\n"; - EXPECT_EQ(expected, s.str()); - delete module; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/eintr_wrapper.h b/toolkit/crashreporter/google-breakpad/src/common/linux/eintr_wrapper.h deleted file mode 100644 index 3f1d18481..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/eintr_wrapper.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_LINUX_EINTR_WRAPPER_H_ -#define COMMON_LINUX_EINTR_WRAPPER_H_ - -#include - -// This provides a wrapper around system calls which may be interrupted by a -// signal and return EINTR. See man 7 signal. -// - -#define HANDLE_EINTR(x) ({ \ - __typeof__(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ - } while (eintr_wrapper_result == -1 && errno == EINTR); \ - eintr_wrapper_result; \ -}) - -#define IGNORE_EINTR(x) ({ \ - __typeof__(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ - if (eintr_wrapper_result == -1 && errno == EINTR) { \ - eintr_wrapper_result = 0; \ - } \ - } while (0); \ - eintr_wrapper_result; \ -}) - -#endif // COMMON_LINUX_EINTR_WRAPPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.cc deleted file mode 100644 index 0e7db7b1f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.cc +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// elf_core_dump.cc: Implement google_breakpad::ElfCoreDump. -// See elf_core_dump.h for details. - -#include "common/linux/elf_core_dump.h" - -#include -#include - -namespace google_breakpad { - -// Implementation of ElfCoreDump::Note. - -ElfCoreDump::Note::Note() {} - -ElfCoreDump::Note::Note(const MemoryRange& content) : content_(content) {} - -bool ElfCoreDump::Note::IsValid() const { - return GetHeader() != NULL; -} - -const ElfCoreDump::Nhdr* ElfCoreDump::Note::GetHeader() const { - return content_.GetData(0); -} - -ElfCoreDump::Word ElfCoreDump::Note::GetType() const { - const Nhdr* header = GetHeader(); - // 0 is not being used as a NOTE type. - return header ? header->n_type : 0; -} - -MemoryRange ElfCoreDump::Note::GetName() const { - const Nhdr* header = GetHeader(); - if (header) { - return content_.Subrange(sizeof(Nhdr), header->n_namesz); - } - return MemoryRange(); -} - -MemoryRange ElfCoreDump::Note::GetDescription() const { - const Nhdr* header = GetHeader(); - if (header) { - return content_.Subrange(AlignedSize(sizeof(Nhdr) + header->n_namesz), - header->n_descsz); - } - return MemoryRange(); -} - -ElfCoreDump::Note ElfCoreDump::Note::GetNextNote() const { - MemoryRange next_content; - const Nhdr* header = GetHeader(); - if (header) { - size_t next_offset = AlignedSize(sizeof(Nhdr) + header->n_namesz); - next_offset = AlignedSize(next_offset + header->n_descsz); - next_content = - content_.Subrange(next_offset, content_.length() - next_offset); - } - return Note(next_content); -} - -// static -size_t ElfCoreDump::Note::AlignedSize(size_t size) { - size_t mask = sizeof(Word) - 1; - return (size + mask) & ~mask; -} - - -// Implementation of ElfCoreDump. - -ElfCoreDump::ElfCoreDump() {} - -ElfCoreDump::ElfCoreDump(const MemoryRange& content) - : content_(content) { -} - -void ElfCoreDump::SetContent(const MemoryRange& content) { - content_ = content; -} - -bool ElfCoreDump::IsValid() const { - const Ehdr* header = GetHeader(); - return (header && - header->e_ident[0] == ELFMAG0 && - header->e_ident[1] == ELFMAG1 && - header->e_ident[2] == ELFMAG2 && - header->e_ident[3] == ELFMAG3 && - header->e_ident[4] == kClass && - header->e_version == EV_CURRENT && - header->e_type == ET_CORE); -} - -const ElfCoreDump::Ehdr* ElfCoreDump::GetHeader() const { - return content_.GetData(0); -} - -const ElfCoreDump::Phdr* ElfCoreDump::GetProgramHeader(unsigned index) const { - const Ehdr* header = GetHeader(); - if (header) { - return reinterpret_cast(content_.GetArrayElement( - header->e_phoff, header->e_phentsize, index)); - } - return NULL; -} - -const ElfCoreDump::Phdr* ElfCoreDump::GetFirstProgramHeaderOfType( - Word type) const { - for (unsigned i = 0, n = GetProgramHeaderCount(); i < n; ++i) { - const Phdr* program = GetProgramHeader(i); - if (program->p_type == type) { - return program; - } - } - return NULL; -} - -unsigned ElfCoreDump::GetProgramHeaderCount() const { - const Ehdr* header = GetHeader(); - return header ? header->e_phnum : 0; -} - -bool ElfCoreDump::CopyData(void* buffer, Addr virtual_address, size_t length) { - for (unsigned i = 0, n = GetProgramHeaderCount(); i < n; ++i) { - const Phdr* program = GetProgramHeader(i); - if (program->p_type != PT_LOAD) - continue; - - size_t offset_in_segment = virtual_address - program->p_vaddr; - if (virtual_address >= program->p_vaddr && - offset_in_segment < program->p_filesz) { - const void* data = - content_.GetData(program->p_offset + offset_in_segment, length); - if (data) { - memcpy(buffer, data, length); - return true; - } - } - } - return false; -} - -ElfCoreDump::Note ElfCoreDump::GetFirstNote() const { - MemoryRange note_content; - const Phdr* program_header = GetFirstProgramHeaderOfType(PT_NOTE); - if (program_header) { - note_content = content_.Subrange(program_header->p_offset, - program_header->p_filesz); - } - return Note(note_content); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.h b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.h deleted file mode 100644 index d03c7a88d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// elf_core_dump.h: Define the google_breakpad::ElfCoreDump class, which -// encapsulates an ELF core dump file mapped into memory. - -#ifndef COMMON_LINUX_ELF_CORE_DUMP_H_ -#define COMMON_LINUX_ELF_CORE_DUMP_H_ - -#include -#include -#include - -#include "common/memory_range.h" - -namespace google_breakpad { - -// A class encapsulating an ELF core dump file mapped into memory, which -// provides methods for accessing program headers and the note section. -class ElfCoreDump { - public: - // ELF types based on the value of __WORDSIZE. - typedef ElfW(Ehdr) Ehdr; - typedef ElfW(Nhdr) Nhdr; - typedef ElfW(Phdr) Phdr; - typedef ElfW(Word) Word; - typedef ElfW(Addr) Addr; -#if __WORDSIZE == 32 - static const int kClass = ELFCLASS32; -#elif __WORDSIZE == 64 - static const int kClass = ELFCLASS64; -#else -#error "Unsupported __WORDSIZE for ElfCoreDump." -#endif - - // A class encapsulating the note content in a core dump, which provides - // methods for accessing the name and description of a note. - class Note { - public: - Note(); - - // Constructor that takes the note content from |content|. - explicit Note(const MemoryRange& content); - - // Returns true if this note is valid, i,e. a note header is found in - // |content_|, or false otherwise. - bool IsValid() const; - - // Returns the note header, or NULL if no note header is found in - // |content_|. - const Nhdr* GetHeader() const; - - // Returns the note type, or 0 if no note header is found in |content_|. - Word GetType() const; - - // Returns a memory range covering the note name, or an empty range - // if no valid note name is found in |content_|. - MemoryRange GetName() const; - - // Returns a memory range covering the note description, or an empty - // range if no valid note description is found in |content_|. - MemoryRange GetDescription() const; - - // Returns the note following this note, or an empty note if no valid - // note is found after this note. - Note GetNextNote() const; - - private: - // Returns the size in bytes round up to the word alignment, specified - // for the note section, of a given size in bytes. - static size_t AlignedSize(size_t size); - - // Note content. - MemoryRange content_; - }; - - ElfCoreDump(); - - // Constructor that takes the core dump content from |content|. - explicit ElfCoreDump(const MemoryRange& content); - - // Sets the core dump content to |content|. - void SetContent(const MemoryRange& content); - - // Returns true if a valid ELF header in the core dump, or false otherwise. - bool IsValid() const; - - // Returns the ELF header in the core dump, or NULL if no ELF header - // is found in |content_|. - const Ehdr* GetHeader() const; - - // Returns the |index|-th program header in the core dump, or NULL if no - // ELF header is found in |content_| or |index| is out of bounds. - const Phdr* GetProgramHeader(unsigned index) const; - - // Returns the first program header of |type| in the core dump, or NULL if - // no ELF header is found in |content_| or no program header of |type| is - // found. - const Phdr* GetFirstProgramHeaderOfType(Word type) const; - - // Returns the number of program headers in the core dump, or 0 if no - // ELF header is found in |content_|. - unsigned GetProgramHeaderCount() const; - - // Copies |length| bytes of data starting at |virtual_address| in the core - // dump to |buffer|. |buffer| should be a valid pointer to a buffer of at - // least |length| bytes. Returns true if the data to be copied is found in - // the core dump, or false otherwise. - bool CopyData(void* buffer, Addr virtual_address, size_t length); - - // Returns the first note found in the note section of the core dump, or - // an empty note if no note is found. - Note GetFirstNote() const; - - private: - // Core dump content. - MemoryRange content_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_ELF_CORE_DUMP_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump_unittest.cc deleted file mode 100644 index 9b41dceee..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_core_dump_unittest.cc +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// elf_core_dump_unittest.cc: Unit tests for google_breakpad::ElfCoreDump. - -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/elf_core_dump.h" -#include "common/linux/memory_mapped_file.h" -#include "common/tests/file_utils.h" -#include "common/linux/tests/crash_generator.h" -#include "common/using_std_string.h" - -using google_breakpad::AutoTempDir; -using google_breakpad::CrashGenerator; -using google_breakpad::ElfCoreDump; -using google_breakpad::MemoryMappedFile; -using google_breakpad::MemoryRange; -using google_breakpad::WriteFile; -using std::set; - -TEST(ElfCoreDumpTest, DefaultConstructor) { - ElfCoreDump core; - EXPECT_FALSE(core.IsValid()); - EXPECT_EQ(NULL, core.GetHeader()); - EXPECT_EQ(0U, core.GetProgramHeaderCount()); - EXPECT_EQ(NULL, core.GetProgramHeader(0)); - EXPECT_EQ(NULL, core.GetFirstProgramHeaderOfType(PT_LOAD)); - EXPECT_FALSE(core.GetFirstNote().IsValid()); -} - -TEST(ElfCoreDumpTest, TestElfHeader) { - ElfCoreDump::Ehdr header; - memset(&header, 0, sizeof(header)); - - AutoTempDir temp_dir; - string core_path = temp_dir.path() + "/core"; - const char* core_file = core_path.c_str(); - MemoryMappedFile mapped_core_file; - ElfCoreDump core; - - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header) - 1)); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - EXPECT_EQ(NULL, core.GetHeader()); - EXPECT_EQ(0U, core.GetProgramHeaderCount()); - EXPECT_EQ(NULL, core.GetProgramHeader(0)); - EXPECT_EQ(NULL, core.GetFirstProgramHeaderOfType(PT_LOAD)); - EXPECT_FALSE(core.GetFirstNote().IsValid()); - - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_ident[0] = ELFMAG0; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_ident[1] = ELFMAG1; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_ident[2] = ELFMAG2; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_ident[3] = ELFMAG3; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_ident[4] = ElfCoreDump::kClass; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_version = EV_CURRENT; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_FALSE(core.IsValid()); - - header.e_type = ET_CORE; - ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); - ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); - core.SetContent(mapped_core_file.content()); - EXPECT_TRUE(core.IsValid()); -} - -TEST(ElfCoreDumpTest, ValidCoreFile) { - CrashGenerator crash_generator; - if (!crash_generator.HasDefaultCorePattern()) { - fprintf(stderr, "ElfCoreDumpTest.ValidCoreFile test is skipped " - "due to non-default core pattern"); - return; - } - - const unsigned kNumOfThreads = 3; - const unsigned kCrashThread = 1; - const int kCrashSignal = SIGABRT; - ASSERT_TRUE(crash_generator.CreateChildCrash(kNumOfThreads, kCrashThread, - kCrashSignal, NULL)); - pid_t expected_crash_thread_id = crash_generator.GetThreadId(kCrashThread); - set expected_thread_ids; - for (unsigned i = 0; i < kNumOfThreads; ++i) { - expected_thread_ids.insert(crash_generator.GetThreadId(i)); - } - -#if defined(__ANDROID__) - struct stat st; - if (stat(crash_generator.GetCoreFilePath().c_str(), &st) != 0) { - fprintf(stderr, "ElfCoreDumpTest.ValidCoreFile test is skipped " - "due to no core file being generated"); - return; - } -#endif - - MemoryMappedFile mapped_core_file; - ASSERT_TRUE( - mapped_core_file.Map(crash_generator.GetCoreFilePath().c_str(), 0)); - - ElfCoreDump core; - core.SetContent(mapped_core_file.content()); - EXPECT_TRUE(core.IsValid()); - - // Based on write_note_info() in linux/kernel/fs/binfmt_elf.c, notes are - // ordered as follows (NT_PRXFPREG and NT_386_TLS are i386 specific): - // Thread Name Type - // ------------------------------------------------------------------- - // 1st thread CORE NT_PRSTATUS - // process-wide CORE NT_PRPSINFO - // process-wide CORE NT_AUXV - // 1st thread CORE NT_FPREGSET - // 1st thread LINUX NT_PRXFPREG - // 1st thread LINUX NT_386_TLS - // - // 2nd thread CORE NT_PRSTATUS - // 2nd thread CORE NT_FPREGSET - // 2nd thread LINUX NT_PRXFPREG - // 2nd thread LINUX NT_386_TLS - // - // 3rd thread CORE NT_PRSTATUS - // 3rd thread CORE NT_FPREGSET - // 3rd thread LINUX NT_PRXFPREG - // 3rd thread LINUX NT_386_TLS - - size_t num_nt_prpsinfo = 0; - size_t num_nt_prstatus = 0; - size_t num_pr_fpvalid = 0; -#if defined(__i386__) || defined(__x86_64__) - size_t num_nt_fpregset = 0; -#endif -#if defined(__i386__) - size_t num_nt_prxfpreg = 0; -#endif - set actual_thread_ids; - ElfCoreDump::Note note = core.GetFirstNote(); - while (note.IsValid()) { - MemoryRange name = note.GetName(); - MemoryRange description = note.GetDescription(); - EXPECT_FALSE(name.IsEmpty()); - EXPECT_FALSE(description.IsEmpty()); - - switch (note.GetType()) { - case NT_PRPSINFO: { - EXPECT_TRUE(description.data() != NULL); - EXPECT_EQ(sizeof(elf_prpsinfo), description.length()); - ++num_nt_prpsinfo; - break; - } - case NT_PRSTATUS: { - EXPECT_TRUE(description.data() != NULL); - EXPECT_EQ(sizeof(elf_prstatus), description.length()); - const elf_prstatus* status = description.GetData(0); - actual_thread_ids.insert(status->pr_pid); - if (num_nt_prstatus == 0) { - EXPECT_EQ(expected_crash_thread_id, status->pr_pid); - EXPECT_EQ(kCrashSignal, status->pr_info.si_signo); - } - ++num_nt_prstatus; - if (status->pr_fpvalid) - ++num_pr_fpvalid; - break; - } -#if defined(__i386__) || defined(__x86_64__) - case NT_FPREGSET: { - EXPECT_TRUE(description.data() != NULL); - EXPECT_EQ(sizeof(user_fpregs_struct), description.length()); - ++num_nt_fpregset; - break; - } -#endif -#if defined(__i386__) - case NT_PRXFPREG: { - EXPECT_TRUE(description.data() != NULL); - EXPECT_EQ(sizeof(user_fpxregs_struct), description.length()); - ++num_nt_prxfpreg; - break; - } -#endif - default: - break; - } - note = note.GetNextNote(); - } - - EXPECT_TRUE(expected_thread_ids == actual_thread_ids); - EXPECT_EQ(1U, num_nt_prpsinfo); - EXPECT_EQ(kNumOfThreads, num_nt_prstatus); -#if defined(__i386__) || defined(__x86_64__) - EXPECT_EQ(num_pr_fpvalid, num_nt_fpregset); -#endif -#if defined(__i386__) - EXPECT_EQ(num_pr_fpvalid, num_nt_prxfpreg); -#endif -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_gnu_compat.h b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_gnu_compat.h deleted file mode 100644 index f870cbc7d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_gnu_compat.h +++ /dev/null @@ -1,46 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Lei Zhang - -// elf_gnu_compat.h: #defines unique to glibc's elf.h. - -#ifndef COMMON_LINUX_ELF_GNU_COMPAT_H_ -#define COMMON_LINUX_ELF_GNU_COMPAT_H_ - -#include - -// A note type on GNU systems corresponding to the .note.gnu.build-id section. -#ifndef NT_GNU_BUILD_ID -#define NT_GNU_BUILD_ID 3 -#endif - -#endif // COMMON_LINUX_ELF_GNU_COMPAT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.cc deleted file mode 100644 index 562875e11..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.cc +++ /dev/null @@ -1,178 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -#include "common/linux/elf_symbols_to_module.h" - -#include -#include -#include - -#include "common/byte_cursor.h" -#include "common/module.h" - -namespace google_breakpad { - -class ELFSymbolIterator { -public: - // The contents of an ELF symbol, adjusted for the host's endianness, - // word size, and so on. Corresponds to the data in Elf32_Sym / Elf64_Sym. - struct Symbol { - // True if this iterator has reached the end of the symbol array. When - // this is set, the other members of this structure are not valid. - bool at_end; - - // The number of this symbol within the list. - size_t index; - - // The current symbol's name offset. This is the offset within the - // string table. - size_t name_offset; - - // The current symbol's value, size, info and shndx fields. - uint64_t value; - uint64_t size; - unsigned char info; - uint16_t shndx; - }; - - // Create an ELFSymbolIterator walking the symbols in BUFFER. Treat the - // symbols as big-endian if BIG_ENDIAN is true, as little-endian - // otherwise. Assume each symbol has a 'value' field whose size is - // VALUE_SIZE. - // - ELFSymbolIterator(const ByteBuffer *buffer, bool big_endian, - size_t value_size) - : value_size_(value_size), cursor_(buffer, big_endian) { - // Actually, weird sizes could be handled just fine, but they're - // probably mistakes --- expressed in bits, say. - assert(value_size == 4 || value_size == 8); - symbol_.index = 0; - Fetch(); - } - - // Move to the next symbol. This function's behavior is undefined if - // at_end() is true when it is called. - ELFSymbolIterator &operator++() { Fetch(); symbol_.index++; return *this; } - - // Dereferencing this iterator produces a reference to an Symbol structure - // that holds the current symbol's values. The symbol is owned by this - // SymbolIterator, and will be invalidated at the next call to operator++. - const Symbol &operator*() const { return symbol_; } - const Symbol *operator->() const { return &symbol_; } - -private: - // Read the symbol at cursor_, and set symbol_ appropriately. - void Fetch() { - // Elf32_Sym and Elf64_Sym have different layouts. - unsigned char other; - if (value_size_ == 4) { - // Elf32_Sym - cursor_ - .Read(4, false, &symbol_.name_offset) - .Read(4, false, &symbol_.value) - .Read(4, false, &symbol_.size) - .Read(1, false, &symbol_.info) - .Read(1, false, &other) - .Read(2, false, &symbol_.shndx); - } else { - // Elf64_Sym - cursor_ - .Read(4, false, &symbol_.name_offset) - .Read(1, false, &symbol_.info) - .Read(1, false, &other) - .Read(2, false, &symbol_.shndx) - .Read(8, false, &symbol_.value) - .Read(8, false, &symbol_.size); - } - symbol_.at_end = !cursor_; - } - - // The size of symbols' value field, in bytes. - size_t value_size_; - - // A byte cursor traversing buffer_. - ByteCursor cursor_; - - // Values for the symbol this iterator refers to. - Symbol symbol_; -}; - -const char *SymbolString(ptrdiff_t offset, ByteBuffer& strings) { - if (offset < 0 || (size_t) offset >= strings.Size()) { - // Return the null string. - offset = 0; - } - return reinterpret_cast(strings.start + offset); -} - -bool ELFSymbolsToModule(const uint8_t *symtab_section, - size_t symtab_size, - const uint8_t *string_section, - size_t string_size, - const bool big_endian, - size_t value_size, - Module *module) { - ByteBuffer symbols(symtab_section, symtab_size); - // Ensure that the string section is null-terminated. - if (string_section[string_size - 1] != '\0') { - const void* null_terminator = memrchr(string_section, '\0', string_size); - string_size = reinterpret_cast(null_terminator) - - string_section; - } - ByteBuffer strings(string_section, string_size); - - // The iterator walking the symbol table. - ELFSymbolIterator iterator(&symbols, big_endian, value_size); - - while(!iterator->at_end) { - if (ELF32_ST_TYPE(iterator->info) == STT_FUNC && - iterator->shndx != SHN_UNDEF) { - Module::Extern *ext = new Module::Extern(iterator->value); - ext->name = SymbolString(iterator->name_offset, strings); -#if !defined(__ANDROID__) // Android NDK doesn't provide abi::__cxa_demangle. - int status = 0; - char* demangled = - abi::__cxa_demangle(ext->name.c_str(), NULL, NULL, &status); - if (demangled) { - if (status == 0) - ext->name = demangled; - free(demangled); - } -#endif - module->AddExtern(ext); - } - ++iterator; - } - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.h deleted file mode 100644 index 2e7c09715..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module.h +++ /dev/null @@ -1,58 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -// elf_symbols_to_module.h: Exposes ELFSymbolsToModule, a function -// for reading ELF symbol tables and inserting exported symbol names -// into a google_breakpad::Module as Extern definitions. - -#ifndef BREAKPAD_COMMON_LINUX_ELF_SYMBOLS_TO_MODULE_H_ -#define BREAKPAD_COMMON_LINUX_ELF_SYMBOLS_TO_MODULE_H_ - -#include -#include - -namespace google_breakpad { - -class Module; - -bool ELFSymbolsToModule(const uint8_t *symtab_section, - size_t symtab_size, - const uint8_t *string_section, - size_t string_size, - const bool big_endian, - size_t value_size, - Module *module); - -} // namespace google_breakpad - - -#endif // BREAKPAD_COMMON_LINUX_ELF_SYMBOLS_TO_MODULE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module_unittest.cc deleted file mode 100644 index 8984449ab..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elf_symbols_to_module_unittest.cc +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -// elf_symbols_to_module_unittest.cc: -// Unittests for google_breakpad::ELFSymbolsToModule - -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/elf_symbols_to_module.h" -#include "common/linux/synth_elf.h" -#include "common/module.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" - -using google_breakpad::Module; -using google_breakpad::synth_elf::StringTable; -using google_breakpad::test_assembler::Endianness; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using ::testing::Test; -using ::testing::TestWithParam; -using std::vector; - -class ELFSymbolsToModuleTestFixture { -public: - ELFSymbolsToModuleTestFixture(Endianness endianness, - size_t value_size) : module("a", "b", "c", "d"), - section(endianness), - table(endianness), - value_size(value_size) {} - - bool ProcessSection() { - string section_contents, table_contents; - section.GetContents(§ion_contents); - table.GetContents(&table_contents); - - bool ret = ELFSymbolsToModule(reinterpret_cast(section_contents.data()), - section_contents.size(), - reinterpret_cast(table_contents.data()), - table_contents.size(), - section.endianness() == kBigEndian, - value_size, - &module); - module.GetExterns(&externs, externs.end()); - return ret; - } - - Module module; - Section section; - StringTable table; - string section_contents; - // 4 or 8 (bytes) - size_t value_size; - - vector externs; -}; - -class ELFSymbolsToModuleTest32 : public ELFSymbolsToModuleTestFixture, - public TestWithParam { -public: - ELFSymbolsToModuleTest32() : ELFSymbolsToModuleTestFixture(GetParam(), 4) {} - - void AddElf32Sym(const string& name, uint32_t value, - uint32_t size, unsigned info, uint16_t shndx) { - section - .D32(table.Add(name)) - .D32(value) - .D32(size) - .D8(info) - .D8(0) // other - .D16(shndx); - } -}; - -TEST_P(ELFSymbolsToModuleTest32, NoFuncs) { - ProcessSection(); - - ASSERT_EQ((size_t)0, externs.size()); -} - -TEST_P(ELFSymbolsToModuleTest32, OneFunc) { - const string kFuncName = "superfunc"; - const uint32_t kFuncAddr = 0x1000; - const uint32_t kFuncSize = 0x10; - - AddElf32Sym(kFuncName, kFuncAddr, kFuncSize, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -TEST_P(ELFSymbolsToModuleTest32, NameOutOfBounds) { - const string kFuncName = ""; - const uint32_t kFuncAddr = 0x1000; - const uint32_t kFuncSize = 0x10; - - table.Add("Foo"); - table.Add("Bar"); - // Can't use AddElf32Sym because it puts in a valid string offset. - section - .D32((uint32_t)table.Here().Value() + 1) - .D32(kFuncAddr) - .D32(kFuncSize) - .D8(ELF32_ST_INFO(STB_GLOBAL, STT_FUNC)) - .D8(0) // other - .D16(SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -TEST_P(ELFSymbolsToModuleTest32, NonTerminatedStringTable) { - const string kFuncName = ""; - const uint32_t kFuncAddr = 0x1000; - const uint32_t kFuncSize = 0x10; - - table.Add("Foo"); - table.Add("Bar"); - // Add a non-null-terminated string to the end of the string table - Label l; - table - .Mark(&l) - .Append("Unterminated"); - // Can't use AddElf32Sym because it puts in a valid string offset. - section - .D32((uint32_t)l.Value()) - .D32(kFuncAddr) - .D32(kFuncSize) - .D8(ELF32_ST_INFO(STB_GLOBAL, STT_FUNC)) - .D8(0) // other - .D16(SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -TEST_P(ELFSymbolsToModuleTest32, MultipleFuncs) { - const string kFuncName1 = "superfunc"; - const uint32_t kFuncAddr1 = 0x10001000; - const uint32_t kFuncSize1 = 0x10; - const string kFuncName2 = "awesomefunc"; - const uint32_t kFuncAddr2 = 0x20002000; - const uint32_t kFuncSize2 = 0x2f; - const string kFuncName3 = "megafunc"; - const uint32_t kFuncAddr3 = 0x30003000; - const uint32_t kFuncSize3 = 0x3c; - - AddElf32Sym(kFuncName1, kFuncAddr1, kFuncSize1, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - AddElf32Sym(kFuncName2, kFuncAddr2, kFuncSize2, - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 2); - AddElf32Sym(kFuncName3, kFuncAddr3, kFuncSize3, - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 3); - - ProcessSection(); - - ASSERT_EQ((size_t)3, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName1, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr1, extern1->address); - Module::Extern *extern2 = externs[1]; - EXPECT_EQ(kFuncName2, extern2->name); - EXPECT_EQ((Module::Address)kFuncAddr2, extern2->address); - Module::Extern *extern3 = externs[2]; - EXPECT_EQ(kFuncName3, extern3->name); - EXPECT_EQ((Module::Address)kFuncAddr3, extern3->address); -} - -TEST_P(ELFSymbolsToModuleTest32, SkipStuff) { - const string kFuncName = "superfunc"; - const uint32_t kFuncAddr = 0x1000; - const uint32_t kFuncSize = 0x10; - - // Should skip functions in SHN_UNDEF - AddElf32Sym("skipme", 0xFFFF, 0x10, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - SHN_UNDEF); - AddElf32Sym(kFuncName, kFuncAddr, kFuncSize, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - // Should skip non-STT_FUNC entries. - AddElf32Sym("skipmetoo", 0xAAAA, 0x10, - ELF32_ST_INFO(STB_GLOBAL, STT_FILE), - SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -// Run all the 32-bit tests with both endianness -INSTANTIATE_TEST_CASE_P(Endian, - ELFSymbolsToModuleTest32, - ::testing::Values(kLittleEndian, kBigEndian)); - -// Similar tests, but with 64-bit values. Ostensibly this could be -// shoehorned into the parameterization by using ::testing::Combine, -// but that would make it difficult to get the types right since these -// actual test cases aren't parameterized. This could also be written -// as a type-parameterized test, but combining that with a value-parameterized -// test seemed really ugly, and also makes it harder to test 64-bit -// values. -class ELFSymbolsToModuleTest64 : public ELFSymbolsToModuleTestFixture, - public TestWithParam { -public: - ELFSymbolsToModuleTest64() : ELFSymbolsToModuleTestFixture(GetParam(), 8) {} - - void AddElf64Sym(const string& name, uint64_t value, - uint64_t size, unsigned info, uint16_t shndx) { - section - .D32(table.Add(name)) - .D8(info) - .D8(0) // other - .D16(shndx) - .D64(value) - .D64(size); - } -}; - -TEST_P(ELFSymbolsToModuleTest64, NoFuncs) { - ProcessSection(); - - ASSERT_EQ((size_t)0, externs.size()); -} - -TEST_P(ELFSymbolsToModuleTest64, OneFunc) { - const string kFuncName = "superfunc"; - const uint64_t kFuncAddr = 0x1000200030004000ULL; - const uint64_t kFuncSize = 0x1000; - - AddElf64Sym(kFuncName, kFuncAddr, kFuncSize, - ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -TEST_P(ELFSymbolsToModuleTest64, MultipleFuncs) { - const string kFuncName1 = "superfunc"; - const uint64_t kFuncAddr1 = 0x1000100010001000ULL; - const uint64_t kFuncSize1 = 0x1000; - const string kFuncName2 = "awesomefunc"; - const uint64_t kFuncAddr2 = 0x2000200020002000ULL; - const uint64_t kFuncSize2 = 0x2f00; - const string kFuncName3 = "megafunc"; - const uint64_t kFuncAddr3 = 0x3000300030003000ULL; - const uint64_t kFuncSize3 = 0x3c00; - - AddElf64Sym(kFuncName1, kFuncAddr1, kFuncSize1, - ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - AddElf64Sym(kFuncName2, kFuncAddr2, kFuncSize2, - ELF64_ST_INFO(STB_LOCAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 2); - AddElf64Sym(kFuncName3, kFuncAddr3, kFuncSize3, - ELF64_ST_INFO(STB_LOCAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 3); - - ProcessSection(); - - ASSERT_EQ((size_t)3, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName1, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr1, extern1->address); - Module::Extern *extern2 = externs[1]; - EXPECT_EQ(kFuncName2, extern2->name); - EXPECT_EQ((Module::Address)kFuncAddr2, extern2->address); - Module::Extern *extern3 = externs[2]; - EXPECT_EQ(kFuncName3, extern3->name); - EXPECT_EQ((Module::Address)kFuncAddr3, extern3->address); -} - -TEST_P(ELFSymbolsToModuleTest64, SkipStuff) { - const string kFuncName = "superfunc"; - const uint64_t kFuncAddr = 0x1000100010001000ULL; - const uint64_t kFuncSize = 0x1000; - - // Should skip functions in SHN_UNDEF - AddElf64Sym("skipme", 0xFFFF, 0x10, - ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), - SHN_UNDEF); - AddElf64Sym(kFuncName, kFuncAddr, kFuncSize, - ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), - // Doesn't really matter, just can't be SHN_UNDEF. - SHN_UNDEF + 1); - // Should skip non-STT_FUNC entries. - AddElf64Sym("skipmetoo", 0xAAAA, 0x10, - ELF64_ST_INFO(STB_GLOBAL, STT_FILE), - SHN_UNDEF + 1); - - ProcessSection(); - - ASSERT_EQ((size_t)1, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_EQ(kFuncName, extern1->name); - EXPECT_EQ((Module::Address)kFuncAddr, extern1->address); -} - -// Run all the 64-bit tests with both endianness -INSTANTIATE_TEST_CASE_P(Endian, - ELFSymbolsToModuleTest64, - ::testing::Values(kLittleEndian, kBigEndian)); diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils-inl.h b/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils-inl.h deleted file mode 100644 index e56b37a9f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils-inl.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_LINUX_ELFUTILS_INL_H__ -#define COMMON_LINUX_ELFUTILS_INL_H__ - -#include "common/linux/linux_libc_support.h" -#include "elfutils.h" - -namespace google_breakpad { - -template -const T* GetOffset(const typename ElfClass::Ehdr* elf_header, - typename ElfClass::Off offset) { - return reinterpret_cast(reinterpret_cast(elf_header) + - offset); -} - -template -const typename ElfClass::Shdr* FindElfSectionByName( - const char* name, - typename ElfClass::Word section_type, - const typename ElfClass::Shdr* sections, - const char* section_names, - const char* names_end, - int nsection) { - assert(name != NULL); - assert(sections != NULL); - assert(nsection > 0); - - int name_len = my_strlen(name); - if (name_len == 0) - return NULL; - - for (int i = 0; i < nsection; ++i) { - const char* section_name = section_names + sections[i].sh_name; - if (sections[i].sh_type == section_type && - names_end - section_name >= name_len + 1 && - my_strcmp(name, section_name) == 0) { - return sections + i; - } - } - return NULL; -} - -} // namespace google_breakpad - -#endif // COMMON_LINUX_ELFUTILS_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc deleted file mode 100644 index a79391c13..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/linux/elfutils.h" - -#include -#include - -#include "common/linux/linux_libc_support.h" -#include "common/linux/elfutils-inl.h" - -namespace google_breakpad { - -namespace { - -template -void FindElfClassSection(const char *elf_base, - const char *section_name, - typename ElfClass::Word section_type, - const void **section_start, - size_t *section_size) { - typedef typename ElfClass::Ehdr Ehdr; - typedef typename ElfClass::Shdr Shdr; - - assert(elf_base); - assert(section_start); - assert(section_size); - - assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); - - const Ehdr* elf_header = reinterpret_cast(elf_base); - assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); - - const Shdr* sections = - GetOffset(elf_header, elf_header->e_shoff); - const Shdr* section_names = sections + elf_header->e_shstrndx; - const char* names = - GetOffset(elf_header, section_names->sh_offset); - const char *names_end = names + section_names->sh_size; - - const Shdr* section = - FindElfSectionByName(section_name, section_type, - sections, names, names_end, - elf_header->e_shnum); - - if (section != NULL && section->sh_size > 0) { - *section_start = elf_base + section->sh_offset; - *section_size = section->sh_size; - } -} - -template -void FindElfClassSegment(const char *elf_base, - typename ElfClass::Word segment_type, - const void **segment_start, - size_t *segment_size) { - typedef typename ElfClass::Ehdr Ehdr; - typedef typename ElfClass::Phdr Phdr; - - assert(elf_base); - assert(segment_start); - assert(segment_size); - - assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); - - const Ehdr* elf_header = reinterpret_cast(elf_base); - assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); - - const Phdr* phdrs = - GetOffset(elf_header, elf_header->e_phoff); - - for (int i = 0; i < elf_header->e_phnum; ++i) { - if (phdrs[i].p_type == segment_type) { - *segment_start = elf_base + phdrs[i].p_offset; - *segment_size = phdrs[i].p_filesz; - return; - } - } -} - -} // namespace - -bool IsValidElf(const void* elf_base) { - return my_strncmp(reinterpret_cast(elf_base), - ELFMAG, SELFMAG) == 0; -} - -int ElfClass(const void* elf_base) { - const ElfW(Ehdr)* elf_header = - reinterpret_cast(elf_base); - - return elf_header->e_ident[EI_CLASS]; -} - -bool FindElfSection(const void *elf_mapped_base, - const char *section_name, - uint32_t section_type, - const void **section_start, - size_t *section_size, - int *elfclass) { - assert(elf_mapped_base); - assert(section_start); - assert(section_size); - - *section_start = NULL; - *section_size = 0; - - if (!IsValidElf(elf_mapped_base)) - return false; - - int cls = ElfClass(elf_mapped_base); - if (elfclass) { - *elfclass = cls; - } - - const char* elf_base = - static_cast(elf_mapped_base); - - if (cls == ELFCLASS32) { - FindElfClassSection(elf_base, section_name, section_type, - section_start, section_size); - return *section_start != NULL; - } else if (cls == ELFCLASS64) { - FindElfClassSection(elf_base, section_name, section_type, - section_start, section_size); - return *section_start != NULL; - } - - return false; -} - -bool FindElfSegment(const void *elf_mapped_base, - uint32_t segment_type, - const void **segment_start, - size_t *segment_size, - int *elfclass) { - assert(elf_mapped_base); - assert(segment_start); - assert(segment_size); - - *segment_start = NULL; - *segment_size = 0; - - if (!IsValidElf(elf_mapped_base)) - return false; - - int cls = ElfClass(elf_mapped_base); - if (elfclass) { - *elfclass = cls; - } - - const char* elf_base = - static_cast(elf_mapped_base); - - if (cls == ELFCLASS32) { - FindElfClassSegment(elf_base, segment_type, - segment_start, segment_size); - return *segment_start != NULL; - } else if (cls == ELFCLASS64) { - FindElfClassSegment(elf_base, segment_type, - segment_start, segment_size); - return *segment_start != NULL; - } - - return false; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.h b/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.h deleted file mode 100644 index f34ba8314..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// elfutils.h: Utilities for dealing with ELF files. -// - -#ifndef COMMON_LINUX_ELFUTILS_H_ -#define COMMON_LINUX_ELFUTILS_H_ - -#include -#include -#include - -namespace google_breakpad { - -// Traits classes so consumers can write templatized code to deal -// with specific ELF bits. -struct ElfClass32 { - typedef Elf32_Addr Addr; - typedef Elf32_Ehdr Ehdr; - typedef Elf32_Nhdr Nhdr; - typedef Elf32_Phdr Phdr; - typedef Elf32_Shdr Shdr; - typedef Elf32_Half Half; - typedef Elf32_Off Off; - typedef Elf32_Sym Sym; - typedef Elf32_Word Word; - - static const int kClass = ELFCLASS32; - static const uint16_t kMachine = EM_386; - static const size_t kAddrSize = sizeof(Elf32_Addr); - static constexpr const char* kMachineName = "x86"; -}; - -struct ElfClass64 { - typedef Elf64_Addr Addr; - typedef Elf64_Ehdr Ehdr; - typedef Elf64_Nhdr Nhdr; - typedef Elf64_Phdr Phdr; - typedef Elf64_Shdr Shdr; - typedef Elf64_Half Half; - typedef Elf64_Off Off; - typedef Elf64_Sym Sym; - typedef Elf64_Word Word; - - static const int kClass = ELFCLASS64; - static const uint16_t kMachine = EM_X86_64; - static const size_t kAddrSize = sizeof(Elf64_Addr); - static constexpr const char* kMachineName = "x86_64"; -}; - -bool IsValidElf(const void* elf_header); -int ElfClass(const void* elf_base); - -// Attempt to find a section named |section_name| of type |section_type| -// in the ELF binary data at |elf_mapped_base|. On success, returns true -// and sets |*section_start| to point to the start of the section data, -// and |*section_size| to the size of the section's data. If |elfclass| -// is not NULL, set |*elfclass| to the ELF file class. -bool FindElfSection(const void *elf_mapped_base, - const char *section_name, - uint32_t section_type, - const void **section_start, - size_t *section_size, - int *elfclass); - -// Internal helper method, exposed for convenience for callers -// that already have more info. -template -const typename ElfClass::Shdr* -FindElfSectionByName(const char* name, - typename ElfClass::Word section_type, - const typename ElfClass::Shdr* sections, - const char* section_names, - const char* names_end, - int nsection); - -// Attempt to find the first segment of type |segment_type| in the ELF -// binary data at |elf_mapped_base|. On success, returns true and sets -// |*segment_start| to point to the start of the segment data, and -// and |*segment_size| to the size of the segment's data. If |elfclass| -// is not NULL, set |*elfclass| to the ELF file class. -bool FindElfSegment(const void *elf_mapped_base, - uint32_t segment_type, - const void **segment_start, - size_t *segment_size, - int *elfclass); - -// Convert an offset from an Elf header into a pointer to the mapped -// address in the current process. Takes an extra template parameter -// to specify the return type to avoid having to dynamic_cast the -// result. -template -const T* -GetOffset(const typename ElfClass::Ehdr* elf_header, - typename ElfClass::Off offset); - -} // namespace google_breakpad - -#endif // COMMON_LINUX_ELFUTILS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc deleted file mode 100644 index 311e03020..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// file_id.cc: Return a unique identifier for a file -// -// See file_id.h for documentation -// - -#include "common/linux/file_id.h" - -#include -#include -#include - -#include -#include - -#include "common/linux/elf_gnu_compat.h" -#include "common/linux/elfutils.h" -#include "common/linux/linux_libc_support.h" -#include "common/linux/memory_mapped_file.h" -#include "common/using_std_string.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -// Used in a few places for backwards-compatibility. -const size_t kMDGUIDSize = sizeof(MDGUID); - -FileID::FileID(const char* path) : path_(path) {} - -// ELF note name and desc are 32-bits word padded. -#define NOTE_PADDING(a) ((a + 3) & ~3) - -// These functions are also used inside the crashed process, so be safe -// and use the syscall/libc wrappers instead of direct syscalls or libc. - -template -static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length, - wasteful_vector& identifier) { - typedef typename ElfClass::Nhdr Nhdr; - - const void* section_end = reinterpret_cast(section) + length; - const Nhdr* note_header = reinterpret_cast(section); - while (reinterpret_cast(note_header) < section_end) { - if (note_header->n_type == NT_GNU_BUILD_ID) - break; - note_header = reinterpret_cast( - reinterpret_cast(note_header) + sizeof(Nhdr) + - NOTE_PADDING(note_header->n_namesz) + - NOTE_PADDING(note_header->n_descsz)); - } - if (reinterpret_cast(note_header) >= section_end || - note_header->n_descsz == 0) { - return false; - } - - const uint8_t* build_id = reinterpret_cast(note_header) + - sizeof(Nhdr) + NOTE_PADDING(note_header->n_namesz); - identifier.insert(identifier.end(), - build_id, - build_id + note_header->n_descsz); - - return true; -} - -// Attempt to locate a .note.gnu.build-id section in an ELF binary -// and copy it into |identifier|. -static bool FindElfBuildIDNote(const void* elf_mapped_base, - wasteful_vector& identifier) { - void* note_section; - size_t note_size; - int elfclass; - if ((!FindElfSegment(elf_mapped_base, PT_NOTE, - (const void**)¬e_section, ¬e_size, &elfclass) || - note_size == 0) && - (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, - (const void**)¬e_section, ¬e_size, &elfclass) || - note_size == 0)) { - return false; - } - - if (elfclass == ELFCLASS32) { - return ElfClassBuildIDNoteIdentifier(note_section, note_size, - identifier); - } else if (elfclass == ELFCLASS64) { - return ElfClassBuildIDNoteIdentifier(note_section, note_size, - identifier); - } - - return false; -} - -// Attempt to locate the .text section of an ELF binary and generate -// a simple hash by XORing the first page worth of bytes into |identifier|. -static bool HashElfTextSection(const void* elf_mapped_base, - wasteful_vector& identifier) { - identifier.resize(kMDGUIDSize); - - void* text_section; - size_t text_size; - if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, - (const void**)&text_section, &text_size, NULL) || - text_size == 0) { - return false; - } - - // Only provide |kMDGUIDSize| bytes to keep identifiers produced by this - // function backwards-compatible. - my_memset(&identifier[0], 0, kMDGUIDSize); - const uint8_t* ptr = reinterpret_cast(text_section); - const uint8_t* ptr_end = ptr + std::min(text_size, static_cast(4096)); - while (ptr < ptr_end) { - for (unsigned i = 0; i < kMDGUIDSize; i++) - identifier[i] ^= ptr[i]; - ptr += kMDGUIDSize; - } - return true; -} - -// static -bool FileID::ElfFileIdentifierFromMappedFile(const void* base, - wasteful_vector& identifier) { - // Look for a build id note first. - if (FindElfBuildIDNote(base, identifier)) - return true; - - // Fall back on hashing the first page of the text section. - return HashElfTextSection(base, identifier); -} - -bool FileID::ElfFileIdentifier(wasteful_vector& identifier) { - MemoryMappedFile mapped_file(path_.c_str(), 0); - if (!mapped_file.data()) // Should probably check if size >= ElfW(Ehdr)? - return false; - - return ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier); -} - -// These three functions are not ever called in an unsafe context, so it's OK -// to allocate memory and use libc. -static string bytes_to_hex_string(const uint8_t* bytes, size_t count) { - string result; - for (unsigned int idx = 0; idx < count; ++idx) { - char buf[3]; - snprintf(buf, sizeof(buf), "%02X", bytes[idx]); - result.append(buf); - } - return result; -} - -// static -string FileID::ConvertIdentifierToUUIDString( - const wasteful_vector& identifier) { - uint8_t identifier_swapped[kMDGUIDSize] = { 0 }; - - // Endian-ness swap to match dump processor expectation. - memcpy(identifier_swapped, &identifier[0], - std::min(kMDGUIDSize, identifier.size())); - uint32_t* data1 = reinterpret_cast(identifier_swapped); - *data1 = htonl(*data1); - uint16_t* data2 = reinterpret_cast(identifier_swapped + 4); - *data2 = htons(*data2); - uint16_t* data3 = reinterpret_cast(identifier_swapped + 6); - *data3 = htons(*data3); - - return bytes_to_hex_string(identifier_swapped, kMDGUIDSize); -} - -// static -string FileID::ConvertIdentifierToString( - const wasteful_vector& identifier) { - return bytes_to_hex_string(&identifier[0], identifier.size()); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.h b/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.h deleted file mode 100644 index a1d2fd6ed..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// file_id.h: Return a unique identifier for a file -// - -#ifndef COMMON_LINUX_FILE_ID_H__ -#define COMMON_LINUX_FILE_ID_H__ - -#include -#include - -#include "common/linux/guid_creator.h" -#include "common/memory.h" - -namespace google_breakpad { - -// GNU binutils' ld defaults to 'sha1', which is 160 bits == 20 bytes, -// so this is enough to fit that, which most binaries will use. -// This is just a sensible default for auto_wasteful_vector so most -// callers can get away with stack allocation. -static const size_t kDefaultBuildIdSize = 20; - -class FileID { - public: - explicit FileID(const char* path); - ~FileID() {} - - // Load the identifier for the elf file path specified in the constructor into - // |identifier|. - // - // The current implementation will look for a .note.gnu.build-id - // section and use that as the file id, otherwise it falls back to - // XORing the first 4096 bytes of the .text section to generate an identifier. - bool ElfFileIdentifier(wasteful_vector& identifier); - - // Load the identifier for the elf file mapped into memory at |base| into - // |identifier|. Return false if the identifier could not be created for this - // file. - static bool ElfFileIdentifierFromMappedFile( - const void* base, - wasteful_vector& identifier); - - // Convert the |identifier| data to a string. The string will - // be formatted as a UUID in all uppercase without dashes. - // (e.g., 22F065BBFC9C49F780FE26A7CEBD7BCE). - static std::string ConvertIdentifierToUUIDString( - const wasteful_vector& identifier); - - // Convert the entire |identifier| data to a hex string. - static std::string ConvertIdentifierToString( - const wasteful_vector& identifier); - - private: - // Storage for the path specified - std::string path_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_FILE_ID_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/file_id_unittest.cc deleted file mode 100644 index 3a8193034..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/file_id_unittest.cc +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unit tests for FileID - -#include -#include - -#include -#include - -#include "common/linux/elf_gnu_compat.h" -#include "common/linux/elfutils.h" -#include "common/linux/file_id.h" -#include "common/linux/safe_readlink.h" -#include "common/linux/synth_elf.h" -#include "common/test_assembler.h" -#include "common/tests/auto_tempdir.h" -#include "common/using_std_string.h" -#include "breakpad_googletest_includes.h" - -using namespace google_breakpad; -using google_breakpad::synth_elf::ELF; -using google_breakpad::synth_elf::Notes; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Section; -using std::vector; -using ::testing::Types; - -namespace { - -// Simply calling Section::Append(size, byte) produces a uninteresting pattern -// that tends to get hashed to 0000...0000. This populates the section with -// data to produce better hashes. -void PopulateSection(Section* section, int size, int prime_number) { - for (int i = 0; i < size; i++) - section->Append(1, (i % prime_number) % 256); -} - -typedef wasteful_vector id_vector; - -} // namespace - -#ifndef __ANDROID__ -// This test is disabled on Android: It will always fail, since there is no -// 'strip' binary installed on test devices. -TEST(FileIDStripTest, StripSelf) { - // Calculate the File ID of this binary using - // FileID::ElfFileIdentifier, then make a copy of this binary, - // strip it, and ensure that the result is the same. - char exe_name[PATH_MAX]; - ASSERT_TRUE(SafeReadLink("/proc/self/exe", exe_name)); - - // copy our binary to a temp file, and strip it - AutoTempDir temp_dir; - string templ = temp_dir.path() + "/file-id-unittest"; - char cmdline[4096]; - sprintf(cmdline, "cp \"%s\" \"%s\"", exe_name, templ.c_str()); - ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline; - sprintf(cmdline, "chmod u+w \"%s\"", templ.c_str()); - ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline; - sprintf(cmdline, "strip \"%s\"", templ.c_str()); - ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline; - - PageAllocator allocator; - id_vector identifier1(&allocator, kDefaultBuildIdSize); - id_vector identifier2(&allocator, kDefaultBuildIdSize); - - FileID fileid1(exe_name); - EXPECT_TRUE(fileid1.ElfFileIdentifier(identifier1)); - FileID fileid2(templ.c_str()); - EXPECT_TRUE(fileid2.ElfFileIdentifier(identifier2)); - - string identifier_string1 = - FileID::ConvertIdentifierToUUIDString(identifier1); - string identifier_string2 = - FileID::ConvertIdentifierToUUIDString(identifier2); - EXPECT_EQ(identifier_string1, identifier_string2); -} -#endif // !__ANDROID__ - -template -class FileIDTest : public testing::Test { -public: - void GetElfContents(ELF& elf) { - string contents; - ASSERT_TRUE(elf.GetContents(&contents)); - ASSERT_LT(0U, contents.size()); - - elfdata_v.clear(); - elfdata_v.insert(elfdata_v.begin(), contents.begin(), contents.end()); - elfdata = &elfdata_v[0]; - } - - id_vector make_vector() { - return id_vector(&allocator, kDefaultBuildIdSize); - } - - template - string get_file_id(const uint8_t (&data)[N]) { - id_vector expected_identifier(make_vector()); - expected_identifier.insert(expected_identifier.end(), - &data[0], - data + N); - return FileID::ConvertIdentifierToUUIDString(expected_identifier); - } - - vector elfdata_v; - uint8_t* elfdata; - PageAllocator allocator; -}; - -typedef Types ElfClasses; - -TYPED_TEST_CASE(FileIDTest, ElfClasses); - -TYPED_TEST(FileIDTest, ElfClass) { - const char expected_identifier_string[] = - "80808080808000000000008080808080"; - const size_t kTextSectionSize = 128; - - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - for (size_t i = 0; i < kTextSectionSize; ++i) { - text.D8(i * 3); - } - elf.AddSection(".text", text, SHT_PROGBITS); - elf.Finish(); - this->GetElfContents(elf); - - id_vector identifier(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier)); - - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - EXPECT_EQ(expected_identifier_string, identifier_string); -} - -TYPED_TEST(FileIDTest, BuildID) { - const uint8_t kExpectedIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13}; - const string expected_identifier_string = - this->get_file_id(kExpectedIdentifierBytes); - - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - Notes notes(kLittleEndian); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, - sizeof(kExpectedIdentifierBytes)); - elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); - elf.Finish(); - this->GetElfContents(elf); - - id_vector identifier(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier)); - EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - EXPECT_EQ(expected_identifier_string, identifier_string); -} - -// Test that a build id note with fewer bytes than usual is handled. -TYPED_TEST(FileIDTest, BuildIDShort) { - const uint8_t kExpectedIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03}; - const string expected_identifier_string = - this->get_file_id(kExpectedIdentifierBytes); - - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - Notes notes(kLittleEndian); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, - sizeof(kExpectedIdentifierBytes)); - elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); - elf.Finish(); - this->GetElfContents(elf); - - id_vector identifier(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier)); - EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - EXPECT_EQ(expected_identifier_string, identifier_string); -} - -// Test that a build id note with more bytes than usual is handled. -TYPED_TEST(FileIDTest, BuildIDLong) { - const uint8_t kExpectedIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; - const string expected_identifier_string = - this->get_file_id(kExpectedIdentifierBytes); - - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - Notes notes(kLittleEndian); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, - sizeof(kExpectedIdentifierBytes)); - elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); - elf.Finish(); - this->GetElfContents(elf); - - id_vector identifier(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier)); - EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - EXPECT_EQ(expected_identifier_string, identifier_string); -} - -TYPED_TEST(FileIDTest, BuildIDPH) { - const uint8_t kExpectedIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13}; - const string expected_identifier_string = - this->get_file_id(kExpectedIdentifierBytes); - - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - text.Append(4096, 0); - elf.AddSection(".text", text, SHT_PROGBITS); - Notes notes(kLittleEndian); - notes.AddNote(0, "Linux", - reinterpret_cast("\0x42\0x02\0\0"), 4); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, - sizeof(kExpectedIdentifierBytes)); - int note_idx = elf.AddSection(".note", notes, SHT_NOTE); - elf.AddSegment(note_idx, note_idx, PT_NOTE); - elf.Finish(); - this->GetElfContents(elf); - - id_vector identifier(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier)); - EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - - string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); - EXPECT_EQ(expected_identifier_string, identifier_string); -} - -// Test to make sure two files with different text sections produce -// different hashes when not using a build id. -TYPED_TEST(FileIDTest, UniqueHashes) { - { - ELF elf1(EM_386, TypeParam::kClass, kLittleEndian); - Section foo_1(kLittleEndian); - PopulateSection(&foo_1, 32, 5); - elf1.AddSection(".foo", foo_1, SHT_PROGBITS); - Section text_1(kLittleEndian); - PopulateSection(&text_1, 4096, 17); - elf1.AddSection(".text", text_1, SHT_PROGBITS); - elf1.Finish(); - this->GetElfContents(elf1); - } - - id_vector identifier_1(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier_1)); - string identifier_string_1 = - FileID::ConvertIdentifierToUUIDString(identifier_1); - - { - ELF elf2(EM_386, TypeParam::kClass, kLittleEndian); - Section text_2(kLittleEndian); - Section foo_2(kLittleEndian); - PopulateSection(&foo_2, 32, 5); - elf2.AddSection(".foo", foo_2, SHT_PROGBITS); - PopulateSection(&text_2, 4096, 31); - elf2.AddSection(".text", text_2, SHT_PROGBITS); - elf2.Finish(); - this->GetElfContents(elf2); - } - - id_vector identifier_2(this->make_vector()); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, - identifier_2)); - string identifier_string_2 = - FileID::ConvertIdentifierToUUIDString(identifier_2); - - EXPECT_NE(identifier_string_1, identifier_string_2); -} - -TYPED_TEST(FileIDTest, ConvertIdentifierToString) { - const uint8_t kIdentifierBytes[] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; - const char* kExpected = - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; - - id_vector identifier(this->make_vector()); - identifier.insert(identifier.end(), - kIdentifierBytes, - kIdentifierBytes + sizeof(kIdentifierBytes)); - ASSERT_EQ(kExpected, - FileID::ConvertIdentifierToString(identifier)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.cc deleted file mode 100644 index 6d86fb369..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#include "common/linux/google_crashdump_uploader.h" - -#include -#include -#include - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword) { - LibcurlWrapper* http_layer = new LibcurlWrapper(); - Init(product, - version, - guid, - ptime, - ctime, - email, - comments, - minidump_pathname, - crash_server, - proxy_host, - proxy_userpassword, - http_layer); -} - -GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword, - LibcurlWrapper* http_layer) { - Init(product, - version, - guid, - ptime, - ctime, - email, - comments, - minidump_pathname, - crash_server, - proxy_host, - proxy_userpassword, - http_layer); -} - -void GoogleCrashdumpUploader::Init(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword, - LibcurlWrapper* http_layer) { - product_ = product; - version_ = version; - guid_ = guid; - ptime_ = ptime; - ctime_ = ctime; - email_ = email; - comments_ = comments; - http_layer_.reset(http_layer); - - crash_server_ = crash_server; - proxy_host_ = proxy_host; - proxy_userpassword_ = proxy_userpassword; - minidump_pathname_ = minidump_pathname; - std::cout << "Uploader initializing"; - std::cout << "\tProduct: " << product_; - std::cout << "\tVersion: " << version_; - std::cout << "\tGUID: " << guid_; - if (!ptime_.empty()) { - std::cout << "\tProcess uptime: " << ptime_; - } - if (!ctime_.empty()) { - std::cout << "\tCumulative Process uptime: " << ctime_; - } - if (!email_.empty()) { - std::cout << "\tEmail: " << email_; - } - if (!comments_.empty()) { - std::cout << "\tComments: " << comments_; - } -} - -bool GoogleCrashdumpUploader::CheckRequiredParametersArePresent() { - string error_text; - if (product_.empty()) { - error_text.append("\nProduct name must be specified."); - } - - if (version_.empty()) { - error_text.append("\nProduct version must be specified."); - } - - if (guid_.empty()) { - error_text.append("\nClient ID must be specified."); - } - - if (minidump_pathname_.empty()) { - error_text.append("\nMinidump pathname must be specified."); - } - - if (!error_text.empty()) { - std::cout << error_text; - return false; - } - return true; - -} - -bool GoogleCrashdumpUploader::Upload(int* http_status_code, - string* http_response_header, - string* http_response_body) { - bool ok = http_layer_->Init(); - if (!ok) { - std::cout << "http layer init failed"; - return ok; - } - - if (!CheckRequiredParametersArePresent()) { - return false; - } - - struct stat st; - int err = stat(minidump_pathname_.c_str(), &st); - if (err) { - std::cout << minidump_pathname_ << " could not be found"; - return false; - } - - parameters_["prod"] = product_; - parameters_["ver"] = version_; - parameters_["guid"] = guid_; - parameters_["ptime"] = ptime_; - parameters_["ctime"] = ctime_; - parameters_["email"] = email_; - parameters_["comments_"] = comments_; - if (!http_layer_->AddFile(minidump_pathname_, - "upload_file_minidump")) { - return false; - } - std::cout << "Sending request to " << crash_server_; - return http_layer_->SendRequest(crash_server_, - parameters_, - http_status_code, - http_response_header, - http_response_body); -} -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.h b/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.h deleted file mode 100644 index a2d0575b5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#ifndef COMMON_LINUX_GOOGLE_CRASHDUMP_UPLOADER_H_ -#define COMMON_LINUX_GOOGLE_CRASHDUMP_UPLOADER_H_ - -#include -#include - -#include "common/linux/libcurl_wrapper.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -class GoogleCrashdumpUploader { - public: - GoogleCrashdumpUploader(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword); - - GoogleCrashdumpUploader(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword, - LibcurlWrapper* http_layer); - - void Init(const string& product, - const string& version, - const string& guid, - const string& ptime, - const string& ctime, - const string& email, - const string& comments, - const string& minidump_pathname, - const string& crash_server, - const string& proxy_host, - const string& proxy_userpassword, - LibcurlWrapper* http_layer); - bool Upload(int* http_status_code, - string* http_response_header, - string* http_response_body); - - private: - bool CheckRequiredParametersArePresent(); - - scoped_ptr http_layer_; - string product_; - string version_; - string guid_; - string ptime_; - string ctime_; - string email_; - string comments_; - string minidump_pathname_; - - string crash_server_; - string proxy_host_; - string proxy_userpassword_; - - std::map parameters_; -}; -} - -#endif // COMMON_LINUX_GOOGLE_CRASHDUMP_UPLOADER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader_test.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader_test.cc deleted file mode 100644 index e94c5d62a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader_test.cc +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unit test for crash dump uploader. - -#include - -#include "common/linux/google_crashdump_uploader.h" -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -using ::testing::Return; -using ::testing::_; - -class MockLibcurlWrapper : public LibcurlWrapper { - public: - MOCK_METHOD0(Init, bool()); - MOCK_METHOD2(SetProxy, bool(const string& proxy_host, - const string& proxy_userpwd)); - MOCK_METHOD2(AddFile, bool(const string& upload_file_path, - const string& basename)); - MOCK_METHOD5(SendRequest, - bool(const string& url, - const std::map& parameters, - int* http_status_code, - string* http_header_data, - string* http_response_data)); -}; - -class GoogleCrashdumpUploaderTest : public ::testing::Test { -}; - -TEST_F(GoogleCrashdumpUploaderTest, InitFailsCausesUploadFailure) { - MockLibcurlWrapper m; - EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(false)); - GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar", - "1.0", - "AAA-BBB", - "", - "", - "test@test.com", - "none", - "/tmp/foo.dmp", - "http://foo.com", - "", - "", - &m); - ASSERT_FALSE(uploader->Upload(NULL, NULL, NULL)); -} - -TEST_F(GoogleCrashdumpUploaderTest, TestSendRequestHappensWithValidParameters) { - // Create a temp file - char tempfn[80] = "/tmp/googletest-upload-XXXXXX"; - int fd = mkstemp(tempfn); - ASSERT_NE(fd, -1); - close(fd); - - MockLibcurlWrapper m; - EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(m, AddFile(tempfn, _)).WillOnce(Return(true)); - EXPECT_CALL(m, - SendRequest("http://foo.com",_,_,_,_)).Times(1).WillOnce(Return(true)); - GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar", - "1.0", - "AAA-BBB", - "", - "", - "test@test.com", - "none", - tempfn, - "http://foo.com", - "", - "", - &m); - ASSERT_TRUE(uploader->Upload(NULL, NULL, NULL)); -} - - -TEST_F(GoogleCrashdumpUploaderTest, InvalidPathname) { - MockLibcurlWrapper m; - EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(m, SendRequest(_,_,_,_,_)).Times(0); - GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar", - "1.0", - "AAA-BBB", - "", - "", - "test@test.com", - "none", - "/tmp/foo.dmp", - "http://foo.com", - "", - "", - &m); - ASSERT_FALSE(uploader->Upload(NULL, NULL, NULL)); -} - -TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) { - // Test with empty product name. - GoogleCrashdumpUploader uploader("", - "1.0", - "AAA-BBB", - "", - "", - "test@test.com", - "none", - "/tmp/foo.dmp", - "http://foo.com", - "", - ""); - ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL)); - - // Test with empty product version. - GoogleCrashdumpUploader uploader1("product", - "", - "AAA-BBB", - "", - "", - "", - "", - "/tmp/foo.dmp", - "", - "", - ""); - - ASSERT_FALSE(uploader1.Upload(NULL, NULL, NULL)); - - // Test with empty client GUID. - GoogleCrashdumpUploader uploader2("product", - "1.0", - "", - "", - "", - "", - "", - "/tmp/foo.dmp", - "", - "", - ""); - ASSERT_FALSE(uploader2.Upload(NULL, NULL, NULL)); -} -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc deleted file mode 100644 index bfb308ee2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/linux/guid_creator.h" - -#include -#include -#include -#include -#include -#include - -// -// GUIDGenerator -// -// This class is used to generate random GUID. -// Currently use random number to generate a GUID since Linux has -// no native GUID generator. This should be OK since we don't expect -// crash to happen very offen. -// -class GUIDGenerator { - public: - static uint32_t BytesToUInt32(const uint8_t bytes[]) { - return ((uint32_t) bytes[0] - | ((uint32_t) bytes[1] << 8) - | ((uint32_t) bytes[2] << 16) - | ((uint32_t) bytes[3] << 24)); - } - - static void UInt32ToBytes(uint8_t bytes[], uint32_t n) { - bytes[0] = n & 0xff; - bytes[1] = (n >> 8) & 0xff; - bytes[2] = (n >> 16) & 0xff; - bytes[3] = (n >> 24) & 0xff; - } - - static bool CreateGUID(GUID *guid) { - InitOnce(); - guid->data1 = random(); - guid->data2 = (uint16_t)(random()); - guid->data3 = (uint16_t)(random()); - UInt32ToBytes(&guid->data4[0], random()); - UInt32ToBytes(&guid->data4[4], random()); - return true; - } - - private: - static void InitOnce() { - pthread_once(&once_control, &InitOnceImpl); - } - - static void InitOnceImpl() { - srandom(time(NULL)); - } - - static pthread_once_t once_control; -}; - -pthread_once_t GUIDGenerator::once_control = PTHREAD_ONCE_INIT; - -bool CreateGUID(GUID *guid) { - return GUIDGenerator::CreateGUID(guid); -} - -// Parse guid to string. -bool GUIDToString(const GUID *guid, char *buf, int buf_len) { - // Should allow more space the the max length of GUID. - assert(buf_len > kGUIDStringLength); - int num = snprintf(buf, buf_len, kGUIDFormatString, - guid->data1, guid->data2, guid->data3, - GUIDGenerator::BytesToUInt32(&(guid->data4[0])), - GUIDGenerator::BytesToUInt32(&(guid->data4[4]))); - if (num != kGUIDStringLength) - return false; - - buf[num] = '\0'; - return true; -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.h b/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.h deleted file mode 100644 index c86d856c4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_LINUX_GUID_CREATOR_H__ -#define COMMON_LINUX_GUID_CREATOR_H__ - -#include "google_breakpad/common/minidump_format.h" - -typedef MDGUID GUID; - -// Format string for parsing GUID. -#define kGUIDFormatString "%08x-%04x-%04x-%08x-%08x" -// Length of GUID string. Don't count the ending '\0'. -#define kGUIDStringLength 36 - -// Create a guid. -bool CreateGUID(GUID *guid); - -// Get the string from guid. -bool GUIDToString(const GUID *guid, char *buf, int buf_len); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.cc deleted file mode 100644 index 702526af7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.cc +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/linux/http_upload.h" - -#include -#include -#include "third_party/curl/curl.h" - -namespace { - -// Callback to get the response data from server. -static size_t WriteCallback(void *ptr, size_t size, - size_t nmemb, void *userp) { - if (!userp) - return 0; - - string *response = reinterpret_cast(userp); - size_t real_size = size * nmemb; - response->append(reinterpret_cast(ptr), real_size); - return real_size; -} - -} // namespace - -namespace google_breakpad { - -static const char kUserAgent[] = "Breakpad/1.0 (Linux)"; - -// static -bool HTTPUpload::SendRequest(const string &url, - const map ¶meters, - const map &files, - const string &proxy, - const string &proxy_user_pwd, - const string &ca_certificate_file, - string *response_body, - long *response_code, - string *error_description) { - if (response_code != NULL) - *response_code = 0; - - if (!CheckParameters(parameters)) - return false; - - // We may have been linked statically; if curl_easy_init is in the - // current binary, no need to search for a dynamic version. - void* curl_lib = dlopen(NULL, RTLD_NOW); - if (!CheckCurlLib(curl_lib)) { - fprintf(stderr, - "Failed to open curl lib from binary, use libcurl.so instead\n"); - dlerror(); // Clear dlerror before attempting to open libraries. - dlclose(curl_lib); - curl_lib = NULL; - } - if (!curl_lib) { - curl_lib = dlopen("libcurl.so", RTLD_NOW); - } - if (!curl_lib) { - if (error_description != NULL) - *error_description = dlerror(); - curl_lib = dlopen("libcurl.so.4", RTLD_NOW); - } - if (!curl_lib) { - // Debian gives libcurl a different name when it is built against GnuTLS - // instead of OpenSSL. - curl_lib = dlopen("libcurl-gnutls.so.4", RTLD_NOW); - } - if (!curl_lib) { - curl_lib = dlopen("libcurl.so.3", RTLD_NOW); - } - if (!curl_lib) { - return false; - } - - CURL* (*curl_easy_init)(void); - *(void**) (&curl_easy_init) = dlsym(curl_lib, "curl_easy_init"); - CURL *curl = (*curl_easy_init)(); - if (error_description != NULL) - *error_description = "No Error"; - - if (!curl) { - dlclose(curl_lib); - return false; - } - - CURLcode err_code = CURLE_OK; - CURLcode (*curl_easy_setopt)(CURL *, CURLoption, ...); - *(void**) (&curl_easy_setopt) = dlsym(curl_lib, "curl_easy_setopt"); - (*curl_easy_setopt)(curl, CURLOPT_URL, url.c_str()); - (*curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent); - // Support multithread by disabling timeout handling, would get SIGSEGV with - // Curl_resolv_timeout in stack trace otherwise. - // See https://curl.haxx.se/libcurl/c/threadsafe.html - (*curl_easy_setopt)(curl, CURLOPT_NOSIGNAL, 1); - // Set proxy information if necessary. - if (!proxy.empty()) - (*curl_easy_setopt)(curl, CURLOPT_PROXY, proxy.c_str()); - if (!proxy_user_pwd.empty()) - (*curl_easy_setopt)(curl, CURLOPT_PROXYUSERPWD, proxy_user_pwd.c_str()); - - if (!ca_certificate_file.empty()) - (*curl_easy_setopt)(curl, CURLOPT_CAINFO, ca_certificate_file.c_str()); - - struct curl_httppost *formpost = NULL; - struct curl_httppost *lastptr = NULL; - // Add form data. - CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...); - *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd"); - map::const_iterator iter = parameters.begin(); - for (; iter != parameters.end(); ++iter) - (*curl_formadd)(&formpost, &lastptr, - CURLFORM_COPYNAME, iter->first.c_str(), - CURLFORM_COPYCONTENTS, iter->second.c_str(), - CURLFORM_END); - - // Add form files. - for (iter = files.begin(); iter != files.end(); ++iter) { - (*curl_formadd)(&formpost, &lastptr, - CURLFORM_COPYNAME, iter->first.c_str(), - CURLFORM_FILE, iter->second.c_str(), - CURLFORM_END); - } - - (*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost); - - // Disable 100-continue header. - struct curl_slist *headerlist = NULL; - char buf[] = "Expect:"; - struct curl_slist* (*curl_slist_append)(struct curl_slist *, const char *); - *(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append"); - headerlist = (*curl_slist_append)(headerlist, buf); - (*curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist); - - if (response_body != NULL) { - (*curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - (*curl_easy_setopt)(curl, CURLOPT_WRITEDATA, - reinterpret_cast(response_body)); - } - - // Fail if 400+ is returned from the web server. - (*curl_easy_setopt)(curl, CURLOPT_FAILONERROR, 1); - - CURLcode (*curl_easy_perform)(CURL *); - *(void**) (&curl_easy_perform) = dlsym(curl_lib, "curl_easy_perform"); - err_code = (*curl_easy_perform)(curl); - if (response_code != NULL) { - CURLcode (*curl_easy_getinfo)(CURL *, CURLINFO, ...); - *(void**) (&curl_easy_getinfo) = dlsym(curl_lib, "curl_easy_getinfo"); - (*curl_easy_getinfo)(curl, CURLINFO_RESPONSE_CODE, response_code); - } - const char* (*curl_easy_strerror)(CURLcode); - *(void**) (&curl_easy_strerror) = dlsym(curl_lib, "curl_easy_strerror"); -#ifndef NDEBUG - if (err_code != CURLE_OK) - fprintf(stderr, "Failed to send http request to %s, error: %s\n", - url.c_str(), - (*curl_easy_strerror)(err_code)); -#endif - if (error_description != NULL) - *error_description = (*curl_easy_strerror)(err_code); - - void (*curl_easy_cleanup)(CURL *); - *(void**) (&curl_easy_cleanup) = dlsym(curl_lib, "curl_easy_cleanup"); - (*curl_easy_cleanup)(curl); - if (formpost != NULL) { - void (*curl_formfree)(struct curl_httppost *); - *(void**) (&curl_formfree) = dlsym(curl_lib, "curl_formfree"); - (*curl_formfree)(formpost); - } - if (headerlist != NULL) { - void (*curl_slist_free_all)(struct curl_slist *); - *(void**) (&curl_slist_free_all) = dlsym(curl_lib, "curl_slist_free_all"); - (*curl_slist_free_all)(headerlist); - } - dlclose(curl_lib); - return err_code == CURLE_OK; -} - -// static -bool HTTPUpload::CheckCurlLib(void* curl_lib) { - return curl_lib && - dlsym(curl_lib, "curl_easy_init") && - dlsym(curl_lib, "curl_easy_setopt"); -} - -// static -bool HTTPUpload::CheckParameters(const map ¶meters) { - for (map::const_iterator pos = parameters.begin(); - pos != parameters.end(); ++pos) { - const string &str = pos->first; - if (str.size() == 0) - return false; // disallow empty parameter names - for (unsigned int i = 0; i < str.size(); ++i) { - int c = str[i]; - if (c < 32 || c == '"' || c > 127) { - return false; - } - } - } - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.h b/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.h deleted file mode 100644 index bc1d5d570..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST -// request using libcurl. It currently supports requests that contain -// a set of string parameters (key/value pairs), and a file to upload. - -#ifndef COMMON_LINUX_HTTP_UPLOAD_H__ -#define COMMON_LINUX_HTTP_UPLOAD_H__ - -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -using std::map; - -class HTTPUpload { - public: - // Sends the given sets of parameters and files as a multipart POST - // request to the given URL. - // Each key in |files| is the name of the file part of the request - // (i.e. it corresponds to the name= attribute on an . - // Parameter names must contain only printable ASCII characters, - // and may not contain a quote (") character. - // Only HTTP(S) URLs are currently supported. Returns true on success. - // If the request is successful and response_body is non-NULL, - // the response body will be returned in response_body. - // If response_code is non-NULL, it will be set to the HTTP response code - // received (or 0 if the request failed before getting an HTTP response). - // If the send fails, a description of the error will be - // returned in error_description. - static bool SendRequest(const string &url, - const map ¶meters, - const map &files, - const string &proxy, - const string &proxy_user_pwd, - const string &ca_certificate_file, - string *response_body, - long *response_code, - string *error_description); - - private: - // Checks that the given list of parameters has only printable - // ASCII characters in the parameter name, and does not contain - // any quote (") characters. Returns true if so. - static bool CheckParameters(const map ¶meters); - - // Checks the curl_lib parameter points to a valid curl lib. - static bool CheckCurlLib(void* curl_lib); - - // No instances of this class should be created. - // Disallow all constructors, destructors, and operator=. - HTTPUpload(); - explicit HTTPUpload(const HTTPUpload &); - void operator=(const HTTPUpload &); - ~HTTPUpload(); -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_HTTP_UPLOAD_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/ignore_ret.h b/toolkit/crashreporter/google-breakpad/src/common/linux/ignore_ret.h deleted file mode 100644 index efd274c20..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/ignore_ret.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_LINUX_IGNORE_RET_H_ -#define COMMON_LINUX_IGNORE_RET_H_ - -// Some compilers are prone to warn about unused return values. In cases where -// either a) the call cannot fail, or b) there is nothing that can be done when -// the call fails, IGNORE_RET() can be used to mark the return code as ignored. -// This avoids spurious compiler warnings. - -#define IGNORE_RET(x) do { if (x) {} } while (0) - -#endif // COMMON_LINUX_IGNORE_RET_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc deleted file mode 100644 index fd4e34cd8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include - -#include "common/linux/libcurl_wrapper.h" -#include "common/using_std_string.h" - -namespace google_breakpad { -LibcurlWrapper::LibcurlWrapper() - : init_ok_(false), - formpost_(NULL), - lastptr_(NULL), - headerlist_(NULL) { - curl_lib_ = dlopen("libcurl.so", RTLD_NOW); - if (!curl_lib_) { - curl_lib_ = dlopen("libcurl.so.4", RTLD_NOW); - } - if (!curl_lib_) { - curl_lib_ = dlopen("libcurl.so.3", RTLD_NOW); - } - if (!curl_lib_) { - std::cout << "Could not find libcurl via dlopen"; - return; - } - std::cout << "LibcurlWrapper init succeeded"; - init_ok_ = true; - return; -} - -LibcurlWrapper::~LibcurlWrapper() {} - -bool LibcurlWrapper::SetProxy(const string& proxy_host, - const string& proxy_userpwd) { - if (!init_ok_) { - return false; - } - // Set proxy information if necessary. - if (!proxy_host.empty()) { - (*easy_setopt_)(curl_, CURLOPT_PROXY, proxy_host.c_str()); - } else { - std::cout << "SetProxy called with empty proxy host."; - return false; - } - if (!proxy_userpwd.empty()) { - (*easy_setopt_)(curl_, CURLOPT_PROXYUSERPWD, proxy_userpwd.c_str()); - } else { - std::cout << "SetProxy called with empty proxy username/password."; - return false; - } - std::cout << "Set proxy host to " << proxy_host; - return true; -} - -bool LibcurlWrapper::AddFile(const string& upload_file_path, - const string& basename) { - if (!init_ok_) { - return false; - } - std::cout << "Adding " << upload_file_path << " to form upload."; - // Add form file. - (*formadd_)(&formpost_, &lastptr_, - CURLFORM_COPYNAME, basename.c_str(), - CURLFORM_FILE, upload_file_path.c_str(), - CURLFORM_END); - - return true; -} - -// Callback to get the response data from server. -static size_t WriteCallback(void *ptr, size_t size, - size_t nmemb, void *userp) { - if (!userp) - return 0; - - string *response = reinterpret_cast(userp); - size_t real_size = size * nmemb; - response->append(reinterpret_cast(ptr), real_size); - return real_size; -} - -bool LibcurlWrapper::SendRequest(const string& url, - const std::map& parameters, - int* http_status_code, - string* http_header_data, - string* http_response_data) { - (*easy_setopt_)(curl_, CURLOPT_URL, url.c_str()); - std::map::const_iterator iter = parameters.begin(); - for (; iter != parameters.end(); ++iter) - (*formadd_)(&formpost_, &lastptr_, - CURLFORM_COPYNAME, iter->first.c_str(), - CURLFORM_COPYCONTENTS, iter->second.c_str(), - CURLFORM_END); - - (*easy_setopt_)(curl_, CURLOPT_HTTPPOST, formpost_); - if (http_response_data != NULL) { - http_response_data->clear(); - (*easy_setopt_)(curl_, CURLOPT_WRITEFUNCTION, WriteCallback); - (*easy_setopt_)(curl_, CURLOPT_WRITEDATA, - reinterpret_cast(http_response_data)); - } - if (http_header_data != NULL) { - http_header_data->clear(); - (*easy_setopt_)(curl_, CURLOPT_HEADERFUNCTION, WriteCallback); - (*easy_setopt_)(curl_, CURLOPT_HEADERDATA, - reinterpret_cast(http_header_data)); - } - - CURLcode err_code = CURLE_OK; - err_code = (*easy_perform_)(curl_); - easy_strerror_ = reinterpret_cast - (dlsym(curl_lib_, "curl_easy_strerror")); - - if (http_status_code != NULL) { - (*easy_getinfo_)(curl_, CURLINFO_RESPONSE_CODE, http_status_code); - } - -#ifndef NDEBUG - if (err_code != CURLE_OK) - fprintf(stderr, "Failed to send http request to %s, error: %s\n", - url.c_str(), - (*easy_strerror_)(err_code)); -#endif - if (headerlist_ != NULL) { - (*slist_free_all_)(headerlist_); - } - - (*easy_cleanup_)(curl_); - if (formpost_ != NULL) { - (*formfree_)(formpost_); - } - - return err_code == CURLE_OK; -} - -bool LibcurlWrapper::Init() { - if (!init_ok_) { - std::cout << "Init_OK was not true in LibcurlWrapper::Init(), check earlier log messages"; - return false; - } - - if (!SetFunctionPointers()) { - std::cout << "Could not find function pointers"; - init_ok_ = false; - return false; - } - - curl_ = (*easy_init_)(); - - last_curl_error_ = "No Error"; - - if (!curl_) { - dlclose(curl_lib_); - std::cout << "Curl initialization failed"; - return false; - } - - // Disable 100-continue header. - char buf[] = "Expect:"; - - headerlist_ = (*slist_append_)(headerlist_, buf); - (*easy_setopt_)(curl_, CURLOPT_HTTPHEADER, headerlist_); - return true; -} - -#define SET_AND_CHECK_FUNCTION_POINTER(var, function_name, type) \ - var = reinterpret_cast(dlsym(curl_lib_, function_name)); \ - if (!var) { \ - std::cout << "Could not find libcurl function " << function_name; \ - init_ok_ = false; \ - return false; \ - } - -bool LibcurlWrapper::SetFunctionPointers() { - - SET_AND_CHECK_FUNCTION_POINTER(easy_init_, - "curl_easy_init", - CURL*(*)()); - - SET_AND_CHECK_FUNCTION_POINTER(easy_setopt_, - "curl_easy_setopt", - CURLcode(*)(CURL*, CURLoption, ...)); - - SET_AND_CHECK_FUNCTION_POINTER(formadd_, "curl_formadd", - CURLFORMcode(*)(curl_httppost**, curl_httppost**, ...)); - - SET_AND_CHECK_FUNCTION_POINTER(slist_append_, "curl_slist_append", - curl_slist*(*)(curl_slist*, const char*)); - - SET_AND_CHECK_FUNCTION_POINTER(easy_perform_, - "curl_easy_perform", - CURLcode(*)(CURL*)); - - SET_AND_CHECK_FUNCTION_POINTER(easy_cleanup_, - "curl_easy_cleanup", - void(*)(CURL*)); - - SET_AND_CHECK_FUNCTION_POINTER(easy_getinfo_, - "curl_easy_getinfo", - CURLcode(*)(CURL *, CURLINFO info, ...)); - - SET_AND_CHECK_FUNCTION_POINTER(slist_free_all_, - "curl_slist_free_all", - void(*)(curl_slist*)); - - SET_AND_CHECK_FUNCTION_POINTER(formfree_, - "curl_formfree", - void(*)(curl_httppost*)); - return true; -} - -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.h b/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.h deleted file mode 100644 index 25905ad8f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// A wrapper for libcurl to do HTTP Uploads, to support easy mocking -// and unit testing of the HTTPUpload class. - -#ifndef COMMON_LINUX_LIBCURL_WRAPPER_H_ -#define COMMON_LINUX_LIBCURL_WRAPPER_H_ - -#include -#include - -#include "common/using_std_string.h" -#include "third_party/curl/curl.h" - -namespace google_breakpad { -class LibcurlWrapper { - public: - LibcurlWrapper(); - virtual ~LibcurlWrapper(); - virtual bool Init(); - virtual bool SetProxy(const string& proxy_host, - const string& proxy_userpwd); - virtual bool AddFile(const string& upload_file_path, - const string& basename); - virtual bool SendRequest(const string& url, - const std::map& parameters, - int* http_status_code, - string* http_header_data, - string* http_response_data); - private: - // This function initializes class state corresponding to function - // pointers into the CURL library. - bool SetFunctionPointers(); - - bool init_ok_; // Whether init succeeded - void* curl_lib_; // Pointer to result of dlopen() on - // curl library - string last_curl_error_; // The text of the last error when - // dealing - // with CURL. - - CURL *curl_; // Pointer for handle for CURL calls. - - CURL* (*easy_init_)(void); - - // Stateful pointers for calling into curl_formadd() - struct curl_httppost *formpost_; - struct curl_httppost *lastptr_; - struct curl_slist *headerlist_; - - // Function pointers into CURL library - CURLcode (*easy_setopt_)(CURL *, CURLoption, ...); - CURLFORMcode (*formadd_)(struct curl_httppost **, - struct curl_httppost **, ...); - struct curl_slist* (*slist_append_)(struct curl_slist *, const char *); - void (*slist_free_all_)(struct curl_slist *); - CURLcode (*easy_perform_)(CURL *); - const char* (*easy_strerror_)(CURLcode); - void (*easy_cleanup_)(CURL *); - CURLcode (*easy_getinfo_)(CURL *, CURLINFO info, ...); - void (*formfree_)(struct curl_httppost *); - -}; -} - -#endif // COMMON_LINUX_LIBCURL_WRAPPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc deleted file mode 100644 index 08b0325e6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This source file provides replacements for libc functions that we need. If -// we call the libc functions directly we risk crashing in the dynamic linker -// as it tries to resolve uncached PLT entries. - -#include "common/linux/linux_libc_support.h" - -#include - -extern "C" { - -size_t my_strlen(const char* s) { - size_t len = 0; - while (*s++) len++; - return len; -} - -int my_strcmp(const char* a, const char* b) { - for (;;) { - if (*a < *b) - return -1; - else if (*a > *b) - return 1; - else if (*a == 0) - return 0; - a++; - b++; - } -} - -int my_strncmp(const char* a, const char* b, size_t len) { - for (size_t i = 0; i < len; ++i) { - if (*a < *b) - return -1; - else if (*a > *b) - return 1; - else if (*a == 0) - return 0; - a++; - b++; - } - - return 0; -} - -// Parse a non-negative integer. -// result: (output) the resulting non-negative integer -// s: a NUL terminated string -// Return true iff successful. -bool my_strtoui(int* result, const char* s) { - if (*s == 0) - return false; - int r = 0; - for (;; s++) { - if (*s == 0) - break; - const int old_r = r; - r *= 10; - if (*s < '0' || *s > '9') - return false; - r += *s - '0'; - if (r < old_r) - return false; - } - - *result = r; - return true; -} - -// Return the length of the given unsigned integer when expressed in base 10. -unsigned my_uint_len(uintmax_t i) { - if (!i) - return 1; - - int len = 0; - while (i) { - len++; - i /= 10; - } - - return len; -} - -// Convert an unsigned integer to a string -// output: (output) the resulting string is written here. This buffer must be -// large enough to hold the resulting string. Call |my_uint_len| to get the -// required length. -// i: the unsigned integer to serialise. -// i_len: the length of the integer in base 10 (see |my_uint_len|). -void my_uitos(char* output, uintmax_t i, unsigned i_len) { - for (unsigned index = i_len; index; --index, i /= 10) - output[index - 1] = '0' + (i % 10); -} - -const char* my_strchr(const char* haystack, char needle) { - while (*haystack && *haystack != needle) - haystack++; - if (*haystack == needle) - return haystack; - return (const char*) 0; -} - -const char* my_strrchr(const char* haystack, char needle) { - const char* ret = NULL; - while (*haystack) { - if (*haystack == needle) - ret = haystack; - haystack++; - } - return ret; -} - -void* my_memchr(const void* src, int needle, size_t src_len) { - const unsigned char* p = (const unsigned char*)src; - const unsigned char* p_end = p + src_len; - for (; p < p_end; ++p) { - if (*p == needle) - return (void*)p; - } - return NULL; -} - -// Read a hex value -// result: (output) the resulting value -// s: a string -// Returns a pointer to the first invalid charactor. -const char* my_read_hex_ptr(uintptr_t* result, const char* s) { - uintptr_t r = 0; - - for (;; ++s) { - if (*s >= '0' && *s <= '9') { - r <<= 4; - r += *s - '0'; - } else if (*s >= 'a' && *s <= 'f') { - r <<= 4; - r += (*s - 'a') + 10; - } else if (*s >= 'A' && *s <= 'F') { - r <<= 4; - r += (*s - 'A') + 10; - } else { - break; - } - } - - *result = r; - return s; -} - -const char* my_read_decimal_ptr(uintptr_t* result, const char* s) { - uintptr_t r = 0; - - for (;; ++s) { - if (*s >= '0' && *s <= '9') { - r *= 10; - r += *s - '0'; - } else { - break; - } - } - *result = r; - return s; -} - -void my_memset(void* ip, char c, size_t len) { - char* p = (char *) ip; - while (len--) - *p++ = c; -} - -size_t my_strlcpy(char* s1, const char* s2, size_t len) { - size_t pos1 = 0; - size_t pos2 = 0; - - while (s2[pos2] != '\0') { - if (pos1 + 1 < len) { - s1[pos1] = s2[pos2]; - pos1++; - } - pos2++; - } - if (len > 0) - s1[pos1] = '\0'; - - return pos2; -} - -size_t my_strlcat(char* s1, const char* s2, size_t len) { - size_t pos1 = 0; - - while (pos1 < len && s1[pos1] != '\0') - pos1++; - - if (pos1 == len) - return pos1; - - return pos1 + my_strlcpy(s1 + pos1, s2, len - pos1); -} - -int my_isspace(int ch) { - // Matches the C locale. - const char spaces[] = " \t\f\n\r\t\v"; - for (size_t i = 0; i < sizeof(spaces); i++) { - if (ch == spaces[i]) - return 1; - } - return 0; -} - -} // extern "C" diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.h b/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.h deleted file mode 100644 index ec5a8d6b6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This header provides replacements for libc functions that we need. We if -// call the libc functions directly we risk crashing in the dynamic linker as -// it tries to resolve uncached PLT entries. - -#ifndef CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_ -#define CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_ - -#include -#include -#include - -extern "C" { - -extern size_t my_strlen(const char* s); - -extern int my_strcmp(const char* a, const char* b); - -extern int my_strncmp(const char* a, const char* b, size_t len); - -// Parse a non-negative integer. -// result: (output) the resulting non-negative integer -// s: a NUL terminated string -// Return true iff successful. -extern bool my_strtoui(int* result, const char* s); - -// Return the length of the given unsigned integer when expressed in base 10. -extern unsigned my_uint_len(uintmax_t i); - -// Convert an unsigned integer to a string -// output: (output) the resulting string is written here. This buffer must be -// large enough to hold the resulting string. Call |my_uint_len| to get the -// required length. -// i: the unsigned integer to serialise. -// i_len: the length of the integer in base 10 (see |my_uint_len|). -extern void my_uitos(char* output, uintmax_t i, unsigned i_len); - -extern const char* my_strchr(const char* haystack, char needle); - -extern const char* my_strrchr(const char* haystack, char needle); - -// Read a hex value -// result: (output) the resulting value -// s: a string -// Returns a pointer to the first invalid charactor. -extern const char* my_read_hex_ptr(uintptr_t* result, const char* s); - -extern const char* my_read_decimal_ptr(uintptr_t* result, const char* s); - -extern void my_memset(void* ip, char c, size_t len); - -extern void* my_memchr(const void* src, int c, size_t len); - -// The following are considered safe to use in a compromised environment. -// Besides, this gives the compiler an opportunity to optimize their calls. -#define my_memcpy memcpy -#define my_memmove memmove -#define my_memcmp memcmp - -extern size_t my_strlcpy(char* s1, const char* s2, size_t len); - -extern size_t my_strlcat(char* s1, const char* s2, size_t len); - -extern int my_isspace(int ch); - -} // extern "C" - -#endif // CLIENT_LINUX_LINUX_LIBC_SUPPORT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support_unittest.cc deleted file mode 100644 index adadfed44..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support_unittest.cc +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "breakpad_googletest_includes.h" -#include "common/linux/linux_libc_support.h" - -namespace { -typedef testing::Test LinuxLibcSupportTest; -} - -TEST(LinuxLibcSupportTest, strlen) { - static const char* test_data[] = { "", "a", "aa", "aaa", "aabc", NULL }; - for (unsigned i = 0; ; ++i) { - if (!test_data[i]) - break; - ASSERT_EQ(strlen(test_data[i]), my_strlen(test_data[i])); - } -} - -TEST(LinuxLibcSupportTest, strcmp) { - static const char* test_data[] = { - "", "", - "a", "", - "", "a", - "a", "b", - "a", "a", - "ab", "aa", - "abc", "ab", - "abc", "abc", - NULL, - }; - - for (unsigned i = 0; ; ++i) { - if (!test_data[i*2]) - break; - int libc_result = strcmp(test_data[i*2], test_data[i*2 + 1]); - if (libc_result > 1) - libc_result = 1; - else if (libc_result < -1) - libc_result = -1; - ASSERT_EQ(my_strcmp(test_data[i*2], test_data[i*2 + 1]), libc_result); - } -} - -TEST(LinuxLibcSupportTest, strtoui) { - int result; - - ASSERT_FALSE(my_strtoui(&result, "")); - ASSERT_FALSE(my_strtoui(&result, "-1")); - ASSERT_FALSE(my_strtoui(&result, "-")); - ASSERT_FALSE(my_strtoui(&result, "a")); - ASSERT_FALSE(my_strtoui(&result, "23472893472938472987987398472398")); - - ASSERT_TRUE(my_strtoui(&result, "0")); - ASSERT_EQ(result, 0); - ASSERT_TRUE(my_strtoui(&result, "1")); - ASSERT_EQ(result, 1); - ASSERT_TRUE(my_strtoui(&result, "12")); - ASSERT_EQ(result, 12); - ASSERT_TRUE(my_strtoui(&result, "123")); - ASSERT_EQ(result, 123); - ASSERT_TRUE(my_strtoui(&result, "0123")); - ASSERT_EQ(result, 123); -} - -TEST(LinuxLibcSupportTest, uint_len) { - ASSERT_EQ(my_uint_len(0), 1U); - ASSERT_EQ(my_uint_len(2), 1U); - ASSERT_EQ(my_uint_len(5), 1U); - ASSERT_EQ(my_uint_len(9), 1U); - ASSERT_EQ(my_uint_len(10), 2U); - ASSERT_EQ(my_uint_len(99), 2U); - ASSERT_EQ(my_uint_len(100), 3U); - ASSERT_EQ(my_uint_len(101), 3U); - ASSERT_EQ(my_uint_len(1000), 4U); - // 0xFFFFFFFFFFFFFFFF - ASSERT_EQ(my_uint_len(18446744073709551615LLU), 20U); -} - -TEST(LinuxLibcSupportTest, uitos) { - char buf[32]; - - my_uitos(buf, 0, 1); - ASSERT_EQ(0, memcmp(buf, "0", 1)); - - my_uitos(buf, 1, 1); - ASSERT_EQ(0, memcmp(buf, "1", 1)); - - my_uitos(buf, 10, 2); - ASSERT_EQ(0, memcmp(buf, "10", 2)); - - my_uitos(buf, 63, 2); - ASSERT_EQ(0, memcmp(buf, "63", 2)); - - my_uitos(buf, 101, 3); - ASSERT_EQ(0, memcmp(buf, "101", 2)); - - // 0xFFFFFFFFFFFFFFFF - my_uitos(buf, 18446744073709551615LLU, 20); - ASSERT_EQ(0, memcmp(buf, "18446744073709551615", 20)); -} - -TEST(LinuxLibcSupportTest, strchr) { - ASSERT_EQ(NULL, my_strchr("abc", 'd')); - ASSERT_EQ(NULL, my_strchr("", 'd')); - ASSERT_EQ(NULL, my_strchr("efghi", 'd')); - - ASSERT_TRUE(my_strchr("a", 'a')); - ASSERT_TRUE(my_strchr("abc", 'a')); - ASSERT_TRUE(my_strchr("bcda", 'a')); - ASSERT_TRUE(my_strchr("sdfasdf", 'a')); - - static const char abc3[] = "abcabcabc"; - ASSERT_EQ(abc3, my_strchr(abc3, 'a')); -} - -TEST(LinuxLibcSupportTest, strrchr) { - ASSERT_EQ(NULL, my_strrchr("abc", 'd')); - ASSERT_EQ(NULL, my_strrchr("", 'd')); - ASSERT_EQ(NULL, my_strrchr("efghi", 'd')); - - ASSERT_TRUE(my_strrchr("a", 'a')); - ASSERT_TRUE(my_strrchr("abc", 'a')); - ASSERT_TRUE(my_strrchr("bcda", 'a')); - ASSERT_TRUE(my_strrchr("sdfasdf", 'a')); - - static const char abc3[] = "abcabcabc"; - ASSERT_EQ(abc3 + 6, my_strrchr(abc3, 'a')); -} - -TEST(LinuxLibcSupportTest, memchr) { - ASSERT_EQ(NULL, my_memchr("abc", 'd', 3)); - ASSERT_EQ(NULL, my_memchr("abcd", 'd', 3)); - ASSERT_EQ(NULL, my_memchr("a", 'a', 0)); - - static const char abc3[] = "abcabcabc"; - ASSERT_EQ(abc3, my_memchr(abc3, 'a', 3)); - ASSERT_EQ(abc3, my_memchr(abc3, 'a', 9)); - ASSERT_EQ(abc3+1, my_memchr(abc3, 'b', 9)); - ASSERT_EQ(abc3+2, my_memchr(abc3, 'c', 9)); -} - -TEST(LinuxLibcSupportTest, read_hex_ptr) { - uintptr_t result; - const char* last; - - last = my_read_hex_ptr(&result, ""); - ASSERT_EQ(result, 0U); - ASSERT_EQ(*last, 0); - - last = my_read_hex_ptr(&result, "0"); - ASSERT_EQ(result, 0U); - ASSERT_EQ(*last, 0); - - last = my_read_hex_ptr(&result, "0123"); - ASSERT_EQ(result, 0x123U); - ASSERT_EQ(*last, 0); - - last = my_read_hex_ptr(&result, "0123a"); - ASSERT_EQ(result, 0x123aU); - ASSERT_EQ(*last, 0); - - last = my_read_hex_ptr(&result, "0123a-"); - ASSERT_EQ(result, 0x123aU); - ASSERT_EQ(*last, '-'); -} - -TEST(LinuxLibcSupportTest, read_decimal_ptr) { - uintptr_t result; - const char* last; - - last = my_read_decimal_ptr(&result, "0"); - ASSERT_EQ(result, 0U); - ASSERT_EQ(*last, 0); - - last = my_read_decimal_ptr(&result, "0123"); - ASSERT_EQ(result, 123U); - ASSERT_EQ(*last, 0); - - last = my_read_decimal_ptr(&result, "1234"); - ASSERT_EQ(result, 1234U); - ASSERT_EQ(*last, 0); - - last = my_read_decimal_ptr(&result, "01234-"); - ASSERT_EQ(result, 1234U); - ASSERT_EQ(*last, '-'); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc deleted file mode 100644 index 4e938269f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_mapped_file.cc: Implement google_breakpad::MemoryMappedFile. -// See memory_mapped_file.h for details. - -#include "common/linux/memory_mapped_file.h" - -#include -#include -#if defined(__ANDROID__) -#include -#endif -#include - -#include "common/memory_range.h" -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -MemoryMappedFile::MemoryMappedFile() {} - -MemoryMappedFile::MemoryMappedFile(const char* path, size_t offset) { - Map(path, offset); -} - -MemoryMappedFile::~MemoryMappedFile() { - Unmap(); -} - -#include - -bool MemoryMappedFile::Map(const char* path, size_t offset) { - Unmap(); - - int fd = sys_open(path, O_RDONLY, 0); - if (fd == -1) { - return false; - } - -#if defined(__x86_64__) || defined(__aarch64__) || \ - (defined(__mips__) && _MIPS_SIM == _ABI64) - - struct kernel_stat st; - if (sys_fstat(fd, &st) == -1 || st.st_size < 0) { -#else - struct kernel_stat64 st; - if (sys_fstat64(fd, &st) == -1 || st.st_size < 0) { -#endif - sys_close(fd); - return false; - } - - // Strangely file size can be negative, but we check above that it is not. - size_t file_len = static_cast(st.st_size); - // If the file does not extend beyond the offset, simply use an empty - // MemoryRange and return true. Don't bother to call mmap() - // even though mmap() can handle an empty file on some platforms. - if (offset >= file_len) { - sys_close(fd); - return true; - } - - void* data = sys_mmap(NULL, file_len, PROT_READ, MAP_PRIVATE, fd, offset); - sys_close(fd); - if (data == MAP_FAILED) { - return false; - } - - content_.Set(data, file_len - offset); - return true; -} - -void MemoryMappedFile::Unmap() { - if (content_.data()) { - sys_munmap(const_cast(content_.data()), content_.length()); - content_.Set(NULL, 0); - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.h b/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.h deleted file mode 100644 index fa660cc91..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_mapped_file.h: Define the google_breakpad::MemoryMappedFile -// class, which maps a file into memory for read-only access. - -#ifndef COMMON_LINUX_MEMORY_MAPPED_FILE_H_ -#define COMMON_LINUX_MEMORY_MAPPED_FILE_H_ - -#include -#include "common/basictypes.h" -#include "common/memory_range.h" - -namespace google_breakpad { - -// A utility class for mapping a file into memory for read-only access of -// the file content. Its implementation avoids calling into libc functions -// by directly making system calls for open, close, mmap, and munmap. -class MemoryMappedFile { - public: - MemoryMappedFile(); - - // Constructor that calls Map() to map a file at |path| into memory. - // If Map() fails, the object behaves as if it is default constructed. - MemoryMappedFile(const char* path, size_t offset); - - ~MemoryMappedFile(); - - // Maps a file at |path| into memory, which can then be accessed via - // content() as a MemoryRange object or via data(), and returns true on - // success. Mapping an empty file will succeed but with data() and size() - // returning NULL and 0, respectively. An existing mapping is unmapped - // before a new mapping is created. - bool Map(const char* path, size_t offset); - - // Unmaps the memory for the mapped file. It's a no-op if no file is - // mapped. - void Unmap(); - - // Returns a MemoryRange object that covers the memory for the mapped - // file. The MemoryRange object is empty if no file is mapped. - const MemoryRange& content() const { return content_; } - - // Returns a pointer to the beginning of the memory for the mapped file. - // or NULL if no file is mapped or the mapped file is empty. - const void* data() const { return content_.data(); } - - // Returns the size in bytes of the mapped file, or zero if no file - // is mapped. - size_t size() const { return content_.length(); } - - private: - // Mapped file content as a MemoryRange object. - MemoryRange content_; - - DISALLOW_COPY_AND_ASSIGN(MemoryMappedFile); -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_MEMORY_MAPPED_FILE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file_unittest.cc deleted file mode 100644 index fad59f40c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file_unittest.cc +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_mapped_file_unittest.cc: -// Unit tests for google_breakpad::MemoryMappedFile. - -#include -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/memory_mapped_file.h" -#include "common/tests/auto_tempdir.h" -#include "common/tests/file_utils.h" -#include "common/using_std_string.h" - -using google_breakpad::AutoTempDir; -using google_breakpad::MemoryMappedFile; -using google_breakpad::WriteFile; - -namespace { - -class MemoryMappedFileTest : public testing::Test { - protected: - void ExpectNoMappedData(const MemoryMappedFile& mapped_file) { - EXPECT_TRUE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() == NULL); - EXPECT_EQ(0U, mapped_file.size()); - } -}; - -} // namespace - -TEST_F(MemoryMappedFileTest, DefaultConstructor) { - MemoryMappedFile mapped_file; - ExpectNoMappedData(mapped_file); -} - -TEST_F(MemoryMappedFileTest, UnmapWithoutMap) { - MemoryMappedFile mapped_file; - mapped_file.Unmap(); -} - -TEST_F(MemoryMappedFileTest, MapNonexistentFile) { - { - MemoryMappedFile mapped_file("nonexistent-file", 0); - ExpectNoMappedData(mapped_file); - } - { - MemoryMappedFile mapped_file; - EXPECT_FALSE(mapped_file.Map("nonexistent-file", 0)); - ExpectNoMappedData(mapped_file); - } -} - -TEST_F(MemoryMappedFileTest, MapEmptyFile) { - AutoTempDir temp_dir; - string test_file = temp_dir.path() + "/empty_file"; - ASSERT_TRUE(WriteFile(test_file.c_str(), NULL, 0)); - - { - MemoryMappedFile mapped_file(test_file.c_str(), 0); - ExpectNoMappedData(mapped_file); - } - { - MemoryMappedFile mapped_file; - EXPECT_TRUE(mapped_file.Map(test_file.c_str(), 0)); - ExpectNoMappedData(mapped_file); - } -} - -TEST_F(MemoryMappedFileTest, MapNonEmptyFile) { - char data[256]; - size_t data_size = sizeof(data); - for (size_t i = 0; i < data_size; ++i) { - data[i] = i; - } - - AutoTempDir temp_dir; - string test_file = temp_dir.path() + "/test_file"; - ASSERT_TRUE(WriteFile(test_file.c_str(), data, data_size)); - - { - MemoryMappedFile mapped_file(test_file.c_str(), 0); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); - } - { - MemoryMappedFile mapped_file; - EXPECT_TRUE(mapped_file.Map(test_file.c_str(), 0)); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); - } -} - -TEST_F(MemoryMappedFileTest, RemapAfterMap) { - char data1[256]; - size_t data1_size = sizeof(data1); - for (size_t i = 0; i < data1_size; ++i) { - data1[i] = i; - } - - char data2[50]; - size_t data2_size = sizeof(data2); - for (size_t i = 0; i < data2_size; ++i) { - data2[i] = 255 - i; - } - - AutoTempDir temp_dir; - string test_file1 = temp_dir.path() + "/test_file1"; - string test_file2 = temp_dir.path() + "/test_file2"; - ASSERT_TRUE(WriteFile(test_file1.c_str(), data1, data1_size)); - ASSERT_TRUE(WriteFile(test_file2.c_str(), data2, data2_size)); - - { - MemoryMappedFile mapped_file(test_file1.c_str(), 0); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data1_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); - - mapped_file.Map(test_file2.c_str(), 0); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data2_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); - } - { - MemoryMappedFile mapped_file; - EXPECT_TRUE(mapped_file.Map(test_file1.c_str(), 0)); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data1_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); - - mapped_file.Map(test_file2.c_str(), 0); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data2_size, mapped_file.size()); - EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); - } -} - -TEST_F(MemoryMappedFileTest, MapWithOffset) { - // Put more data in the test file this time. Offsets can only be - // done on page boundaries, so we need a two page file to test this. - const int page_size = 4096; - char data1[2 * page_size]; - size_t data1_size = sizeof(data1); - for (size_t i = 0; i < data1_size; ++i) { - data1[i] = i & 0x7f; - } - - AutoTempDir temp_dir; - string test_file1 = temp_dir.path() + "/test_file1"; - ASSERT_TRUE(WriteFile(test_file1.c_str(), data1, data1_size)); - { - MemoryMappedFile mapped_file(test_file1.c_str(), page_size); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data1_size - page_size, mapped_file.size()); - EXPECT_EQ( - 0, - memcmp(data1 + page_size, mapped_file.data(), data1_size - page_size)); - } - { - MemoryMappedFile mapped_file; - mapped_file.Map(test_file1.c_str(), page_size); - EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); - EXPECT_EQ(data1_size - page_size, mapped_file.size()); - EXPECT_EQ( - 0, - memcmp(data1 + page_size, mapped_file.data(), data1_size - page_size)); - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build b/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build deleted file mode 100644 index 7450f6ba3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build +++ /dev/null @@ -1,56 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'elfutils.cc', - 'guid_creator.cc', - 'linux_libc_support.cc', - 'memory_mapped_file.cc', - 'safe_readlink.cc', -] - -# file_id.cc cannot be built in unified mode because it uses a custom DISABLE_STL_WRAPPING -SOURCES += [ - 'file_id.cc', -] - -if CONFIG['OS_TARGET'] != 'Android': - UNIFIED_SOURCES += [ - 'http_upload.cc', - ] - -HostLibrary('host_breakpad_linux_common_s') -HOST_SOURCES += [ - 'crc32.cc', - 'dump_symbols.cc', - 'elf_symbols_to_module.cc', - 'elfutils.cc', - 'file_id.cc', - 'guid_creator.cc', - 'linux_libc_support.cc', - 'memory_mapped_file.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -if CONFIG['OS_TARGET'] == 'Android': - LOCAL_INCLUDES += [ - '/toolkit/crashreporter/google-breakpad/src/common/android/include', - ] - -Library('breakpad_linux_common_s') - -FINAL_LIBRARY = 'xul' - -HOST_DEFINES['NO_STABS_SUPPORT'] = True - -include('/toolkit/crashreporter/crashreporter.mozbuild') - -if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-shadow'] diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.cc deleted file mode 100644 index 870c28af3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// safe_readlink.cc: Implement google_breakpad::SafeReadLink. -// See safe_readlink.h for details. - -#include - -#include "third_party/lss/linux_syscall_support.h" - -namespace google_breakpad { - -bool SafeReadLink(const char* path, char* buffer, size_t buffer_size) { - // sys_readlink() does not add a NULL byte to |buffer|. In order to return - // a NULL-terminated string in |buffer|, |buffer_size| should be at least - // one byte longer than the expected path length. Also, sys_readlink() - // returns the actual path length on success, which does not count the - // NULL byte, so |result_size| should be less than |buffer_size|. - ssize_t result_size = sys_readlink(path, buffer, buffer_size); - if (result_size >= 0 && static_cast(result_size) < buffer_size) { - buffer[result_size] = '\0'; - return true; - } - return false; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.h b/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.h deleted file mode 100644 index 4ae131b58..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// safe_readlink.h: Define the google_breakpad::SafeReadLink function, -// which wraps sys_readlink and gurantees the result is NULL-terminated. - -#ifndef COMMON_LINUX_SAFE_READLINK_H_ -#define COMMON_LINUX_SAFE_READLINK_H_ - -#include - -namespace google_breakpad { - -// This function wraps sys_readlink() and performs the same functionalty, -// but guarantees |buffer| is NULL-terminated if sys_readlink() returns -// no error. It takes the same arguments as sys_readlink(), but unlike -// sys_readlink(), it returns true on success. -// -// |buffer_size| specifies the size of |buffer| in bytes. As this function -// always NULL-terminates |buffer| on success, |buffer_size| should be -// at least one byte longer than the expected path length (e.g. PATH_MAX, -// which is typically defined as the maximum length of a path name -// including the NULL byte). -// -// The implementation of this function calls sys_readlink() instead of -// readlink(), it can thus be used in the context where calling to libc -// functions is discouraged. -bool SafeReadLink(const char* path, char* buffer, size_t buffer_size); - -// Same as the three-argument version of SafeReadLink() but deduces the -// size of |buffer| if it is a char array of known size. -template -bool SafeReadLink(const char* path, char (&buffer)[N]) { - return SafeReadLink(path, buffer, sizeof(buffer)); -} - -} // namespace google_breakpad - -#endif // COMMON_LINUX_SAFE_READLINK_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink_unittest.cc deleted file mode 100644 index d346b2a80..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/safe_readlink_unittest.cc +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// safe_readlink_unittest.cc: Unit tests for google_breakpad::SafeReadLink. - -#include "breakpad_googletest_includes.h" -#include "common/linux/safe_readlink.h" - -using google_breakpad::SafeReadLink; - -TEST(SafeReadLinkTest, ZeroBufferSize) { - char buffer[1]; - EXPECT_FALSE(SafeReadLink("/proc/self/exe", buffer, 0)); -} - -TEST(SafeReadLinkTest, BufferSizeTooSmall) { - char buffer[1]; - EXPECT_FALSE(SafeReadLink("/proc/self/exe", buffer, 1)); -} - -TEST(SafeReadLinkTest, BoundaryBufferSize) { - char buffer[PATH_MAX]; - EXPECT_TRUE(SafeReadLink("/proc/self/exe", buffer, sizeof(buffer))); - size_t path_length = strlen(buffer); - EXPECT_LT(0U, path_length); - EXPECT_GT(sizeof(buffer), path_length); - - // Buffer size equals to the expected path length plus 1 for the NULL byte. - char buffer2[PATH_MAX]; - EXPECT_TRUE(SafeReadLink("/proc/self/exe", buffer2, path_length + 1)); - EXPECT_EQ(path_length, strlen(buffer2)); - EXPECT_EQ(0, strncmp(buffer, buffer2, PATH_MAX)); - - // Buffer size equals to the expected path length. - EXPECT_FALSE(SafeReadLink("/proc/self/exe", buffer, path_length)); -} - -TEST(SafeReadLinkTest, NonexistentPath) { - char buffer[PATH_MAX]; - EXPECT_FALSE(SafeReadLink("nonexistent_path", buffer, sizeof(buffer))); -} - -TEST(SafeReadLinkTest, NonSymbolicLinkPath) { - char actual_path[PATH_MAX]; - EXPECT_TRUE(SafeReadLink("/proc/self/exe", actual_path, sizeof(actual_path))); - - char buffer[PATH_MAX]; - EXPECT_FALSE(SafeReadLink(actual_path, buffer, sizeof(buffer))); -} - -TEST(SafeReadLinkTest, DeduceBufferSizeFromCharArray) { - char buffer[PATH_MAX]; - char* buffer_pointer = buffer; - EXPECT_TRUE(SafeReadLink("/proc/self/exe", buffer_pointer, sizeof(buffer))); - size_t path_length = strlen(buffer); - - // Use the template version of SafeReadLink to deduce the buffer size - // from the char array. - char buffer2[PATH_MAX]; - EXPECT_TRUE(SafeReadLink("/proc/self/exe", buffer2)); - EXPECT_EQ(path_length, strlen(buffer2)); - EXPECT_EQ(0, strncmp(buffer, buffer2, PATH_MAX)); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.cc deleted file mode 100644 index bbd3181e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// symbol_upload.cc: implemented google_breakpad::sym_upload::Start, a helper -// function for linux symbol upload tool. - -#include "common/linux/http_upload.h" -#include "common/linux/symbol_upload.h" - -#include -#include - -#include -#include - -namespace google_breakpad { -namespace sym_upload { - -void TokenizeByChar(const string &source_string, int c, - std::vector *results) { - assert(results); - string::size_type cur_pos = 0, next_pos = 0; - while ((next_pos = source_string.find(c, cur_pos)) != string::npos) { - if (next_pos != cur_pos) - results->push_back(source_string.substr(cur_pos, next_pos - cur_pos)); - cur_pos = next_pos + 1; - } - if (cur_pos < source_string.size() && next_pos != cur_pos) - results->push_back(source_string.substr(cur_pos)); -} - -//============================================================================= -// Parse out the module line which have 5 parts. -// MODULE -bool ModuleDataForSymbolFile(const string &file, - std::vector *module_parts) { - assert(module_parts); - const size_t kModulePartNumber = 5; - FILE* fp = fopen(file.c_str(), "r"); - if (fp) { - char buffer[1024]; - if (fgets(buffer, sizeof(buffer), fp)) { - string line(buffer); - string::size_type line_break_pos = line.find_first_of('\n'); - if (line_break_pos == string::npos) { - assert(0 && "The file is invalid!"); - fclose(fp); - return false; - } - line.resize(line_break_pos); - const char kDelimiter = ' '; - TokenizeByChar(line, kDelimiter, module_parts); - if (module_parts->size() != kModulePartNumber) - module_parts->clear(); - } - fclose(fp); - } - - return module_parts->size() == kModulePartNumber; -} - -//============================================================================= -string CompactIdentifier(const string &uuid) { - std::vector components; - TokenizeByChar(uuid, '-', &components); - string result; - for (size_t i = 0; i < components.size(); ++i) - result += components[i]; - return result; -} - -//============================================================================= -void Start(Options *options) { - std::map parameters; - options->success = false; - std::vector module_parts; - if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) { - fprintf(stderr, "Failed to parse symbol file!\n"); - return; - } - - string compacted_id = CompactIdentifier(module_parts[3]); - - // Add parameters - if (!options->version.empty()) - parameters["version"] = options->version; - - // MODULE - // 0 1 2 3 4 - parameters["os"] = module_parts[1]; - parameters["cpu"] = module_parts[2]; - parameters["debug_file"] = module_parts[4]; - parameters["code_file"] = module_parts[4]; - parameters["debug_identifier"] = compacted_id; - - std::map files; - files["symbol_file"] = options->symbolsPath; - - string response, error; - long response_code; - bool success = HTTPUpload::SendRequest(options->uploadURLStr, - parameters, - files, - options->proxy, - options->proxy_user_pwd, - "", - &response, - &response_code, - &error); - - if (!success) { - printf("Failed to send symbol file: %s\n", error.c_str()); - printf("Response code: %ld\n", response_code); - printf("Response:\n"); - printf("%s\n", response.c_str()); - } else if (response_code == 0) { - printf("Failed to send symbol file: No response code\n"); - } else if (response_code != 200) { - printf("Failed to send symbol file: Response code %ld\n", response_code); - printf("Response:\n"); - printf("%s\n", response.c_str()); - } else { - printf("Successfully sent the symbol file.\n"); - } - options->success = success; -} - -} // namespace sym_upload -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.h b/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.h deleted file mode 100644 index 0a469692a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/symbol_upload.h +++ /dev/null @@ -1,59 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// symbol_upload.h: helper functions for linux symbol upload tool. - -#ifndef COMMON_LINUX_SYMBOL_UPLOAD_H_ -#define COMMON_LINUX_SYMBOL_UPLOAD_H_ - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { -namespace sym_upload { - -typedef struct { - string symbolsPath; - string uploadURLStr; - string proxy; - string proxy_user_pwd; - string version; - bool success; -} Options; - -// Starts upload to symbol server with options. -void Start(Options* options); - -} // namespace sym_upload -} // namespace google_breakpad - -#endif // COMMON_LINUX_SYMBOL_UPLOAD_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.cc deleted file mode 100644 index 98e81dab7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.cc +++ /dev/null @@ -1,263 +0,0 @@ -#include "common/linux/synth_elf.h" - -#include -#include -#include -#include - -#include "common/linux/elf_gnu_compat.h" -#include "common/using_std_string.h" - -namespace google_breakpad { -namespace synth_elf { - -ELF::ELF(uint16_t machine, - uint8_t file_class, - Endianness endianness) - : Section(endianness), - addr_size_(file_class == ELFCLASS64 ? 8 : 4), - program_count_(0), - program_header_table_(endianness), - section_count_(0), - section_header_table_(endianness), - section_header_strings_(endianness) { - // Could add support for more machine types here if needed. - assert(machine == EM_386 || - machine == EM_X86_64 || - machine == EM_ARM); - assert(file_class == ELFCLASS32 || file_class == ELFCLASS64); - - start() = 0; - // Add ELF header - // e_ident - // EI_MAG0...EI_MAG3 - D8(ELFMAG0); - D8(ELFMAG1); - D8(ELFMAG2); - D8(ELFMAG3); - // EI_CLASS - D8(file_class); - // EI_DATA - D8(endianness == kLittleEndian ? ELFDATA2LSB : ELFDATA2MSB); - // EI_VERSION - D8(EV_CURRENT); - // EI_OSABI - D8(ELFOSABI_SYSV); - // EI_ABIVERSION - D8(0); - // EI_PAD - Append(7, 0); - assert(Size() == EI_NIDENT); - - // e_type - D16(ET_EXEC); //TODO: allow passing ET_DYN? - // e_machine - D16(machine); - // e_version - D32(EV_CURRENT); - // e_entry - Append(endianness, addr_size_, 0); - // e_phoff - Append(endianness, addr_size_, program_header_label_); - // e_shoff - Append(endianness, addr_size_, section_header_label_); - // e_flags - D32(0); - // e_ehsize - D16(addr_size_ == 8 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr)); - // e_phentsize - D16(addr_size_ == 8 ? sizeof(Elf64_Phdr) : sizeof(Elf32_Phdr)); - // e_phnum - D16(program_count_label_); - // e_shentsize - D16(addr_size_ == 8 ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr)); - // e_shnum - D16(section_count_label_); - // e_shstrndx - D16(section_header_string_index_); - - // Add an empty section for SHN_UNDEF. - Section shn_undef; - AddSection("", shn_undef, SHT_NULL); -} - -int ELF::AddSection(const string& name, const Section& section, - uint32_t type, uint32_t flags, uint64_t addr, - uint32_t link, uint64_t entsize, uint64_t offset) { - Label offset_label; - Label string_label(section_header_strings_.Add(name)); - size_t size = section.Size(); - - int index = section_count_; - ++section_count_; - - section_header_table_ - // sh_name - .D32(string_label) - // sh_type - .D32(type) - // sh_flags - .Append(endianness(), addr_size_, flags) - // sh_addr - .Append(endianness(), addr_size_, addr) - // sh_offset - .Append(endianness(), addr_size_, offset_label) - // sh_size - .Append(endianness(), addr_size_, size) - // sh_link - .D32(link) - // sh_info - .D32(0) - // sh_addralign - .Append(endianness(), addr_size_, 0) - // sh_entsize - .Append(endianness(), addr_size_, entsize); - - sections_.push_back(ElfSection(section, type, addr, offset, offset_label, - size)); - return index; -} - -void ELF::AppendSection(ElfSection §ion) { - // NULL and NOBITS sections have no content, so they - // don't need to be written to the file. - if (section.type_ == SHT_NULL) { - section.offset_label_ = 0; - } else if (section.type_ == SHT_NOBITS) { - section.offset_label_ = section.offset_; - } else { - Mark(§ion.offset_label_); - Append(section); - Align(4); - } -} - -void ELF::AddSegment(int start, int end, uint32_t type, uint32_t flags) { - assert(start > 0); - assert(size_t(start) < sections_.size()); - assert(end > 0); - assert(size_t(end) < sections_.size()); - ++program_count_; - - // p_type - program_header_table_.D32(type); - - if (addr_size_ == 8) { - // p_flags - program_header_table_.D32(flags); - } - - size_t filesz = 0; - size_t memsz = 0; - bool prev_was_nobits = false; - for (int i = start; i <= end; ++i) { - size_t size = sections_[i].size_; - if (sections_[i].type_ != SHT_NOBITS) { - assert(!prev_was_nobits); - // non SHT_NOBITS sections are 4-byte aligned (see AddSection) - size = (size + 3) & ~3; - filesz += size; - } else { - prev_was_nobits = true; - } - memsz += size; - } - - program_header_table_ - // p_offset - .Append(endianness(), addr_size_, sections_[start].offset_label_) - // p_vaddr - .Append(endianness(), addr_size_, sections_[start].addr_) - // p_paddr - .Append(endianness(), addr_size_, sections_[start].addr_) - // p_filesz - .Append(endianness(), addr_size_, filesz) - // p_memsz - .Append(endianness(), addr_size_, memsz); - - if (addr_size_ == 4) { - // p_flags - program_header_table_.D32(flags); - } - - // p_align - program_header_table_.Append(endianness(), addr_size_, 0); -} - -void ELF::Finish() { - // Add the section header string table at the end. - section_header_string_index_ = section_count_; - //printf(".shstrtab size: %ld\n", section_header_strings_.Size()); - AddSection(".shstrtab", section_header_strings_, SHT_STRTAB); - //printf("section_count_: %ld, sections_.size(): %ld\n", - // section_count_, sections_.size()); - if (program_count_) { - Mark(&program_header_label_); - Append(program_header_table_); - } else { - program_header_label_ = 0; - } - - for (vector::iterator it = sections_.begin(); - it < sections_.end(); ++it) { - AppendSection(*it); - } - section_count_label_ = section_count_; - program_count_label_ = program_count_; - - // Section header table starts here. - Mark(§ion_header_label_); - Append(section_header_table_); -} - -SymbolTable::SymbolTable(Endianness endianness, - size_t addr_size, - StringTable& table) : Section(endianness), - table_(table) { -#ifndef NDEBUG - addr_size_ = addr_size; -#endif - assert(addr_size_ == 4 || addr_size_ == 8); -} - -void SymbolTable::AddSymbol(const string& name, uint32_t value, - uint32_t size, unsigned info, uint16_t shndx) { - assert(addr_size_ == 4); - D32(table_.Add(name)); - D32(value); - D32(size); - D8(info); - D8(0); // other - D16(shndx); -} - -void SymbolTable::AddSymbol(const string& name, uint64_t value, - uint64_t size, unsigned info, uint16_t shndx) { - assert(addr_size_ == 8); - D32(table_.Add(name)); - D8(info); - D8(0); // other - D16(shndx); - D64(value); - D64(size); -} - -void Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes, - size_t desc_size) { - // Elf32_Nhdr and Elf64_Nhdr are exactly the same. - Elf32_Nhdr note_header; - memset(¬e_header, 0, sizeof(note_header)); - note_header.n_namesz = name.length() + 1; - note_header.n_descsz = desc_size; - note_header.n_type = type; - - Append(reinterpret_cast(¬e_header), - sizeof(note_header)); - AppendCString(name); - Align(4); - Append(desc_bytes, desc_size); - Align(4); -} - -} // namespace synth_elf -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.h b/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.h deleted file mode 100644 index 1d2a20ca2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf.h +++ /dev/null @@ -1,197 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -// synth_elf.h: Interface to synth_elf::ELF: fake ELF generator. - -#ifndef COMMON_LINUX_SYNTH_ELF_H_ -#define COMMON_LINUX_SYNTH_ELF_H_ - -#include "common/test_assembler.h" - -#include -#include -#include -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { -namespace synth_elf { - -using std::list; -using std::vector; -using std::map; -using std::pair; -using test_assembler::Endianness; -using test_assembler::kLittleEndian; -using test_assembler::kUnsetEndian; -using test_assembler::Label; -using test_assembler::Section; - -// String tables are common in ELF headers, so subclass Section -// to make them easy to generate. -class StringTable : public Section { -public: - StringTable(Endianness endianness = kUnsetEndian) - : Section(endianness) { - start() = 0; - empty_string = Add(""); - } - - // Add the string s to the string table, and return - // a label containing the offset into the string table - // at which it was added. - Label Add(const string& s) { - if (strings_.find(s) != strings_.end()) - return strings_[s]; - - Label string_label(Here()); - AppendCString(s); - strings_[s] = string_label; - return string_label; - } - - // All StringTables contain an empty string as their first - // entry. - Label empty_string; - - // Avoid inserting duplicate strings. - map strings_; -}; - -// A Section representing an entire ELF file. -class ELF : public Section { - public: - ELF(uint16_t machine, // EM_386, etc - uint8_t file_class, // ELFCLASS{32,64} - Endianness endianness = kLittleEndian); - - // Add the Section section to the section header table and append it - // to the file. Returns the index of the section in the section - // header table. - int AddSection(const string& name, const Section& section, - uint32_t type, uint32_t flags = 0, uint64_t addr = 0, - uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0); - - // Add a segment containing from section index start to section index end. - // The indexes must have been gotten from AddSection. - void AddSegment(int start, int end, uint32_t type, uint32_t flags = 0); - - // Write out all data. GetContents may be used after this. - void Finish(); - - private: - // Size of an address, in bytes. - const size_t addr_size_; - - // Offset to the program header table. - Label program_header_label_; - // Number of entries in the program header table. - int program_count_; - Label program_count_label_; - // The program header table itself. - Section program_header_table_; - - // Offset to the section header table. - Label section_header_label_; - // Number of entries in the section header table. - int section_count_; - Label section_count_label_; - // The section header table itself. - Section section_header_table_; - - // Index of the section header string table in the section - // header table. - Label section_header_string_index_; - // Section containing the names of section header table entries. - StringTable section_header_strings_; - - // Record of an added section - struct ElfSection : public Section { - ElfSection(const Section& section, uint32_t type, uint32_t addr, - uint32_t offset, Label offset_label, uint32_t size) - : Section(section), type_(type), addr_(addr), offset_(offset) - , offset_label_(offset_label), size_(size) { - } - - uint32_t type_; - uint32_t addr_; - uint32_t offset_; - Label offset_label_; - uint32_t size_; - }; - - vector sections_; - - void AppendSection(ElfSection §ion); -}; - -// A class to build .symtab or .dynsym sections. -class SymbolTable : public Section { - public: - // table is the StringTable that contains symbol names. The caller - // must ensure that it remains alive for the life of the - // SymbolTable. - SymbolTable(Endianness endianness, size_t addr_size, StringTable& table); - - // Add an Elf32_Sym. - void AddSymbol(const string& name, uint32_t value, - uint32_t size, unsigned info, uint16_t shndx); - // Add an Elf64_Sym. - void AddSymbol(const string& name, uint64_t value, - uint64_t size, unsigned info, uint16_t shndx); - - private: -#ifndef NDEBUG - size_t addr_size_; -#endif - StringTable& table_; -}; - -// A class for note sections -class Notes : public Section { -public: - Notes(Endianness endianness) - : Section(endianness) { - } - - // Add a note. - void AddNote(int type, const string &name, const uint8_t* desc_bytes, - size_t desc_size); -}; - -} // namespace synth_elf -} // namespace google_breakpad - -#endif // COMMON_LINUX_SYNTH_ELF_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc deleted file mode 100644 index 3715b6e60..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ted Mielczarek - -// synth_elf_unittest.cc: -// Unittests for google_breakpad::synth_elf::ELF - -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/elfutils.h" -#include "common/linux/synth_elf.h" -#include "common/using_std_string.h" - -using google_breakpad::ElfClass32; -using google_breakpad::ElfClass64; -using google_breakpad::synth_elf::ELF; -using google_breakpad::synth_elf::Notes; -using google_breakpad::synth_elf::Section; -using google_breakpad::synth_elf::StringTable; -using google_breakpad::synth_elf::SymbolTable; -using google_breakpad::test_assembler::Endianness; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using ::testing::Test; -using ::testing::Types; - -class StringTableTest : public Test { -public: - StringTableTest() : table(kLittleEndian) {} - - StringTable table; -}; - -TEST_F(StringTableTest, Empty) { - EXPECT_EQ(1U, table.Size()); - string contents; - ASSERT_TRUE(table.GetContents(&contents)); - const char* kExpectedContents = "\0"; - EXPECT_EQ(0, memcmp(kExpectedContents, - contents.c_str(), - contents.size())); - ASSERT_TRUE(table.empty_string.IsKnownConstant()); - EXPECT_EQ(0U, table.empty_string.Value()); -} - -TEST_F(StringTableTest, Basic) { - const string s1("table fills with strings"); - const string s2("offsets preserved as labels"); - const string s3("verified with tests"); - const char* kExpectedContents = - "\0table fills with strings\0" - "offsets preserved as labels\0" - "verified with tests\0"; - Label l1(table.Add(s1)); - Label l2(table.Add(s2)); - Label l3(table.Add(s3)); - string contents; - ASSERT_TRUE(table.GetContents(&contents)); - EXPECT_EQ(0, memcmp(kExpectedContents, - contents.c_str(), - contents.size())); - // empty_string is at zero, other strings start at 1. - ASSERT_TRUE(l1.IsKnownConstant()); - EXPECT_EQ(1U, l1.Value()); - // Each string has an extra byte for a trailing null. - EXPECT_EQ(1 + s1.length() + 1, l2.Value()); - EXPECT_EQ(1 + s1.length() + 1 + s2.length() + 1, l3.Value()); -} - -TEST_F(StringTableTest, Duplicates) { - const string s1("string 1"); - const string s2("string 2"); - const string s3(""); - const char* kExpectedContents = "\0string 1\0string 2\0"; - Label l1(table.Add(s1)); - Label l2(table.Add(s2)); - // Adding strings twice should return the same Label. - Label l3(table.Add(s3)); - Label l4(table.Add(s2)); - string contents; - ASSERT_TRUE(table.GetContents(&contents)); - EXPECT_EQ(0, memcmp(kExpectedContents, - contents.c_str(), - contents.size())); - EXPECT_EQ(0U, table.empty_string.Value()); - EXPECT_EQ(table.empty_string.Value(), l3.Value()); - EXPECT_EQ(l2.Value(), l4.Value()); -} - -class SymbolTableTest : public Test {}; - -TEST_F(SymbolTableTest, Simple32) { - StringTable table(kLittleEndian); - SymbolTable syms(kLittleEndian, 4, table); - - const string kFuncName1 = "superfunc"; - const uint32_t kFuncAddr1 = 0x10001000; - const uint32_t kFuncSize1 = 0x10; - const string kFuncName2 = "awesomefunc"; - const uint32_t kFuncAddr2 = 0x20002000; - const uint32_t kFuncSize2 = 0x2f; - const string kFuncName3 = "megafunc"; - const uint32_t kFuncAddr3 = 0x30003000; - const uint32_t kFuncSize3 = 0x3c; - - syms.AddSymbol(kFuncName1, kFuncAddr1, kFuncSize1, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), - SHN_UNDEF + 1); - syms.AddSymbol(kFuncName2, kFuncAddr2, kFuncSize2, - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), - SHN_UNDEF + 2); - syms.AddSymbol(kFuncName3, kFuncAddr3, kFuncSize3, - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), - SHN_UNDEF + 3); - - const char kExpectedStringTable[] = "\0superfunc\0awesomefunc\0megafunc"; - const size_t kExpectedStringTableSize = sizeof(kExpectedStringTable); - EXPECT_EQ(kExpectedStringTableSize, table.Size()); - string table_contents; - table.GetContents(&table_contents); - EXPECT_EQ(0, memcmp(kExpectedStringTable, - table_contents.c_str(), - table_contents.size())); - - const uint8_t kExpectedSymbolContents[] = { - // Symbol 1 - 0x01, 0x00, 0x00, 0x00, // name - 0x00, 0x10, 0x00, 0x10, // value - 0x10, 0x00, 0x00, 0x00, // size - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), // info - 0x00, // other - 0x01, 0x00, // shndx - // Symbol 2 - 0x0B, 0x00, 0x00, 0x00, // name - 0x00, 0x20, 0x00, 0x20, // value - 0x2f, 0x00, 0x00, 0x00, // size - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info - 0x00, // other - 0x02, 0x00, // shndx - // Symbol 3 - 0x17, 0x00, 0x00, 0x00, // name - 0x00, 0x30, 0x00, 0x30, // value - 0x3c, 0x00, 0x00, 0x00, // size - ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info - 0x00, // other - 0x03, 0x00, // shndx - }; - const size_t kExpectedSymbolSize = sizeof(kExpectedSymbolContents); - EXPECT_EQ(kExpectedSymbolSize, syms.Size()); - - string symbol_contents; - syms.GetContents(&symbol_contents); - EXPECT_EQ(0, memcmp(kExpectedSymbolContents, - symbol_contents.c_str(), - symbol_contents.size())); -} - -template -class BasicElf : public Test {}; - -// Doesn't seem worthwhile writing the tests to be endian-independent -// when they're unlikely to ever be run on big-endian systems. -#if defined(__i386__) || defined(__x86_64__) - -typedef Types ElfClasses; - -TYPED_TEST_CASE(BasicElf, ElfClasses); - -TYPED_TEST(BasicElf, EmptyLE) { - typedef typename TypeParam::Ehdr Ehdr; - typedef typename TypeParam::Phdr Phdr; - typedef typename TypeParam::Shdr Shdr; - const size_t kStringTableSize = sizeof("\0.shstrtab"); - const size_t kStringTableAlign = 4 - kStringTableSize % 4; - const size_t kExpectedSize = sizeof(Ehdr) + - // Two sections, SHT_NULL + the section header string table. - 2 * sizeof(Shdr) + - kStringTableSize + kStringTableAlign; - - // It doesn't really matter that the machine type is right for the class. - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - elf.Finish(); - EXPECT_EQ(kExpectedSize, elf.Size()); - - string contents; - ASSERT_TRUE(elf.GetContents(&contents)); - ASSERT_EQ(kExpectedSize, contents.size()); - const Ehdr* header = - reinterpret_cast(contents.data()); - const uint8_t kIdent[] = { - ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, - TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent))); - EXPECT_EQ(ET_EXEC, header->e_type); - EXPECT_EQ(EM_386, header->e_machine); - EXPECT_EQ(static_cast(EV_CURRENT), header->e_version); - EXPECT_EQ(0U, header->e_entry); - EXPECT_EQ(0U, header->e_phoff); - EXPECT_EQ(sizeof(Ehdr) + kStringTableSize + kStringTableAlign, - header->e_shoff); - EXPECT_EQ(0U, header->e_flags); - EXPECT_EQ(sizeof(Ehdr), header->e_ehsize); - EXPECT_EQ(sizeof(Phdr), header->e_phentsize); - EXPECT_EQ(0, header->e_phnum); - EXPECT_EQ(sizeof(Shdr), header->e_shentsize); - EXPECT_EQ(2, header->e_shnum); - EXPECT_EQ(1, header->e_shstrndx); - - const Shdr* shdr = - reinterpret_cast(contents.data() + header->e_shoff); - EXPECT_EQ(0U, shdr[0].sh_name); - EXPECT_EQ(static_cast(SHT_NULL), shdr[0].sh_type); - EXPECT_EQ(0U, shdr[0].sh_flags); - EXPECT_EQ(0U, shdr[0].sh_addr); - EXPECT_EQ(0U, shdr[0].sh_offset); - EXPECT_EQ(0U, shdr[0].sh_size); - EXPECT_EQ(0U, shdr[0].sh_link); - EXPECT_EQ(0U, shdr[0].sh_info); - EXPECT_EQ(0U, shdr[0].sh_addralign); - EXPECT_EQ(0U, shdr[0].sh_entsize); - - EXPECT_EQ(1U, shdr[1].sh_name); - EXPECT_EQ(static_cast(SHT_STRTAB), shdr[1].sh_type); - EXPECT_EQ(0U, shdr[1].sh_flags); - EXPECT_EQ(0U, shdr[1].sh_addr); - EXPECT_EQ(sizeof(Ehdr), shdr[1].sh_offset); - EXPECT_EQ(kStringTableSize, shdr[1].sh_size); - EXPECT_EQ(0U, shdr[1].sh_link); - EXPECT_EQ(0U, shdr[1].sh_info); - EXPECT_EQ(0U, shdr[1].sh_addralign); - EXPECT_EQ(0U, shdr[1].sh_entsize); -} - -TYPED_TEST(BasicElf, BasicLE) { - typedef typename TypeParam::Ehdr Ehdr; - typedef typename TypeParam::Phdr Phdr; - typedef typename TypeParam::Shdr Shdr; - const size_t kStringTableSize = sizeof("\0.text\0.bss\0.shstrtab"); - const size_t kStringTableAlign = 4 - kStringTableSize % 4; - const size_t kExpectedSize = sizeof(Ehdr) + - // Four sections, SHT_NULL + the section header string table + - // 4096 bytes of the size-aligned .text section + one program header. - sizeof(Phdr) + 4 * sizeof(Shdr) + 4096 + - kStringTableSize + kStringTableAlign; - - // It doesn't really matter that the machine type is right for the class. - ELF elf(EM_386, TypeParam::kClass, kLittleEndian); - Section text(kLittleEndian); - text.Append(4094, 0); - int text_idx = elf.AddSection(".text", text, SHT_PROGBITS); - Section bss(kLittleEndian); - bss.Append(16, 0); - int bss_idx = elf.AddSection(".bss", bss, SHT_NOBITS); - elf.AddSegment(text_idx, bss_idx, PT_LOAD); - elf.Finish(); - EXPECT_EQ(kExpectedSize, elf.Size()); - - string contents; - ASSERT_TRUE(elf.GetContents(&contents)); - ASSERT_EQ(kExpectedSize, contents.size()); - const Ehdr* header = - reinterpret_cast(contents.data()); - const uint8_t kIdent[] = { - ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, - TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent))); - EXPECT_EQ(ET_EXEC, header->e_type); - EXPECT_EQ(EM_386, header->e_machine); - EXPECT_EQ(static_cast(EV_CURRENT), header->e_version); - EXPECT_EQ(0U, header->e_entry); - EXPECT_EQ(sizeof(Ehdr), header->e_phoff); - EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096 + kStringTableSize + - kStringTableAlign, header->e_shoff); - EXPECT_EQ(0U, header->e_flags); - EXPECT_EQ(sizeof(Ehdr), header->e_ehsize); - EXPECT_EQ(sizeof(Phdr), header->e_phentsize); - EXPECT_EQ(1, header->e_phnum); - EXPECT_EQ(sizeof(Shdr), header->e_shentsize); - EXPECT_EQ(4, header->e_shnum); - EXPECT_EQ(3, header->e_shstrndx); - - const Shdr* shdr = - reinterpret_cast(contents.data() + header->e_shoff); - EXPECT_EQ(0U, shdr[0].sh_name); - EXPECT_EQ(static_cast(SHT_NULL), shdr[0].sh_type); - EXPECT_EQ(0U, shdr[0].sh_flags); - EXPECT_EQ(0U, shdr[0].sh_addr); - EXPECT_EQ(0U, shdr[0].sh_offset); - EXPECT_EQ(0U, shdr[0].sh_size); - EXPECT_EQ(0U, shdr[0].sh_link); - EXPECT_EQ(0U, shdr[0].sh_info); - EXPECT_EQ(0U, shdr[0].sh_addralign); - EXPECT_EQ(0U, shdr[0].sh_entsize); - - EXPECT_EQ(1U, shdr[1].sh_name); - EXPECT_EQ(static_cast(SHT_PROGBITS), shdr[1].sh_type); - EXPECT_EQ(0U, shdr[1].sh_flags); - EXPECT_EQ(0U, shdr[1].sh_addr); - EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), shdr[1].sh_offset); - EXPECT_EQ(4094U, shdr[1].sh_size); - EXPECT_EQ(0U, shdr[1].sh_link); - EXPECT_EQ(0U, shdr[1].sh_info); - EXPECT_EQ(0U, shdr[1].sh_addralign); - EXPECT_EQ(0U, shdr[1].sh_entsize); - - EXPECT_EQ(sizeof("\0.text"), shdr[2].sh_name); - EXPECT_EQ(static_cast(SHT_NOBITS), shdr[2].sh_type); - EXPECT_EQ(0U, shdr[2].sh_flags); - EXPECT_EQ(0U, shdr[2].sh_addr); - EXPECT_EQ(0U, shdr[2].sh_offset); - EXPECT_EQ(16U, shdr[2].sh_size); - EXPECT_EQ(0U, shdr[2].sh_link); - EXPECT_EQ(0U, shdr[2].sh_info); - EXPECT_EQ(0U, shdr[2].sh_addralign); - EXPECT_EQ(0U, shdr[2].sh_entsize); - - EXPECT_EQ(sizeof("\0.text\0.bss"), shdr[3].sh_name); - EXPECT_EQ(static_cast(SHT_STRTAB), shdr[3].sh_type); - EXPECT_EQ(0U, shdr[3].sh_flags); - EXPECT_EQ(0U, shdr[3].sh_addr); - EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096, shdr[3].sh_offset); - EXPECT_EQ(kStringTableSize, shdr[3].sh_size); - EXPECT_EQ(0U, shdr[3].sh_link); - EXPECT_EQ(0U, shdr[3].sh_info); - EXPECT_EQ(0U, shdr[3].sh_addralign); - EXPECT_EQ(0U, shdr[3].sh_entsize); - - const Phdr* phdr = - reinterpret_cast(contents.data() + header->e_phoff); - EXPECT_EQ(static_cast(PT_LOAD), phdr->p_type); - EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), phdr->p_offset); - EXPECT_EQ(0U, phdr->p_vaddr); - EXPECT_EQ(0U, phdr->p_paddr); - EXPECT_EQ(4096U, phdr->p_filesz); - EXPECT_EQ(4096U + 16U, phdr->p_memsz); - EXPECT_EQ(0U, phdr->p_flags); - EXPECT_EQ(0U, phdr->p_align); -} - -class ElfNotesTest : public Test {}; - -TEST_F(ElfNotesTest, Empty) { - Notes notes(kLittleEndian); - string contents; - ASSERT_TRUE(notes.GetContents(&contents)); - EXPECT_EQ(0U, contents.size()); -} - -TEST_F(ElfNotesTest, Notes) { - Notes notes(kLittleEndian); - notes.AddNote(1, "Linux", reinterpret_cast("\x42\x02\0\0"), - 4); - notes.AddNote(2, "a", reinterpret_cast("foobar"), - sizeof("foobar") - 1); - - const uint8_t kExpectedNotesContents[] = { - // Note 1 - 0x06, 0x00, 0x00, 0x00, // name size, including terminating zero - 0x04, 0x00, 0x00, 0x00, // desc size - 0x01, 0x00, 0x00, 0x00, // type - 'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux" - 0x42, 0x02, 0x00, 0x00, // desc - // Note 2 - 0x02, 0x00, 0x00, 0x00, // name size - 0x06, 0x00, 0x00, 0x00, // desc size - 0x02, 0x00, 0x00, 0x00, // type - 'a', 0x00, 0x00, 0x00, // padded "a" - 'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar" - }; - const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents); - EXPECT_EQ(kExpectedNotesSize, notes.Size()); - - string notes_contents; - ASSERT_TRUE(notes.GetContents(¬es_contents)); - EXPECT_EQ(0, memcmp(kExpectedNotesContents, - notes_contents.data(), - notes_contents.size())); -} - -#endif // defined(__i386__) || defined(__x86_64__) diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/auto_testfile.h b/toolkit/crashreporter/google-breakpad/src/common/linux/tests/auto_testfile.h deleted file mode 100644 index 92fe017b9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/auto_testfile.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utility class for creating a temporary file for unit tests -// that is deleted in the destructor. - -#ifndef GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE -#define GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE - -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/linux/eintr_wrapper.h" -#include "common/tests/auto_tempdir.h" - -namespace google_breakpad { - -class AutoTestFile { - public: - // Create a new empty test file. - // test_prefix: (input) test-specific prefix, can't be NULL. - explicit AutoTestFile(const char* test_prefix) { - Init(test_prefix); - } - - // Create a new test file, and fill it with initial data from a C string. - // The terminating zero is not written. - // test_prefix: (input) test-specific prefix, can't be NULL. - // text: (input) initial content. - AutoTestFile(const char* test_prefix, const char* text) { - Init(test_prefix); - if (fd_ >= 0) - WriteText(text, static_cast(strlen(text))); - } - - AutoTestFile(const char* test_prefix, const char* text, size_t text_len) { - Init(test_prefix); - if (fd_ >= 0) - WriteText(text, text_len); - } - - // Destroy test file on scope exit. - ~AutoTestFile() { - if (fd_ >= 0) { - close(fd_); - fd_ = -1; - } - } - - // Returns true iff the test file could be created properly. - // Useful in tests inside EXPECT_TRUE(file.IsOk()); - bool IsOk() { - return fd_ >= 0; - } - - // Returns the Posix file descriptor for the test file, or -1 - // If IsOk() returns false. Note: on Windows, this always returns -1. - int GetFd() { - return fd_; - } - - private: - void Init(const char* test_prefix) { - fd_ = -1; - char path_templ[PATH_MAX]; - int ret = snprintf(path_templ, sizeof(path_templ), - TEMPDIR "/%s-unittest.XXXXXX", - test_prefix); - if (ret >= static_cast(sizeof(path_templ))) - return; - - fd_ = mkstemp(path_templ); - if (fd_ < 0) - return; - - unlink(path_templ); - } - - void WriteText(const char* text, size_t text_len) { - ssize_t r = HANDLE_EINTR(write(fd_, text, text_len)); - if (r != static_cast(text_len)) { - close(fd_); - fd_ = -1; - return; - } - - lseek(fd_, 0, SEEK_SET); - } - - int fd_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.cc deleted file mode 100644 index c9491f6f2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.cc +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// crash_generator.cc: Implement google_breakpad::CrashGenerator. -// See crash_generator.h for details. - -#include "common/linux/tests/crash_generator.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if defined(__ANDROID__) -#include "common/android/testing/pthread_fixes.h" -#endif -#include "common/linux/eintr_wrapper.h" -#include "common/tests/auto_tempdir.h" -#include "common/tests/file_utils.h" -#include "common/using_std_string.h" - -namespace { - -struct ThreadData { - pthread_t thread; - pthread_barrier_t* barrier; - pid_t* thread_id_ptr; -}; - -const char* const kProcFilesToCopy[] = { - "auxv", "cmdline", "environ", "maps", "status" -}; -const size_t kNumProcFilesToCopy = - sizeof(kProcFilesToCopy) / sizeof(kProcFilesToCopy[0]); - -int gettid() { - // Glibc does not provide a wrapper for this. - return syscall(__NR_gettid); -} - -int tkill(pid_t tid, int sig) { - // Glibc does not provide a wrapper for this. - return syscall(__NR_tkill, tid, sig); -} - -// Core file size limit set to 1 MB, which is big enough for test purposes. -const rlim_t kCoreSizeLimit = 1024 * 1024; - -void *thread_function(void *data) { - ThreadData* thread_data = reinterpret_cast(data); - volatile pid_t thread_id = gettid(); - *(thread_data->thread_id_ptr) = thread_id; - int result = pthread_barrier_wait(thread_data->barrier); - if (result != 0 && result != PTHREAD_BARRIER_SERIAL_THREAD) { - perror("Failed to wait for sync barrier"); - exit(1); - } - while (true) { - pthread_yield(); - } -} - -} // namespace - -namespace google_breakpad { - -CrashGenerator::CrashGenerator() - : shared_memory_(NULL), - shared_memory_size_(0) { -} - -CrashGenerator::~CrashGenerator() { - UnmapSharedMemory(); -} - -bool CrashGenerator::HasDefaultCorePattern() const { - char buffer[8]; - ssize_t buffer_size = sizeof(buffer); - return ReadFile("/proc/sys/kernel/core_pattern", buffer, &buffer_size) && - buffer_size == 5 && memcmp(buffer, "core", 4) == 0; -} - -string CrashGenerator::GetCoreFilePath() const { - return temp_dir_.path() + "/core"; -} - -string CrashGenerator::GetDirectoryOfProcFilesCopy() const { - return temp_dir_.path() + "/proc"; -} - -pid_t CrashGenerator::GetThreadId(unsigned index) const { - return reinterpret_cast(shared_memory_)[index]; -} - -pid_t* CrashGenerator::GetThreadIdPointer(unsigned index) { - return reinterpret_cast(shared_memory_) + index; -} - -bool CrashGenerator::MapSharedMemory(size_t memory_size) { - if (!UnmapSharedMemory()) - return false; - - void* mapped_memory = mmap(0, memory_size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0); - if (mapped_memory == MAP_FAILED) { - perror("CrashGenerator: Failed to map shared memory"); - return false; - } - - memset(mapped_memory, 0, memory_size); - shared_memory_ = mapped_memory; - shared_memory_size_ = memory_size; - return true; -} - -bool CrashGenerator::UnmapSharedMemory() { - if (!shared_memory_) - return true; - - if (munmap(shared_memory_, shared_memory_size_) == 0) { - shared_memory_ = NULL; - shared_memory_size_ = 0; - return true; - } - - perror("CrashGenerator: Failed to unmap shared memory"); - return false; -} - -bool CrashGenerator::SetCoreFileSizeLimit(rlim_t limit) const { - struct rlimit limits = { limit, limit }; - if (setrlimit(RLIMIT_CORE, &limits) == -1) { - perror("CrashGenerator: Failed to set core file size limit"); - return false; - } - return true; -} - -bool CrashGenerator::CreateChildCrash( - unsigned num_threads, unsigned crash_thread, int crash_signal, - pid_t* child_pid) { - if (num_threads == 0 || crash_thread >= num_threads) { - fprintf(stderr, "CrashGenerator: Invalid thread counts; num_threads=%u" - " crash_thread=%u\n", num_threads, crash_thread); - return false; - } - - if (!MapSharedMemory(num_threads * sizeof(pid_t))) { - perror("CrashGenerator: Unable to map shared memory"); - return false; - } - - pid_t pid = fork(); - if (pid == 0) { - if (chdir(temp_dir_.path().c_str()) == -1) { - perror("CrashGenerator: Failed to change directory"); - exit(1); - } - if (SetCoreFileSizeLimit(kCoreSizeLimit)) { - CreateThreadsInChildProcess(num_threads); - string proc_dir = GetDirectoryOfProcFilesCopy(); - if (mkdir(proc_dir.c_str(), 0755) == -1) { - perror("CrashGenerator: Failed to create proc directory"); - exit(1); - } - if (!CopyProcFiles(getpid(), proc_dir.c_str())) { - fprintf(stderr, "CrashGenerator: Failed to copy proc files\n"); - exit(1); - } - // On Android the signal sometimes doesn't seem to get sent even though - // tkill returns '0'. Retry a couple of times if the signal doesn't get - // through on the first go: - // https://code.google.com/p/google-breakpad/issues/detail?id=579 -#if defined(__ANDROID__) - const int kRetries = 60; - const unsigned int kSleepTimeInSeconds = 1; -#else - const int kRetries = 1; - const unsigned int kSleepTimeInSeconds = 600; -#endif - for (int i = 0; i < kRetries; i++) { - if (tkill(*GetThreadIdPointer(crash_thread), crash_signal) == -1) { - perror("CrashGenerator: Failed to kill thread by signal"); - } else { - // At this point, we've queued the signal for delivery, but there's no - // guarantee when it'll be delivered. We don't want the main thread to - // race and exit before the thread we signaled is processed. So sleep - // long enough that we won't flake even under fairly high load. - // TODO: See if we can't be a bit more deterministic. There doesn't - // seem to be an API to check on signal delivery status, so we can't - // really poll and wait for the kernel to declare the signal has been - // delivered. If it has, and things worked, we'd be killed, so the - // sleep length doesn't really matter. - sleep(kSleepTimeInSeconds); - } - } - } else { - perror("CrashGenerator: Failed to set core limit"); - } - exit(1); - } else if (pid == -1) { - perror("CrashGenerator: Failed to create child process"); - return false; - } - - int status; - if (HANDLE_EINTR(waitpid(pid, &status, 0)) == -1) { - perror("CrashGenerator: Failed to wait for child process"); - return false; - } - if (!WIFSIGNALED(status) || WTERMSIG(status) != crash_signal) { - fprintf(stderr, "CrashGenerator: Child process not killed by the expected signal\n" - " exit status=0x%x pid=%u signaled=%s sig=%d expected=%d\n", - status, pid, WIFSIGNALED(status) ? "true" : "false", - WTERMSIG(status), crash_signal); - return false; - } - - if (child_pid) - *child_pid = pid; - return true; -} - -bool CrashGenerator::CopyProcFiles(pid_t pid, const char* path) const { - char from_path[PATH_MAX], to_path[PATH_MAX]; - for (size_t i = 0; i < kNumProcFilesToCopy; ++i) { - int num_chars = snprintf(from_path, PATH_MAX, "/proc/%d/%s", - pid, kProcFilesToCopy[i]); - if (num_chars < 0 || num_chars >= PATH_MAX) - return false; - - num_chars = snprintf(to_path, PATH_MAX, "%s/%s", - path, kProcFilesToCopy[i]); - if (num_chars < 0 || num_chars >= PATH_MAX) - return false; - - if (!CopyFile(from_path, to_path)) - return false; - } - return true; -} - -void CrashGenerator::CreateThreadsInChildProcess(unsigned num_threads) { - *GetThreadIdPointer(0) = getpid(); - - if (num_threads <= 1) - return; - - // This method does not clean up any pthread resource, as the process - // is expected to be killed anyway. - ThreadData* thread_data = new ThreadData[num_threads]; - - // Create detached threads so that we do not worry about pthread_join() - // later being called or not. - pthread_attr_t thread_attributes; - if (pthread_attr_init(&thread_attributes) != 0 || - pthread_attr_setdetachstate(&thread_attributes, - PTHREAD_CREATE_DETACHED) != 0) { - fprintf(stderr, "CrashGenerator: Failed to initialize thread attribute\n"); - exit(1); - } - - pthread_barrier_t thread_barrier; - if (pthread_barrier_init(&thread_barrier, NULL, num_threads) != 0) { - fprintf(stderr, "CrashGenerator: Failed to initialize thread barrier\n"); - exit(1); - } - - for (unsigned i = 1; i < num_threads; ++i) { - thread_data[i].barrier = &thread_barrier; - thread_data[i].thread_id_ptr = GetThreadIdPointer(i); - if (pthread_create(&thread_data[i].thread, &thread_attributes, - thread_function, &thread_data[i]) != 0) { - fprintf(stderr, "CrashGenerator: Failed to create thread %d\n", i); - exit(1); - } - } - - int result = pthread_barrier_wait(&thread_barrier); - if (result != 0 && result != PTHREAD_BARRIER_SERIAL_THREAD) { - fprintf(stderr, "CrashGenerator: Failed to wait for thread barrier\n"); - exit(1); - } - - pthread_barrier_destroy(&thread_barrier); - pthread_attr_destroy(&thread_attributes); - delete[] thread_data; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.h b/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.h deleted file mode 100644 index 7e2fcbf98..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/tests/crash_generator.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// crash_generator.h: Define the google_breakpad::CrashGenerator class, -// which is used to generate a crash (and a core dump file) for testing. - -#ifndef COMMON_LINUX_TESTS_CRASH_GENERATOR_H_ -#define COMMON_LINUX_TESTS_CRASH_GENERATOR_H_ - -#include - -#include - -#include "common/tests/auto_tempdir.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -// A utility class for generating a crash (and a core dump file) for -// testing. It creates a child process with the specified number of -// threads, which is then termainated by the specified signal. A core -// dump file is expected to be created upon the termination of the child -// process, which can then be used for testing code that processes core -// dump files. -class CrashGenerator { - public: - CrashGenerator(); - - ~CrashGenerator(); - - // Returns true if a core dump file named 'core' will be generated in - // the current directory for a test that produces a crash by checking - // if /proc/sys/kernel/core_pattern has the default value 'core'. - bool HasDefaultCorePattern() const; - - // Returns the expected path of the core dump file. - string GetCoreFilePath() const; - - // Returns the directory of a copy of proc files of the child process. - string GetDirectoryOfProcFilesCopy() const; - - // Creates a crash (and a core dump file) by creating a child process with - // |num_threads| threads, and the terminating the child process by sending - // a signal with number |crash_signal| to the |crash_thread|-th thread. - // Returns true on success. - bool CreateChildCrash(unsigned num_threads, unsigned crash_thread, - int crash_signal, pid_t* child_pid); - - // Returns the thread ID of the |index|-th thread in the child process. - // This method does not validate |index|. - pid_t GetThreadId(unsigned index) const; - - private: - // Copies the following proc files of the process with |pid| to the directory - // at |path|: auxv, cmdline, environ, maps, status - // The directory must have been created. Returns true on success. - bool CopyProcFiles(pid_t pid, const char* path) const; - - // Creates |num_threads| threads in the child process. - void CreateThreadsInChildProcess(unsigned num_threads); - - // Sets the maximum size of core dump file (both the soft and hard limit) - // to |limit| bytes. Returns true on success. - bool SetCoreFileSizeLimit(rlim_t limit) const; - - // Creates a shared memory of |memory_size| bytes for communicating thread - // IDs between the parent and child process. Returns true on success. - bool MapSharedMemory(size_t memory_size); - - // Releases any shared memory created by MapSharedMemory(). Returns true on - // success. - bool UnmapSharedMemory(); - - // Returns the pointer to the thread ID of the |index|-th thread in the child - // process. This method does not validate |index|. - pid_t* GetThreadIdPointer(unsigned index); - - // Temporary directory in which a core file is generated. - AutoTempDir temp_dir_; - - // Shared memory for communicating thread IDs between the parent and - // child process. - void* shared_memory_; - - // Number of bytes mapped for |shared_memory_|. - size_t shared_memory_size_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_TESTS_CRASH_GENERATOR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/Breakpad.xcconfig b/toolkit/crashreporter/google-breakpad/src/common/mac/Breakpad.xcconfig deleted file mode 100644 index f09136908..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/Breakpad.xcconfig +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -GCC_C_LANGUAGE_STANDARD = c99 - -GCC_WARN_CHECK_SWITCH_STATEMENTS = YES -// TODO(nealsid): Get the code so we can turn on the 64_TO_32 warning. -GCC_WARN_64_TO_32_BIT_CONVERSION = NO -GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES -GCC_WARN_ABOUT_RETURN_TYPE = YES -GCC_WARN_MISSING_PARENTHESES = YES - -// Once https://bugs.chromium.org/p/google-breakpad/issues/detail?id=697 -// is fixed this should be reenabled. -//GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES -GCC_WARN_ABOUT_MISSING_NEWLINE = YES -GCC_WARN_SIGN_COMPARE = YES -GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES -GCC_WARN_UNDECLARED_SELECTOR = YES -GCC_WARN_UNKNOWN_PRAGMAS = YES -GCC_WARN_UNUSED_VARIABLE = YES -GCC_TREAT_WARNINGS_AS_ERRORS = YES - -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym - -ALWAYS_SEARCH_USER_PATHS = NO diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadDebug.xcconfig b/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadDebug.xcconfig deleted file mode 100644 index 94cdd8cfc..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadDebug.xcconfig +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "Breakpad.xcconfig" - -GCC_OPTIMIZATION_LEVEL = 0 diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadRelease.xcconfig b/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadRelease.xcconfig deleted file mode 100644 index 920f277db..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/BreakpadRelease.xcconfig +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "Breakpad.xcconfig" - -GCC_OPTIMIZATION_LEVEL = s -GCC_WARN_UNINITIALIZED_AUTOS = YES -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) NDEBUG diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMDefines.h b/toolkit/crashreporter/google-breakpad/src/common/mac/GTMDefines.h deleted file mode 100644 index 14ffa7e13..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMDefines.h +++ /dev/null @@ -1,456 +0,0 @@ -// -// GTMDefines.h -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// ============================================================================ - -#include -#include - -#ifdef __OBJC__ -#include -#endif // __OBJC__ - -#if TARGET_OS_IPHONE -#include -#endif // TARGET_OS_IPHONE - -// Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs -#ifndef MAC_OS_X_VERSION_10_5 - #define MAC_OS_X_VERSION_10_5 1050 -#endif -#ifndef MAC_OS_X_VERSION_10_6 - #define MAC_OS_X_VERSION_10_6 1060 -#endif -#ifndef MAC_OS_X_VERSION_10_7 - #define MAC_OS_X_VERSION_10_7 1070 -#endif - -// Not all __IPHONE_X macros defined in past SDKs -#ifndef __IPHONE_3_0 - #define __IPHONE_3_0 30000 -#endif -#ifndef __IPHONE_3_1 - #define __IPHONE_3_1 30100 -#endif -#ifndef __IPHONE_3_2 - #define __IPHONE_3_2 30200 -#endif -#ifndef __IPHONE_4_0 - #define __IPHONE_4_0 40000 -#endif -#ifndef __IPHONE_4_3 - #define __IPHONE_4_3 40300 -#endif -#ifndef __IPHONE_5_0 - #define __IPHONE_5_0 50000 -#endif - -// ---------------------------------------------------------------------------- -// CPP symbols that can be overridden in a prefix to control how the toolbox -// is compiled. -// ---------------------------------------------------------------------------- - - -// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and -// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens -// when a validation fails. If you implement your own validators, you may want -// to control their internals using the same macros for consistency. -#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0 -#endif - -// Give ourselves a consistent way to do inlines. Apple's macros even use -// a few different actual definitions, so we're based off of the foundation -// one. -#if !defined(GTM_INLINE) - #if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__) - #define GTM_INLINE static __inline__ __attribute__((always_inline)) - #else - #define GTM_INLINE static __inline__ - #endif -#endif - -// Give ourselves a consistent way of doing externs that links up nicely -// when mixing objc and objc++ -#if !defined (GTM_EXTERN) - #if defined __cplusplus - #define GTM_EXTERN extern "C" - #define GTM_EXTERN_C_BEGIN extern "C" { - #define GTM_EXTERN_C_END } - #else - #define GTM_EXTERN extern - #define GTM_EXTERN_C_BEGIN - #define GTM_EXTERN_C_END - #endif -#endif - -// Give ourselves a consistent way of exporting things if we have visibility -// set to hidden. -#if !defined (GTM_EXPORT) - #define GTM_EXPORT __attribute__((visibility("default"))) -#endif - -// Give ourselves a consistent way of declaring something as unused. This -// doesn't use __unused because that is only supported in gcc 4.2 and greater. -#if !defined (GTM_UNUSED) -#define GTM_UNUSED(x) ((void)(x)) -#endif - -// _GTMDevLog & _GTMDevAssert -// -// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for -// developer level errors. This implementation simply macros to NSLog/NSAssert. -// It is not intended to be a general logging/reporting system. -// -// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert -// for a little more background on the usage of these macros. -// -// _GTMDevLog log some error/problem in debug builds -// _GTMDevAssert assert if conditon isn't met w/in a method/function -// in all builds. -// -// To replace this system, just provide different macro definitions in your -// prefix header. Remember, any implementation you provide *must* be thread -// safe since this could be called by anything in what ever situtation it has -// been placed in. -// - -// We only define the simple macros if nothing else has defined this. -#ifndef _GTMDevLog - -#ifdef DEBUG - #define _GTMDevLog(...) NSLog(__VA_ARGS__) -#else - #define _GTMDevLog(...) do { } while (0) -#endif - -#endif // _GTMDevLog - -#ifndef _GTMDevAssert -// we directly invoke the NSAssert handler so we can pass on the varargs -// (NSAssert doesn't have a macro we can use that takes varargs) -#if !defined(NS_BLOCK_ASSERTIONS) - #define _GTMDevAssert(condition, ...) \ - do { \ - if (!(condition)) { \ - [[NSAssertionHandler currentHandler] \ - handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \ - file:[NSString stringWithUTF8String:__FILE__] \ - lineNumber:__LINE__ \ - description:__VA_ARGS__]; \ - } \ - } while(0) -#else // !defined(NS_BLOCK_ASSERTIONS) - #define _GTMDevAssert(condition, ...) do { } while (0) -#endif // !defined(NS_BLOCK_ASSERTIONS) - -#endif // _GTMDevAssert - -// _GTMCompileAssert -// _GTMCompileAssert is an assert that is meant to fire at compile time if you -// want to check things at compile instead of runtime. For example if you -// want to check that a wchar is 4 bytes instead of 2 you would use -// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X) -// Note that the second "arg" is not in quotes, and must be a valid processor -// symbol in it's own right (no spaces, punctuation etc). - -// Wrapping this in an #ifndef allows external groups to define their own -// compile time assert scheme. -#ifndef _GTMCompileAssert - // We got this technique from here: - // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html - - #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg - #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg) - #define _GTMCompileAssert(test, msg) \ - typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ] -#endif // _GTMCompileAssert - -// ---------------------------------------------------------------------------- -// CPP symbols defined based on the project settings so the GTM code has -// simple things to test against w/o scattering the knowledge of project -// setting through all the code. -// ---------------------------------------------------------------------------- - -// Provide a single constant CPP symbol that all of GTM uses for ifdefing -// iPhone code. -#if TARGET_OS_IPHONE // iPhone SDK - // For iPhone specific stuff - #define GTM_IPHONE_SDK 1 - #if TARGET_IPHONE_SIMULATOR - #define GTM_IPHONE_DEVICE 0 - #define GTM_IPHONE_SIMULATOR 1 - #else - #define GTM_IPHONE_DEVICE 1 - #define GTM_IPHONE_SIMULATOR 0 - #endif // TARGET_IPHONE_SIMULATOR - // By default, GTM has provided it's own unittesting support, define this - // to use the support provided by Xcode, especially for the Xcode4 support - // for unittesting. - #ifndef GTM_IPHONE_USE_SENTEST - #define GTM_IPHONE_USE_SENTEST 0 - #endif - #define GTM_MACOS_SDK 0 -#else - // For MacOS specific stuff - #define GTM_MACOS_SDK 1 - #define GTM_IPHONE_SDK 0 - #define GTM_IPHONE_SIMULATOR 0 - #define GTM_IPHONE_DEVICE 0 - #define GTM_IPHONE_USE_SENTEST 0 -#endif - -// Some of our own availability macros -#if GTM_MACOS_SDK -#define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE -#define GTM_AVAILABLE_ONLY_ON_MACOS -#else -#define GTM_AVAILABLE_ONLY_ON_IPHONE -#define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE -#endif - -// GC was dropped by Apple, define the old constant incase anyone still keys -// off of it. -#ifndef GTM_SUPPORT_GC - #define GTM_SUPPORT_GC 0 -#endif - -// To simplify support for 64bit (and Leopard in general), we provide the type -// defines for non Leopard SDKs -#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - // NSInteger/NSUInteger and Max/Mins - #ifndef NSINTEGER_DEFINED - #if (defined(__LP64__) && __LP64__) || NS_BUILD_32_LIKE_64 - typedef long NSInteger; - typedef unsigned long NSUInteger; - #else - typedef int NSInteger; - typedef unsigned int NSUInteger; - #endif - #define NSIntegerMax LONG_MAX - #define NSIntegerMin LONG_MIN - #define NSUIntegerMax ULONG_MAX - #define NSINTEGER_DEFINED 1 - #endif // NSINTEGER_DEFINED - // CGFloat - #ifndef CGFLOAT_DEFINED - #if defined(__LP64__) && __LP64__ - // This really is an untested path (64bit on Tiger?) - typedef double CGFloat; - #define CGFLOAT_MIN DBL_MIN - #define CGFLOAT_MAX DBL_MAX - #define CGFLOAT_IS_DOUBLE 1 - #else /* !defined(__LP64__) || !__LP64__ */ - typedef float CGFloat; - #define CGFLOAT_MIN FLT_MIN - #define CGFLOAT_MAX FLT_MAX - #define CGFLOAT_IS_DOUBLE 0 - #endif /* !defined(__LP64__) || !__LP64__ */ - #define CGFLOAT_DEFINED 1 - #endif // CGFLOAT_DEFINED -#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - -// Some support for advanced clang static analysis functionality -// See http://clang-analyzer.llvm.org/annotations.html -#ifndef __has_feature // Optional. - #define __has_feature(x) 0 // Compatibility with non-clang compilers. -#endif - -#ifndef NS_RETURNS_RETAINED - #if __has_feature(attribute_ns_returns_retained) - #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) - #else - #define NS_RETURNS_RETAINED - #endif -#endif - -#ifndef NS_RETURNS_NOT_RETAINED - #if __has_feature(attribute_ns_returns_not_retained) - #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) - #else - #define NS_RETURNS_NOT_RETAINED - #endif -#endif - -#ifndef CF_RETURNS_RETAINED - #if __has_feature(attribute_cf_returns_retained) - #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) - #else - #define CF_RETURNS_RETAINED - #endif -#endif - -#ifndef CF_RETURNS_NOT_RETAINED - #if __has_feature(attribute_cf_returns_not_retained) - #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) - #else - #define CF_RETURNS_NOT_RETAINED - #endif -#endif - -#ifndef NS_CONSUMED - #if __has_feature(attribute_ns_consumed) - #define NS_CONSUMED __attribute__((ns_consumed)) - #else - #define NS_CONSUMED - #endif -#endif - -#ifndef CF_CONSUMED - #if __has_feature(attribute_cf_consumed) - #define CF_CONSUMED __attribute__((cf_consumed)) - #else - #define CF_CONSUMED - #endif -#endif - -#ifndef NS_CONSUMES_SELF - #if __has_feature(attribute_ns_consumes_self) - #define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) - #else - #define NS_CONSUMES_SELF - #endif -#endif - -// Defined on 10.6 and above. -#ifndef NS_FORMAT_ARGUMENT - #define NS_FORMAT_ARGUMENT(A) -#endif - -// Defined on 10.6 and above. -#ifndef NS_FORMAT_FUNCTION - #define NS_FORMAT_FUNCTION(F,A) -#endif - -// Defined on 10.6 and above. -#ifndef CF_FORMAT_ARGUMENT - #define CF_FORMAT_ARGUMENT(A) -#endif - -// Defined on 10.6 and above. -#ifndef CF_FORMAT_FUNCTION - #define CF_FORMAT_FUNCTION(F,A) -#endif - -#ifndef GTM_NONNULL - #if defined(__has_attribute) - #if __has_attribute(nonnull) - #define GTM_NONNULL(x) __attribute__((nonnull x)) - #else - #define GTM_NONNULL(x) - #endif - #else - #define GTM_NONNULL(x) - #endif -#endif - -// Invalidates the initializer from which it's called. -#ifndef GTMInvalidateInitializer - #if __has_feature(objc_arc) - #define GTMInvalidateInitializer() \ - do { \ - [self class]; /* Avoid warning of dead store to |self|. */ \ - _GTMDevAssert(NO, @"Invalid initializer."); \ - return nil; \ - } while (0) - #else - #define GTMInvalidateInitializer() \ - do { \ - [self release]; \ - _GTMDevAssert(NO, @"Invalid initializer."); \ - return nil; \ - } while (0) - #endif -#endif - -#ifndef GTMCFAutorelease - #if __has_feature(objc_arc) - #define GTMCFAutorelease(x) CFBridgingRelease(x) - #else - #define GTMCFAutorelease(x) ([(id)x autorelease]) - #endif -#endif - -#ifdef __OBJC__ - -// Declared here so that it can easily be used for logging tracking if -// necessary. See GTMUnitTestDevLog.h for details. -@class NSString; -GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2); - -// Macro to allow you to create NSStrings out of other macros. -// #define FOO foo -// NSString *fooString = GTM_NSSTRINGIFY(FOO); -#if !defined (GTM_NSSTRINGIFY) - #define GTM_NSSTRINGIFY_INNER(x) @#x - #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x) -#endif - -// Macro to allow fast enumeration when building for 10.5 or later, and -// reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration -// does keys, so pick the right thing, nothing is done on the FastEnumeration -// side to be sure you're getting what you wanted. -#ifndef GTM_FOREACH_OBJECT - #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - #define GTM_FOREACH_ENUMEREE(element, enumeration) \ - for (element in enumeration) - #define GTM_FOREACH_OBJECT(element, collection) \ - for (element in collection) - #define GTM_FOREACH_KEY(element, collection) \ - for (element in collection) - #else - #define GTM_FOREACH_ENUMEREE(element, enumeration) \ - for (NSEnumerator *_ ## element ## _enum = enumeration; \ - (element = [_ ## element ## _enum nextObject]) != nil; ) - #define GTM_FOREACH_OBJECT(element, collection) \ - GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator]) - #define GTM_FOREACH_KEY(element, collection) \ - GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator]) - #endif -#endif - -// ============================================================================ - -// To simplify support for both Leopard and Snow Leopard we declare -// the Snow Leopard protocols that we need here. -#if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) -#define GTM_10_6_PROTOCOLS_DEFINED 1 -@protocol NSConnectionDelegate -@end -@protocol NSAnimationDelegate -@end -@protocol NSImageDelegate -@end -@protocol NSTabViewDelegate -@end -#endif // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) - -// GTM_SEL_STRING is for specifying selector (usually property) names to KVC -// or KVO methods. -// In debug it will generate warnings for undeclared selectors if -// -Wunknown-selector is turned on. -// In release it will have no runtime overhead. -#ifndef GTM_SEL_STRING - #ifdef DEBUG - #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName)) - #else - #define GTM_SEL_STRING(selName) @#selName - #endif // DEBUG -#endif // GTM_SEL_STRING - -#endif // __OBJC__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.h b/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.h deleted file mode 100644 index c4fd14029..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.h +++ /dev/null @@ -1,504 +0,0 @@ -// -// GTMLogger.h -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// Key Abstractions -// ---------------- -// -// This file declares multiple classes and protocols that are used by the -// GTMLogger logging system. The 4 main abstractions used in this file are the -// following: -// -// * logger (GTMLogger) - The main logging class that users interact with. It -// has methods for logging at different levels and uses a log writer, a log -// formatter, and a log filter to get the job done. -// -// * log writer (GTMLogWriter) - Writes a given string to some log file, where -// a "log file" can be a physical file on disk, a POST over HTTP to some URL, -// or even some in-memory structure (e.g., a ring buffer). -// -// * log formatter (GTMLogFormatter) - Given a format string and arguments as -// a va_list, returns a single formatted NSString. A "formatted string" could -// be a string with the date prepended, a string with values in a CSV format, -// or even a string of XML. -// -// * log filter (GTMLogFilter) - Given a formatted log message as an NSString -// and the level at which the message is to be logged, this class will decide -// whether the given message should be logged or not. This is a flexible way -// to filter out messages logged at a certain level, messages that contain -// certain text, or filter nothing out at all. This gives the caller the -// flexibility to dynamically enable debug logging in Release builds. -// -// This file also declares some classes to handle the common log writer, log -// formatter, and log filter cases. Callers can also create their own writers, -// formatters, and filters and they can even build them on top of the ones -// declared here. Keep in mind that your custom writer/formatter/filter may be -// called from multiple threads, so it must be thread-safe. - -#import -#import "GTMDefines.h" - -// Predeclaration of used protocols that are declared later in this file. -@protocol GTMLogWriter, GTMLogFormatter, GTMLogFilter; - -// GTMLogger -// -// GTMLogger is the primary user-facing class for an object-oriented logging -// system. It is built on the concept of log formatters (GTMLogFormatter), log -// writers (GTMLogWriter), and log filters (GTMLogFilter). When a message is -// sent to a GTMLogger to log a message, the message is formatted using the log -// formatter, then the log filter is consulted to see if the message should be -// logged, and if so, the message is sent to the log writer to be written out. -// -// GTMLogger is intended to be a flexible and thread-safe logging solution. Its -// flexibility comes from the fact that GTMLogger instances can be customized -// with user defined formatters, filters, and writers. And these writers, -// filters, and formatters can be combined, stacked, and customized in arbitrary -// ways to suit the needs at hand. For example, multiple writers can be used at -// the same time, and a GTMLogger instance can even be used as another -// GTMLogger's writer. This allows for arbitrarily deep logging trees. -// -// A standard GTMLogger uses a writer that sends messages to standard out, a -// formatter that smacks a timestamp and a few other bits of interesting -// information on the message, and a filter that filters out debug messages from -// release builds. Using the standard log settings, a log message will look like -// the following: -// -// 2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] foo= -// -// The output contains the date and time of the log message, the name of the -// process followed by its process ID/thread ID, the log level at which the -// message was logged (in the previous example the level was 1: -// kGTMLoggerLevelDebug), and finally, the user-specified log message itself (in -// this case, the log message was @"foo=%@", foo). -// -// Multiple instances of GTMLogger can be created, each configured their own -// way. Though GTMLogger is not a singleton (in the GoF sense), it does provide -// access to a shared (i.e., globally accessible) GTMLogger instance. This makes -// it convenient for all code in a process to use the same GTMLogger instance. -// The shared GTMLogger instance can also be configured in an arbitrary, and -// these configuration changes will affect all code that logs through the shared -// instance. - -// -// Log Levels -// ---------- -// GTMLogger has 3 different log levels: Debug, Info, and Error. GTMLogger -// doesn't take any special action based on the log level; it simply forwards -// this information on to formatters, filters, and writers, each of which may -// optionally take action based on the level. Since log level filtering is -// performed at runtime, log messages are typically not filtered out at compile -// time. The exception to this rule is that calls to the GTMLoggerDebug() macro -// *ARE* filtered out of non-DEBUG builds. This is to be backwards compatible -// with behavior that many developers are currently used to. Note that this -// means that GTMLoggerDebug(@"hi") will be compiled out of Release builds, but -// [[GTMLogger sharedLogger] logDebug:@"hi"] will NOT be compiled out. -// -// Standard loggers are created with the GTMLogLevelFilter log filter, which -// filters out certain log messages based on log level, and some other settings. -// -// In addition to the -logDebug:, -logInfo:, and -logError: methods defined on -// GTMLogger itself, there are also C macros that make usage of the shared -// GTMLogger instance very convenient. These macros are: -// -// GTMLoggerDebug(...) -// GTMLoggerInfo(...) -// GTMLoggerError(...) -// -// Again, a notable feature of these macros is that GTMLogDebug() calls *will be -// compiled out of non-DEBUG builds*. -// -// Standard Loggers -// ---------------- -// GTMLogger has the concept of "standard loggers". A standard logger is simply -// a logger that is pre-configured with some standard/common writer, formatter, -// and filter combination. Standard loggers are created using the creation -// methods beginning with "standard". The alternative to a standard logger is a -// regular logger, which will send messages to stdout, with no special -// formatting, and no filtering. -// -// How do I use GTMLogger? -// ---------------------- -// The typical way you will want to use GTMLogger is to simply use the -// GTMLogger*() macros for logging from code. That way we can easily make -// changes to the GTMLogger class and simply update the macros accordingly. Only -// your application startup code (perhaps, somewhere in main()) should use the -// GTMLogger class directly in order to configure the shared logger, which all -// of the code using the macros will be using. Again, this is just the typical -// situation. -// -// To be complete, there are cases where you may want to use GTMLogger directly, -// or even create separate GTMLogger instances for some reason. That's fine, -// too. -// -// Examples -// -------- -// The following show some common GTMLogger use cases. -// -// 1. You want to log something as simply as possible. Also, this call will only -// appear in debug builds. In non-DEBUG builds it will be completely removed. -// -// GTMLoggerDebug(@"foo = %@", foo); -// -// 2. The previous example is similar to the following. The major difference is -// that the previous call (example 1) will be compiled out of Release builds -// but this statement will not be compiled out. -// -// [[GTMLogger sharedLogger] logDebug:@"foo = %@", foo]; -// -// 3. Send all logging output from the shared logger to a file. We do this by -// creating an NSFileHandle for writing associated with a file, and setting -// that file handle as the logger's writer. -// -// NSFileHandle *f = [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log" -// create:YES]; -// [[GTMLogger sharedLogger] setWriter:f]; -// GTMLoggerError(@"hi"); // This will be sent to /tmp/f.log -// -// 4. Create a new GTMLogger that will log to a file. This example differs from -// the previous one because here we create a new GTMLogger that is different -// from the shared logger. -// -// GTMLogger *logger = [GTMLogger standardLoggerWithPath:@"/tmp/temp.log"]; -// [logger logInfo:@"hi temp log file"]; -// -// 5. Create a logger that writes to stdout and does NOT do any formatting to -// the log message. This might be useful, for example, when writing a help -// screen for a command-line tool to standard output. -// -// GTMLogger *logger = [GTMLogger logger]; -// [logger logInfo:@"%@ version 0.1 usage", progName]; -// -// 6. Send log output to stdout AND to a log file. The trick here is that -// NSArrays function as composite log writers, which means when an array is -// set as the log writer, it forwards all logging messages to all of its -// contained GTMLogWriters. -// -// // Create array of GTMLogWriters -// NSArray *writers = [NSArray arrayWithObjects: -// [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log" create:YES], -// [NSFileHandle fileHandleWithStandardOutput], nil]; -// -// GTMLogger *logger = [GTMLogger standardLogger]; -// [logger setWriter:writers]; -// [logger logInfo:@"hi"]; // Output goes to stdout and /tmp/f.log -// -// For futher details on log writers, formatters, and filters, see the -// documentation below. -// -// NOTE: GTMLogger is application level logging. By default it does nothing -// with _GTMDevLog/_GTMDevAssert (see GTMDefines.h). An application can choose -// to bridge _GTMDevLog/_GTMDevAssert to GTMLogger by providing macro -// definitions in its prefix header (see GTMDefines.h for how one would do -// that). -// -@interface GTMLogger : NSObject { - @private - id writer_; - id formatter_; - id filter_; -} - -// -// Accessors for the shared logger instance -// - -// Returns a shared/global standard GTMLogger instance. Callers should typically -// use this method to get a GTMLogger instance, unless they explicitly want -// their own instance to configure for their own needs. This is the only method -// that returns a shared instance; all the rest return new GTMLogger instances. -+ (id)sharedLogger; - -// Sets the shared logger instance to |logger|. Future calls to +sharedLogger -// will return |logger| instead. -+ (void)setSharedLogger:(GTMLogger *)logger; - -// -// Creation methods -// - -// Returns a new autoreleased GTMLogger instance that will log to stdout, using -// the GTMLogStandardFormatter, and the GTMLogLevelFilter filter. -+ (id)standardLogger; - -// Same as +standardLogger, but logs to stderr. -+ (id)standardLoggerWithStderr; - -// Same as +standardLogger but levels >= kGTMLoggerLevelError are routed to -// stderr, everything else goes to stdout. -+ (id)standardLoggerWithStdoutAndStderr; - -// Returns a new standard GTMLogger instance with a log writer that will -// write to the file at |path|, and will use the GTMLogStandardFormatter and -// GTMLogLevelFilter classes. If |path| does not exist, it will be created. -+ (id)standardLoggerWithPath:(NSString *)path; - -// Returns an autoreleased GTMLogger instance that will use the specified -// |writer|, |formatter|, and |filter|. -+ (id)loggerWithWriter:(id)writer - formatter:(id)formatter - filter:(id)filter; - -// Returns an autoreleased GTMLogger instance that logs to stdout, with the -// basic formatter, and no filter. The returned logger differs from the logger -// returned by +standardLogger because this one does not do any filtering and -// does not do any special log formatting; this is the difference between a -// "regular" logger and a "standard" logger. -+ (id)logger; - -// Designated initializer. This method returns a GTMLogger initialized with the -// specified |writer|, |formatter|, and |filter|. See the setter methods below -// for what values will be used if nil is passed for a parameter. -- (id)initWithWriter:(id)writer - formatter:(id)formatter - filter:(id)filter; - -// -// Logging methods -// - -// Logs a message at the debug level (kGTMLoggerLevelDebug). -- (void)logDebug:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2); -// Logs a message at the info level (kGTMLoggerLevelInfo). -- (void)logInfo:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2); -// Logs a message at the error level (kGTMLoggerLevelError). -- (void)logError:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2); -// Logs a message at the assert level (kGTMLoggerLevelAssert). -- (void)logAssert:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2); - - -// -// Accessors -// - -// Accessor methods for the log writer. If the log writer is set to nil, -// [NSFileHandle fileHandleWithStandardOutput] is used. -- (id)writer; -- (void)setWriter:(id)writer; - -// Accessor methods for the log formatter. If the log formatter is set to nil, -// GTMLogBasicFormatter is used. This formatter will format log messages in a -// plain printf style. -- (id)formatter; -- (void)setFormatter:(id)formatter; - -// Accessor methods for the log filter. If the log filter is set to nil, -// GTMLogNoFilter is used, which allows all log messages through. -- (id)filter; -- (void)setFilter:(id)filter; - -@end // GTMLogger - - -// Helper functions that are used by the convenience GTMLogger*() macros that -// enable the logging of function names. -@interface GTMLogger (GTMLoggerMacroHelpers) -- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... - NS_FORMAT_FUNCTION(2, 3); -- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ... - NS_FORMAT_FUNCTION(2, 3); -- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ... - NS_FORMAT_FUNCTION(2, 3); -- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ... - NS_FORMAT_FUNCTION(2, 3); -@end // GTMLoggerMacroHelpers - - -// The convenience macros are only defined if they haven't already been defined. -#ifndef GTMLoggerInfo - -// Convenience macros that log to the shared GTMLogger instance. These macros -// are how users should typically log to GTMLogger. Notice that GTMLoggerDebug() -// calls will be compiled out of non-Debug builds. -#define GTMLoggerDebug(...) \ - [[GTMLogger sharedLogger] logFuncDebug:__func__ msg:__VA_ARGS__] -#define GTMLoggerInfo(...) \ - [[GTMLogger sharedLogger] logFuncInfo:__func__ msg:__VA_ARGS__] -#define GTMLoggerError(...) \ - [[GTMLogger sharedLogger] logFuncError:__func__ msg:__VA_ARGS__] -#define GTMLoggerAssert(...) \ - [[GTMLogger sharedLogger] logFuncAssert:__func__ msg:__VA_ARGS__] - -// If we're not in a debug build, remove the GTMLoggerDebug statements. This -// makes calls to GTMLoggerDebug "compile out" of Release builds -#ifndef DEBUG -#undef GTMLoggerDebug -#define GTMLoggerDebug(...) do {} while(0) -#endif - -#endif // !defined(GTMLoggerInfo) - -// Log levels. -typedef enum { - kGTMLoggerLevelUnknown, - kGTMLoggerLevelDebug, - kGTMLoggerLevelInfo, - kGTMLoggerLevelError, - kGTMLoggerLevelAssert, -} GTMLoggerLevel; - - -// -// Log Writers -// - -// Protocol to be implemented by a GTMLogWriter instance. -@protocol GTMLogWriter -// Writes the given log message to where the log writer is configured to write. -- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level; -@end // GTMLogWriter - - -// Simple category on NSFileHandle that makes NSFileHandles valid log writers. -// This is convenient because something like, say, +fileHandleWithStandardError -// now becomes a valid log writer. Log messages are written to the file handle -// with a newline appended. -@interface NSFileHandle (GTMFileHandleLogWriter) -// Opens the file at |path| in append mode, and creates the file with |mode| -// if it didn't previously exist. -+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode; -@end // NSFileHandle - - -// This category makes NSArray a GTMLogWriter that can be composed of other -// GTMLogWriters. This is the classic Composite GoF design pattern. When the -// GTMLogWriter -logMessage:level: message is sent to the array, the array -// forwards the message to all of its elements that implement the GTMLogWriter -// protocol. -// -// This is useful in situations where you would like to send log output to -// multiple log writers at the same time. Simply create an NSArray of the log -// writers you wish to use, then set the array as the "writer" for your -// GTMLogger instance. -@interface NSArray (GTMArrayCompositeLogWriter) -@end // GTMArrayCompositeLogWriter - - -// This category adapts the GTMLogger interface so that it can be used as a log -// writer; it's an "adapter" in the GoF Adapter pattern sense. -// -// This is useful when you want to configure a logger to log to a specific -// writer with a specific formatter and/or filter. But you want to also compose -// that with a different log writer that may have its own formatter and/or -// filter. -@interface GTMLogger (GTMLoggerLogWriter) -@end // GTMLoggerLogWriter - - -// -// Log Formatters -// - -// Protocol to be implemented by a GTMLogFormatter instance. -@protocol GTMLogFormatter -// Returns a formatted string using the format specified in |fmt| and the va -// args specified in |args|. -- (NSString *)stringForFunc:(NSString *)func - withFormat:(NSString *)fmt - valist:(va_list)args - level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0); -@end // GTMLogFormatter - - -// A basic log formatter that formats a string the same way that NSLog (or -// printf) would. It does not do anything fancy, nor does it add any data of its -// own. -@interface GTMLogBasicFormatter : NSObject - -// Helper method for prettying C99 __func__ and GCC __PRETTY_FUNCTION__ -- (NSString *)prettyNameForFunc:(NSString *)func; - -@end // GTMLogBasicFormatter - - -// A log formatter that formats the log string like the basic formatter, but -// also prepends a timestamp and some basic process info to the message, as -// shown in the following sample output. -// 2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] log mesage here -@interface GTMLogStandardFormatter : GTMLogBasicFormatter { - @private - NSDateFormatter *dateFormatter_; // yyyy-MM-dd HH:mm:ss.SSS - NSString *pname_; - pid_t pid_; -} -@end // GTMLogStandardFormatter - - -// -// Log Filters -// - -// Protocol to be imlemented by a GTMLogFilter instance. -@protocol GTMLogFilter -// Returns YES if |msg| at |level| should be filtered out; NO otherwise. -- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level; -@end // GTMLogFilter - - -// A log filter that filters messages at the kGTMLoggerLevelDebug level out of -// non-debug builds. Messages at the kGTMLoggerLevelInfo level are also filtered -// out of non-debug builds unless GTMVerboseLogging is set in the environment or -// the processes's defaults. Messages at the kGTMLoggerLevelError level are -// never filtered. -@interface GTMLogLevelFilter : NSObject -@end // GTMLogLevelFilter - -// A simple log filter that does NOT filter anything out; -// -filterAllowsMessage:level will always return YES. This can be a convenient -// way to enable debug-level logging in release builds (if you so desire). -@interface GTMLogNoFilter : NSObject -@end // GTMLogNoFilter - - -// Base class for custom level filters. Not for direct use, use the minimum -// or maximum level subclasses below. -@interface GTMLogAllowedLevelFilter : NSObject { - @private - NSIndexSet *allowedLevels_; -} -@end - -// A log filter that allows you to set a minimum log level. Messages below this -// level will be filtered. -@interface GTMLogMininumLevelFilter : GTMLogAllowedLevelFilter - -// Designated initializer, logs at levels < |level| will be filtered. -- (id)initWithMinimumLevel:(GTMLoggerLevel)level; - -@end - -// A log filter that allows you to set a maximum log level. Messages whose level -// exceeds this level will be filtered. This is really only useful if you have -// a composite GTMLogger that is sending the other messages elsewhere. -@interface GTMLogMaximumLevelFilter : GTMLogAllowedLevelFilter - -// Designated initializer, logs at levels > |level| will be filtered. -- (id)initWithMaximumLevel:(GTMLoggerLevel)level; - -@end - - -// For subclasses only -@interface GTMLogger (PrivateMethods) - -- (void)logInternalFunc:(const char *)func - format:(NSString *)fmt - valist:(va_list)args - level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0); - -@end - diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m b/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m deleted file mode 100644 index ebc5836a2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m +++ /dev/null @@ -1,611 +0,0 @@ -// -// GTMLogger.m -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMLogger.h" -#import -#import -#import -#import - - -#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) -// Some versions of GCC (4.2 and below AFAIK) aren't great about supporting -// -Wmissing-format-attribute -// when the function is anything more complex than foo(NSString *fmt, ...). -// You see the error inside the function when you turn ... into va_args and -// attempt to call another function (like vsprintf for example). -// So we just shut off the warning for this file. We reenable it at the end. -#pragma GCC diagnostic ignored "-Wmissing-format-attribute" -#endif // !__clang__ - -// Reference to the shared GTMLogger instance. This is not a singleton, it's -// just an easy reference to one shared instance. -static GTMLogger *gSharedLogger = nil; - - -@implementation GTMLogger - -// Returns a pointer to the shared logger instance. If none exists, a standard -// logger is created and returned. -+ (id)sharedLogger { - @synchronized(self) { - if (gSharedLogger == nil) { - gSharedLogger = [[self standardLogger] retain]; - } - } - return [[gSharedLogger retain] autorelease]; -} - -+ (void)setSharedLogger:(GTMLogger *)logger { - @synchronized(self) { - [gSharedLogger autorelease]; - gSharedLogger = [logger retain]; - } -} - -+ (id)standardLogger { - // Don't trust NSFileHandle not to throw - @try { - id writer = [NSFileHandle fileHandleWithStandardOutput]; - id fr = [[[GTMLogStandardFormatter alloc] init] - autorelease]; - id filter = [[[GTMLogLevelFilter alloc] init] autorelease]; - return [[[self alloc] initWithWriter:writer - formatter:fr - filter:filter] autorelease]; - } - @catch (id e) { - // Ignored - } - return nil; -} - -+ (id)standardLoggerWithStderr { - // Don't trust NSFileHandle not to throw - @try { - id me = [self standardLogger]; - [me setWriter:[NSFileHandle fileHandleWithStandardError]]; - return me; - } - @catch (id e) { - // Ignored - } - return nil; -} - -+ (id)standardLoggerWithStdoutAndStderr { - // We're going to take advantage of the GTMLogger to GTMLogWriter adaptor - // and create a composite logger that an outer "standard" logger can use - // as a writer. Our inner loggers should apply no formatting since the main - // logger does that and we want the caller to be able to change formatters - // or add writers without knowing the inner structure of our composite. - - // Don't trust NSFileHandle not to throw - @try { - GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init] - autorelease]; - GTMLogger *stdoutLogger = - [self loggerWithWriter:[NSFileHandle fileHandleWithStandardOutput] - formatter:formatter - filter:[[[GTMLogMaximumLevelFilter alloc] - initWithMaximumLevel:kGTMLoggerLevelInfo] - autorelease]]; - GTMLogger *stderrLogger = - [self loggerWithWriter:[NSFileHandle fileHandleWithStandardError] - formatter:formatter - filter:[[[GTMLogMininumLevelFilter alloc] - initWithMinimumLevel:kGTMLoggerLevelError] - autorelease]]; - GTMLogger *compositeWriter = - [self loggerWithWriter:[NSArray arrayWithObjects: - stdoutLogger, stderrLogger, nil] - formatter:formatter - filter:[[[GTMLogNoFilter alloc] init] autorelease]]; - GTMLogger *outerLogger = [self standardLogger]; - [outerLogger setWriter:compositeWriter]; - return outerLogger; - } - @catch (id e) { - // Ignored - } - return nil; -} - -+ (id)standardLoggerWithPath:(NSString *)path { - @try { - NSFileHandle *fh = [NSFileHandle fileHandleForLoggingAtPath:path mode:0644]; - if (fh == nil) return nil; - id me = [self standardLogger]; - [me setWriter:fh]; - return me; - } - @catch (id e) { - // Ignored - } - return nil; -} - -+ (id)loggerWithWriter:(id)writer - formatter:(id)formatter - filter:(id)filter { - return [[[self alloc] initWithWriter:writer - formatter:formatter - filter:filter] autorelease]; -} - -+ (id)logger { - return [[[self alloc] init] autorelease]; -} - -- (id)init { - return [self initWithWriter:nil formatter:nil filter:nil]; -} - -- (id)initWithWriter:(id)writer - formatter:(id)formatter - filter:(id)filter { - if ((self = [super init])) { - [self setWriter:writer]; - [self setFormatter:formatter]; - [self setFilter:filter]; - } - return self; -} - -- (void)dealloc { - // Unlikely, but |writer_| may be an NSFileHandle, which can throw - @try { - [formatter_ release]; - [filter_ release]; - [writer_ release]; - } - @catch (id e) { - // Ignored - } - [super dealloc]; -} - -- (id)writer { - return [[writer_ retain] autorelease]; -} - -- (void)setWriter:(id)writer { - @synchronized(self) { - [writer_ autorelease]; - writer_ = nil; - if (writer == nil) { - // Try to use stdout, but don't trust NSFileHandle - @try { - writer_ = [[NSFileHandle fileHandleWithStandardOutput] retain]; - } - @catch (id e) { - // Leave |writer_| nil - } - } else { - writer_ = [writer retain]; - } - } -} - -- (id)formatter { - return [[formatter_ retain] autorelease]; -} - -- (void)setFormatter:(id)formatter { - @synchronized(self) { - [formatter_ autorelease]; - formatter_ = nil; - if (formatter == nil) { - @try { - formatter_ = [[GTMLogBasicFormatter alloc] init]; - } - @catch (id e) { - // Leave |formatter_| nil - } - } else { - formatter_ = [formatter retain]; - } - } -} - -- (id)filter { - return [[filter_ retain] autorelease]; -} - -- (void)setFilter:(id)filter { - @synchronized(self) { - [filter_ autorelease]; - filter_ = nil; - if (filter == nil) { - @try { - filter_ = [[GTMLogNoFilter alloc] init]; - } - @catch (id e) { - // Leave |filter_| nil - } - } else { - filter_ = [filter retain]; - } - } -} - -- (void)logDebug:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelDebug]; - va_end(args); -} - -- (void)logInfo:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelInfo]; - va_end(args); -} - -- (void)logError:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelError]; - va_end(args); -} - -- (void)logAssert:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelAssert]; - va_end(args); -} - -@end // GTMLogger - -@implementation GTMLogger (GTMLoggerMacroHelpers) - -- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelDebug]; - va_end(args); -} - -- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelInfo]; - va_end(args); -} - -- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelError]; - va_end(args); -} - -- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelAssert]; - va_end(args); -} - -@end // GTMLoggerMacroHelpers - -@implementation GTMLogger (PrivateMethods) - -- (void)logInternalFunc:(const char *)func - format:(NSString *)fmt - valist:(va_list)args - level:(GTMLoggerLevel)level { - // Primary point where logging happens, logging should never throw, catch - // everything. - @try { - NSString *fname = func ? [NSString stringWithUTF8String:func] : nil; - NSString *msg = [formatter_ stringForFunc:fname - withFormat:fmt - valist:args - level:level]; - if (msg && [filter_ filterAllowsMessage:msg level:level]) - [writer_ logMessage:msg level:level]; - } - @catch (id e) { - // Ignored - } -} - -@end // PrivateMethods - - -@implementation NSFileHandle (GTMFileHandleLogWriter) - -+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode { - int fd = -1; - if (path) { - int flags = O_WRONLY | O_APPEND | O_CREAT; - fd = open([path fileSystemRepresentation], flags, mode); - } - if (fd == -1) return nil; - return [[[self alloc] initWithFileDescriptor:fd - closeOnDealloc:YES] autorelease]; -} - -- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level { - @synchronized(self) { - // Closed pipes should not generate exceptions in our caller. Catch here - // as well [GTMLogger logInternalFunc:...] so that an exception in this - // writer does not prevent other writers from having a chance. - @try { - NSString *line = [NSString stringWithFormat:@"%@\n", msg]; - [self writeData:[line dataUsingEncoding:NSUTF8StringEncoding]]; - } - @catch (id e) { - // Ignored - } - } -} - -@end // GTMFileHandleLogWriter - - -@implementation NSArray (GTMArrayCompositeLogWriter) - -- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level { - @synchronized(self) { - id child = nil; - GTM_FOREACH_OBJECT(child, self) { - if ([child conformsToProtocol:@protocol(GTMLogWriter)]) - [child logMessage:msg level:level]; - } - } -} - -@end // GTMArrayCompositeLogWriter - - -@implementation GTMLogger (GTMLoggerLogWriter) - -- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level { - switch (level) { - case kGTMLoggerLevelDebug: - [self logDebug:@"%@", msg]; - break; - case kGTMLoggerLevelInfo: - [self logInfo:@"%@", msg]; - break; - case kGTMLoggerLevelError: - [self logError:@"%@", msg]; - break; - case kGTMLoggerLevelAssert: - [self logAssert:@"%@", msg]; - break; - default: - // Ignore the message. - break; - } -} - -@end // GTMLoggerLogWriter - - -@implementation GTMLogBasicFormatter - -- (NSString *)prettyNameForFunc:(NSString *)func { - NSString *name = [func stringByTrimmingCharactersInSet: - [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - NSString *function = @"(unknown)"; - if ([name length]) { - if (// Objective C __func__ and __PRETTY_FUNCTION__ - [name hasPrefix:@"-["] || [name hasPrefix:@"+["] || - // C++ __PRETTY_FUNCTION__ and other preadorned formats - [name hasSuffix:@")"]) { - function = name; - } else { - // Assume C99 __func__ - function = [NSString stringWithFormat:@"%@()", name]; - } - } - return function; -} - -- (NSString *)stringForFunc:(NSString *)func - withFormat:(NSString *)fmt - valist:(va_list)args - level:(GTMLoggerLevel)level { - // Performance note: We may want to do a quick check here to see if |fmt| - // contains a '%', and if not, simply return 'fmt'. - if (!(fmt && args)) return nil; - return [[[NSString alloc] initWithFormat:fmt arguments:args] autorelease]; -} - -@end // GTMLogBasicFormatter - - -@implementation GTMLogStandardFormatter - -- (id)init { - if ((self = [super init])) { - dateFormatter_ = [[NSDateFormatter alloc] init]; - [dateFormatter_ setFormatterBehavior:NSDateFormatterBehavior10_4]; - [dateFormatter_ setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"]; - pname_ = [[[NSProcessInfo processInfo] processName] copy]; - pid_ = [[NSProcessInfo processInfo] processIdentifier]; - if (!(dateFormatter_ && pname_)) { - [self release]; - return nil; - } - } - return self; -} - -- (void)dealloc { - [dateFormatter_ release]; - [pname_ release]; - [super dealloc]; -} - -- (NSString *)stringForFunc:(NSString *)func - withFormat:(NSString *)fmt - valist:(va_list)args - level:(GTMLoggerLevel)level { - NSString *tstamp = nil; - @synchronized (dateFormatter_) { - tstamp = [dateFormatter_ stringFromDate:[NSDate date]]; - } - return [NSString stringWithFormat:@"%@ %@[%d/%p] [lvl=%d] %@ %@", - tstamp, pname_, pid_, pthread_self(), - level, [self prettyNameForFunc:func], - // |super| has guard for nil |fmt| and |args| - [super stringForFunc:func withFormat:fmt valist:args level:level]]; -} - -@end // GTMLogStandardFormatter - - -@implementation GTMLogLevelFilter - -// Check the environment and the user preferences for the GTMVerboseLogging key -// to see if verbose logging has been enabled. The environment variable will -// override the defaults setting, so check the environment first. -// COV_NF_START -static BOOL IsVerboseLoggingEnabled(void) { - static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging"; - NSString *value = [[[NSProcessInfo processInfo] environment] - objectForKey:kVerboseLoggingKey]; - if (value) { - // Emulate [NSString boolValue] for pre-10.5 - value = [value stringByTrimmingCharactersInSet: - [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if ([[value uppercaseString] hasPrefix:@"Y"] || - [[value uppercaseString] hasPrefix:@"T"] || - [value intValue]) { - return YES; - } else { - return NO; - } - } - return [[NSUserDefaults standardUserDefaults] boolForKey:kVerboseLoggingKey]; -} -// COV_NF_END - -// In DEBUG builds, log everything. If we're not in a debug build we'll assume -// that we're in a Release build. -- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level { -#if defined(DEBUG) && DEBUG - return YES; -#endif - - BOOL allow = YES; - - switch (level) { - case kGTMLoggerLevelDebug: - allow = NO; - break; - case kGTMLoggerLevelInfo: - allow = IsVerboseLoggingEnabled(); - break; - case kGTMLoggerLevelError: - allow = YES; - break; - case kGTMLoggerLevelAssert: - allow = YES; - break; - default: - allow = YES; - break; - } - - return allow; -} - -@end // GTMLogLevelFilter - - -@implementation GTMLogNoFilter - -- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level { - return YES; // Allow everything through -} - -@end // GTMLogNoFilter - - -@implementation GTMLogAllowedLevelFilter - -// Private designated initializer -- (id)initWithAllowedLevels:(NSIndexSet *)levels { - self = [super init]; - if (self != nil) { - allowedLevels_ = [levels retain]; - // Cap min/max level - if (!allowedLevels_ || - // NSIndexSet is unsigned so only check the high bound, but need to - // check both first and last index because NSIndexSet appears to allow - // wraparound. - ([allowedLevels_ firstIndex] > kGTMLoggerLevelAssert) || - ([allowedLevels_ lastIndex] > kGTMLoggerLevelAssert)) { - [self release]; - return nil; - } - } - return self; -} - -- (id)init { - // Allow all levels in default init - return [self initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange: - NSMakeRange(kGTMLoggerLevelUnknown, - (kGTMLoggerLevelAssert - kGTMLoggerLevelUnknown + 1))]]; -} - -- (void)dealloc { - [allowedLevels_ release]; - [super dealloc]; -} - -- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level { - return [allowedLevels_ containsIndex:level]; -} - -@end // GTMLogAllowedLevelFilter - - -@implementation GTMLogMininumLevelFilter - -- (id)initWithMinimumLevel:(GTMLoggerLevel)level { - return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange: - NSMakeRange(level, - (kGTMLoggerLevelAssert - level + 1))]]; -} - -@end // GTMLogMininumLevelFilter - - -@implementation GTMLogMaximumLevelFilter - -- (id)initWithMaximumLevel:(GTMLoggerLevel)level { - return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange: - NSMakeRange(kGTMLoggerLevelUnknown, level + 1)]]; -} - -@end // GTMLogMaximumLevelFilter - -#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) -// See comment at top of file. -#pragma GCC diagnostic error "-Wmissing-format-attribute" -#endif // !__clang__ - diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.h b/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.h deleted file mode 100644 index 42e8fed39..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// HTTPMultipartUpload: A multipart/form-data HTTP uploader. -// Each parameter pair is sent as a boundary -// Each file is sent with a name field in addition to the filename and data -// The data will be sent synchronously. - -#import - -@interface HTTPMultipartUpload : NSObject { - @protected - NSURL *url_; // The destination URL (STRONG) - NSDictionary *parameters_; // The key/value pairs for sending data (STRONG) - NSMutableDictionary *files_; // Dictionary of name/file-path (STRONG) - NSString *boundary_; // The boundary string (STRONG) - NSHTTPURLResponse *response_; // The response from the send (STRONG) -} - -- (id)initWithURL:(NSURL *)url; - -- (NSURL *)URL; - -- (void)setParameters:(NSDictionary *)parameters; -- (NSDictionary *)parameters; - -- (void)addFileAtPath:(NSString *)path name:(NSString *)name; -- (void)addFileContents:(NSData *)data name:(NSString *)name; -- (NSDictionary *)files; - -// Set the data and return the response -- (NSData *)send:(NSError **)error; -- (NSHTTPURLResponse *)response; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.m b/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.m deleted file mode 100644 index 9ac886d53..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/HTTPMultipartUpload.m +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#import "HTTPMultipartUpload.h" -#import "GTMDefines.h" - -// As -[NSString stringByAddingPercentEscapesUsingEncoding:] has been -// deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements it -// using -[NSString stringByAddingPercentEncodingWithAllowedCharacters:] when -// using those SDKs. -static NSString *PercentEncodeNSString(NSString *key) { -#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_9_0) && \ - __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0) || \ - (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ - defined(MAC_OS_X_VERSION_10_11) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) - return [key stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]; -#else - return [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -#endif -} - -// As -[NSURLConnection sendSynchronousRequest:returningResponse:error:] has -// been deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements -// it using -[NSURLSession dataTaskWithRequest:completionHandler:] when using -// those SDKs. -static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, - NSURLResponse **out_response, - NSError **out_error) { -#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_9_0) && \ - __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0) || \ - (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ - defined(MAC_OS_X_VERSION_10_11) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) - __block NSData* result = nil; - __block NSError* error = nil; - __block NSURLResponse* response = nil; - dispatch_semaphore_t wait_semaphone = dispatch_semaphore_create(0); - [[[NSURLSession sharedSession] - dataTaskWithRequest:req - completionHandler:^(NSData *data, - NSURLResponse *resp, - NSError *err) { - if (out_error) - error = [err retain]; - if (out_response) - response = [resp retain]; - if (err == nil) - result = [data retain]; - dispatch_semaphore_signal(wait_semaphone); - }] resume]; - dispatch_semaphore_wait(wait_semaphone, DISPATCH_TIME_FOREVER); - dispatch_release(wait_semaphone); - if (out_error) - *out_error = [error autorelease]; - if (out_response) - *out_response = [response autorelease]; - return [result autorelease]; -#else - return [NSURLConnection sendSynchronousRequest:req - returningResponse:out_response - error:out_error]; -#endif -} -@interface HTTPMultipartUpload(PrivateMethods) -- (NSString *)multipartBoundary; -// Each of the following methods will append the starting multipart boundary, -// but not the ending one. -- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value; -- (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name; -- (NSData *)formDataForFile:(NSString *)file name:(NSString *)name; -@end - -@implementation HTTPMultipartUpload -//============================================================================= -#pragma mark - -#pragma mark || Private || -//============================================================================= -- (NSString *)multipartBoundary { - // The boundary has 27 '-' characters followed by 16 hex digits - return [NSString stringWithFormat:@"---------------------------%08X%08X", - rand(), rand()]; -} - -//============================================================================= -- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { - NSString *escaped = PercentEncodeNSString(key); - NSString *fmt = - @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; - NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; - - return [form dataUsingEncoding:NSUTF8StringEncoding]; -} - -//============================================================================= -- (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name { - NSMutableData *data = [NSMutableData data]; - NSString *escaped = PercentEncodeNSString(name); - NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"%@\"; " - "filename=\"minidump.dmp\"\r\nContent-Type: application/octet-stream\r\n\r\n"; - NSString *pre = [NSString stringWithFormat:fmt, boundary_, escaped]; - - [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; - [data appendData:contents]; - - return data; -} - -//============================================================================= -- (NSData *)formDataForFile:(NSString *)file name:(NSString *)name { - NSData *contents = [NSData dataWithContentsOfFile:file]; - - return [self formDataForFileContents:contents name:name]; -} - -//============================================================================= -#pragma mark - -#pragma mark || Public || -//============================================================================= -- (id)initWithURL:(NSURL *)url { - if ((self = [super init])) { - url_ = [url copy]; - boundary_ = [[self multipartBoundary] retain]; - files_ = [[NSMutableDictionary alloc] init]; - } - - return self; -} - -//============================================================================= -- (void)dealloc { - [url_ release]; - [parameters_ release]; - [files_ release]; - [boundary_ release]; - [response_ release]; - - [super dealloc]; -} - -//============================================================================= -- (NSURL *)URL { - return url_; -} - -//============================================================================= -- (void)setParameters:(NSDictionary *)parameters { - if (parameters != parameters_) { - [parameters_ release]; - parameters_ = [parameters copy]; - } -} - -//============================================================================= -- (NSDictionary *)parameters { - return parameters_; -} - -//============================================================================= -- (void)addFileAtPath:(NSString *)path name:(NSString *)name { - [files_ setObject:path forKey:name]; -} - -//============================================================================= -- (void)addFileContents:(NSData *)data name:(NSString *)name { - [files_ setObject:data forKey:name]; -} - -//============================================================================= -- (NSDictionary *)files { - return files_; -} - -//============================================================================= -- (NSData *)send:(NSError **)error { - NSMutableURLRequest *req = - [[NSMutableURLRequest alloc] - initWithURL:url_ cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:10.0 ]; - - NSMutableData *postBody = [NSMutableData data]; - - [req setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", - boundary_] forHTTPHeaderField:@"Content-type"]; - - // Add any parameters to the message - NSArray *parameterKeys = [parameters_ allKeys]; - NSString *key; - - NSInteger count = [parameterKeys count]; - for (NSInteger i = 0; i < count; ++i) { - key = [parameterKeys objectAtIndex:i]; - [postBody appendData:[self formDataForKey:key - value:[parameters_ objectForKey:key]]]; - } - - // Add any files to the message - NSArray *fileNames = [files_ allKeys]; - count = [fileNames count]; - for (NSInteger i = 0; i < count; ++i) { - NSString *name = [fileNames objectAtIndex:i]; - id fileOrData = [files_ objectForKey:name]; - NSData *fileData; - - // The object can be either the path to a file (NSString) or the contents - // of the file (NSData). - if ([fileOrData isKindOfClass:[NSData class]]) - fileData = [self formDataForFileContents:fileOrData name:name]; - else - fileData = [self formDataForFile:fileOrData name:name]; - - [postBody appendData:fileData]; - } - - NSString *epilogue = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary_]; - [postBody appendData:[epilogue dataUsingEncoding:NSUTF8StringEncoding]]; - - [req setHTTPBody:postBody]; - [req setHTTPMethod:@"POST"]; - - [response_ release]; - response_ = nil; - - NSData *data = nil; - if ([[req URL] isFileURL]) { - [[req HTTPBody] writeToURL:[req URL] options:0 error:error]; - } else { - NSURLResponse *response = nil; - data = SendSynchronousNSURLRequest(req, &response, error); - response_ = (NSHTTPURLResponse *)[response retain]; - } - [req release]; - - return data; -} - -//============================================================================= -- (NSHTTPURLResponse *)response { - return response_; -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.h b/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.h deleted file mode 100644 index 8df9165bb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.h +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// MachIPC.h -// -// Some helpful wrappers for using Mach IPC calls - -#ifndef MACH_IPC_H__ -#define MACH_IPC_H__ - -#import -#import -#import -#import - -#import - -//============================================================================== -// DISCUSSION: -// -// The three main classes of interest are -// -// MachMessage: a wrapper for a mach message of the following form -// mach_msg_header_t -// mach_msg_body_t -// optional descriptors -// optional extra message data -// -// MachReceiveMessage and MachSendMessage subclass MachMessage -// and are used instead of MachMessage which is an abstract base class -// -// ReceivePort: -// Represents a mach port for which we have receive rights -// -// MachPortSender: -// Represents a mach port for which we have send rights -// -// Here's an example to receive a message on a server port: -// -// // This creates our named server port -// ReceivePort receivePort("com.Google.MyService"); -// -// MachReceiveMessage message; -// kern_return_t result = receivePort.WaitForMessage(&message, 0); -// -// if (result == KERN_SUCCESS && message.GetMessageID() == 57) { -// mach_port_t task = message.GetTranslatedPort(0); -// mach_port_t thread = message.GetTranslatedPort(1); -// -// char *messageString = message.GetData(); -// -// printf("message string = %s\n", messageString); -// } -// -// Here is an example of using these classes to send a message to this port: -// -// // send to already named port -// MachPortSender sender("com.Google.MyService"); -// MachSendMessage message(57); // our message ID is 57 -// -// // add some ports to be translated for us -// message.AddDescriptor(mach_task_self()); // our task -// message.AddDescriptor(mach_thread_self()); // this thread -// -// char messageString[] = "Hello server!\n"; -// message.SetData(messageString, strlen(messageString)+1); -// -// kern_return_t result = sender.SendMessage(message, 1000); // timeout 1000ms -// - -namespace google_breakpad { -#define PRINT_MACH_RESULT(result_, message_) \ - printf(message_" %s (%d)\n", mach_error_string(result_), result_ ); - -//============================================================================== -// A wrapper class for mach_msg_port_descriptor_t (with same memory layout) -// with convenient constructors and accessors -class MachMsgPortDescriptor : public mach_msg_port_descriptor_t { - public: - // General-purpose constructor - MachMsgPortDescriptor(mach_port_t in_name, - mach_msg_type_name_t in_disposition) { - name = in_name; - pad1 = 0; - pad2 = 0; - disposition = in_disposition; - type = MACH_MSG_PORT_DESCRIPTOR; - } - - // For passing send rights to a port - MachMsgPortDescriptor(mach_port_t in_name) { - name = in_name; - pad1 = 0; - pad2 = 0; - disposition = MACH_MSG_TYPE_COPY_SEND; - type = MACH_MSG_PORT_DESCRIPTOR; - } - - // Copy constructor - MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) { - name = desc.name; - pad1 = desc.pad1; - pad2 = desc.pad2; - disposition = desc.disposition; - type = desc.type; - } - - mach_port_t GetMachPort() const { - return name; - } - - mach_msg_type_name_t GetDisposition() const { - return disposition; - } - - // For convenience - operator mach_port_t() const { - return GetMachPort(); - } -}; - -//============================================================================== -// MachMessage: a wrapper for a mach message -// (mach_msg_header_t, mach_msg_body_t, extra data) -// -// This considerably simplifies the construction of a message for sending -// and the getting at relevant data and descriptors for the receiver. -// -// Currently the combined size of the descriptors plus data must be -// less than 1024. But as a benefit no memory allocation is necessary. -// -// TODO: could consider adding malloc() support for very large messages -// -// A MachMessage object is used by ReceivePort::WaitForMessage -// and MachPortSender::SendMessage -// -class MachMessage { - public: - - // The receiver of the message can retrieve the raw data this way - uint8_t *GetData() { - return GetDataLength() > 0 ? GetDataPacket()->data : NULL; - } - - uint32_t GetDataLength() { - return EndianU32_LtoN(GetDataPacket()->data_length); - } - - // The message ID may be used as a code identifying the type of message - void SetMessageID(int32_t message_id) { - GetDataPacket()->id = EndianU32_NtoL(message_id); - } - - int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); } - - // Adds a descriptor (typically a mach port) to be translated - // returns true if successful, otherwise not enough space - bool AddDescriptor(const MachMsgPortDescriptor &desc); - - int GetDescriptorCount() const { return body.msgh_descriptor_count; } - MachMsgPortDescriptor *GetDescriptor(int n); - - // Convenience method which gets the mach port described by the descriptor - mach_port_t GetTranslatedPort(int n); - - // A simple message is one with no descriptors - bool IsSimpleMessage() const { return GetDescriptorCount() == 0; } - - // Sets raw data for the message (returns false if not enough space) - bool SetData(void *data, int32_t data_length); - - protected: - // Consider this an abstract base class - must create an actual instance - // of MachReceiveMessage or MachSendMessage - - MachMessage() { - memset(this, 0, sizeof(MachMessage)); - } - - friend class ReceivePort; - friend class MachPortSender; - - // Represents raw data in our message - struct MessageDataPacket { - int32_t id; // little-endian - int32_t data_length; // little-endian - uint8_t data[1]; // actual size limited by sizeof(MachMessage) - }; - - MessageDataPacket* GetDataPacket(); - - void SetDescriptorCount(int n); - void SetDescriptor(int n, const MachMsgPortDescriptor &desc); - - // Returns total message size setting msgh_size in the header to this value - mach_msg_size_t CalculateSize(); - - mach_msg_header_t head; - mach_msg_body_t body; - uint8_t padding[1024]; // descriptors and data may be embedded here -}; - -//============================================================================== -// MachReceiveMessage and MachSendMessage are useful to separate the idea -// of a mach message being sent and being received, and adds increased type -// safety: -// ReceivePort::WaitForMessage() only accepts a MachReceiveMessage -// MachPortSender::SendMessage() only accepts a MachSendMessage - -//============================================================================== -class MachReceiveMessage : public MachMessage { - public: - MachReceiveMessage() : MachMessage() {}; -}; - -//============================================================================== -class MachSendMessage : public MachMessage { - public: - MachSendMessage(int32_t message_id); -}; - -//============================================================================== -// Represents a mach port for which we have receive rights -class ReceivePort { - public: - // Creates a new mach port for receiving messages and registers a name for it - explicit ReceivePort(const char *receive_port_name); - - // Given an already existing mach port, use it. We take ownership of the - // port and deallocate it in our destructor. - explicit ReceivePort(mach_port_t receive_port); - - // Create a new mach port for receiving messages - ReceivePort(); - - ~ReceivePort(); - - // Waits on the mach port until message received or timeout - kern_return_t WaitForMessage(MachReceiveMessage *out_message, - mach_msg_timeout_t timeout); - - // The underlying mach port that we wrap - mach_port_t GetPort() const { return port_; } - - private: - ReceivePort(const ReceivePort&); // disable copy c-tor - - mach_port_t port_; - kern_return_t init_result_; -}; - -//============================================================================== -// Represents a mach port for which we have send rights -class MachPortSender { - public: - // get a port with send rights corresponding to a named registered service - explicit MachPortSender(const char *receive_port_name); - - - // Given an already existing mach port, use it. - explicit MachPortSender(mach_port_t send_port); - - kern_return_t SendMessage(MachSendMessage &message, - mach_msg_timeout_t timeout); - - private: - MachPortSender(const MachPortSender&); // disable copy c-tor - - mach_port_t send_port_; - kern_return_t init_result_; -}; - -} // namespace google_breakpad - -#endif // MACH_IPC_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.mm b/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.mm deleted file mode 100644 index dc9773f77..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/MachIPC.mm +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// MachIPC.mm -// Wrapper for mach IPC calls - -#import -#import "MachIPC.h" -#include "common/mac/bootstrap_compat.h" - -namespace google_breakpad { -//============================================================================== -MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() { - head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); - - // head.msgh_remote_port = ...; // filled out in MachPortSender::SendMessage() - head.msgh_local_port = MACH_PORT_NULL; - head.msgh_reserved = 0; - head.msgh_id = 0; - - SetDescriptorCount(0); // start out with no descriptors - - SetMessageID(message_id); - SetData(NULL, 0); // client may add data later -} - -//============================================================================== -// returns true if successful -bool MachMessage::SetData(void *data, - int32_t data_length) { - // first check to make sure we have enough space - size_t size = CalculateSize(); - size_t new_size = size + data_length; - - if (new_size > sizeof(MachMessage)) { - return false; // not enough space - } - - GetDataPacket()->data_length = EndianU32_NtoL(data_length); - if (data) memcpy(GetDataPacket()->data, data, data_length); - - CalculateSize(); - - return true; -} - -//============================================================================== -// calculates and returns the total size of the message -// Currently, the entire message MUST fit inside of the MachMessage -// messsage size <= sizeof(MachMessage) -mach_msg_size_t MachMessage::CalculateSize() { - size_t size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t); - - // add space for MessageDataPacket - int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3; - size += 2*sizeof(int32_t) + alignedDataLength; - - // add space for descriptors - size += GetDescriptorCount() * sizeof(MachMsgPortDescriptor); - - head.msgh_size = static_cast(size); - - return head.msgh_size; -} - -//============================================================================== -MachMessage::MessageDataPacket *MachMessage::GetDataPacket() { - size_t desc_size = sizeof(MachMsgPortDescriptor)*GetDescriptorCount(); - MessageDataPacket *packet = - reinterpret_cast(padding + desc_size); - - return packet; -} - -//============================================================================== -void MachMessage::SetDescriptor(int n, - const MachMsgPortDescriptor &desc) { - MachMsgPortDescriptor *desc_array = - reinterpret_cast(padding); - desc_array[n] = desc; -} - -//============================================================================== -// returns true if successful otherwise there was not enough space -bool MachMessage::AddDescriptor(const MachMsgPortDescriptor &desc) { - // first check to make sure we have enough space - int size = CalculateSize(); - size_t new_size = size + sizeof(MachMsgPortDescriptor); - - if (new_size > sizeof(MachMessage)) { - return false; // not enough space - } - - // unfortunately, we need to move the data to allow space for the - // new descriptor - u_int8_t *p = reinterpret_cast(GetDataPacket()); - bcopy(p, p+sizeof(MachMsgPortDescriptor), GetDataLength()+2*sizeof(int32_t)); - - SetDescriptor(GetDescriptorCount(), desc); - SetDescriptorCount(GetDescriptorCount() + 1); - - CalculateSize(); - - return true; -} - -//============================================================================== -void MachMessage::SetDescriptorCount(int n) { - body.msgh_descriptor_count = n; - - if (n > 0) { - head.msgh_bits |= MACH_MSGH_BITS_COMPLEX; - } else { - head.msgh_bits &= ~MACH_MSGH_BITS_COMPLEX; - } -} - -//============================================================================== -MachMsgPortDescriptor *MachMessage::GetDescriptor(int n) { - if (n < GetDescriptorCount()) { - MachMsgPortDescriptor *desc = - reinterpret_cast(padding); - return desc + n; - } - - return nil; -} - -//============================================================================== -mach_port_t MachMessage::GetTranslatedPort(int n) { - if (n < GetDescriptorCount()) { - return GetDescriptor(n)->GetMachPort(); - } - return MACH_PORT_NULL; -} - -#pragma mark - - -//============================================================================== -// create a new mach port for receiving messages and register a name for it -ReceivePort::ReceivePort(const char *receive_port_name) { - mach_port_t current_task = mach_task_self(); - - init_result_ = mach_port_allocate(current_task, - MACH_PORT_RIGHT_RECEIVE, - &port_); - - if (init_result_ != KERN_SUCCESS) - return; - - init_result_ = mach_port_insert_right(current_task, - port_, - port_, - MACH_MSG_TYPE_MAKE_SEND); - - if (init_result_ != KERN_SUCCESS) - return; - - mach_port_t task_bootstrap_port = 0; - init_result_ = task_get_bootstrap_port(current_task, &task_bootstrap_port); - - if (init_result_ != KERN_SUCCESS) - return; - - init_result_ = breakpad::BootstrapRegister( - bootstrap_port, - const_cast(receive_port_name), - port_); -} - -//============================================================================== -// create a new mach port for receiving messages -ReceivePort::ReceivePort() { - mach_port_t current_task = mach_task_self(); - - init_result_ = mach_port_allocate(current_task, - MACH_PORT_RIGHT_RECEIVE, - &port_); - - if (init_result_ != KERN_SUCCESS) - return; - - init_result_ = mach_port_insert_right(current_task, - port_, - port_, - MACH_MSG_TYPE_MAKE_SEND); -} - -//============================================================================== -// Given an already existing mach port, use it. We take ownership of the -// port and deallocate it in our destructor. -ReceivePort::ReceivePort(mach_port_t receive_port) - : port_(receive_port), - init_result_(KERN_SUCCESS) { -} - -//============================================================================== -ReceivePort::~ReceivePort() { - if (init_result_ == KERN_SUCCESS) - mach_port_deallocate(mach_task_self(), port_); -} - -//============================================================================== -kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message, - mach_msg_timeout_t timeout) { - if (!out_message) { - return KERN_INVALID_ARGUMENT; - } - - // return any error condition encountered in constructor - if (init_result_ != KERN_SUCCESS) - return init_result_; - - out_message->head.msgh_bits = 0; - out_message->head.msgh_local_port = port_; - out_message->head.msgh_remote_port = MACH_PORT_NULL; - out_message->head.msgh_reserved = 0; - out_message->head.msgh_id = 0; - - mach_msg_option_t options = MACH_RCV_MSG; - if (timeout != MACH_MSG_TIMEOUT_NONE) - options |= MACH_RCV_TIMEOUT; - kern_return_t result = mach_msg(&out_message->head, - options, - 0, - sizeof(MachMessage), - port_, - timeout, // timeout in ms - MACH_PORT_NULL); - - return result; -} - -#pragma mark - - -//============================================================================== -// get a port with send rights corresponding to a named registered service -MachPortSender::MachPortSender(const char *receive_port_name) { - mach_port_t task_bootstrap_port = 0; - init_result_ = task_get_bootstrap_port(mach_task_self(), - &task_bootstrap_port); - - if (init_result_ != KERN_SUCCESS) - return; - - init_result_ = bootstrap_look_up(task_bootstrap_port, - const_cast(receive_port_name), - &send_port_); -} - -//============================================================================== -MachPortSender::MachPortSender(mach_port_t send_port) - : send_port_(send_port), - init_result_(KERN_SUCCESS) { -} - -//============================================================================== -kern_return_t MachPortSender::SendMessage(MachSendMessage &message, - mach_msg_timeout_t timeout) { - if (message.head.msgh_size == 0) { - return KERN_INVALID_VALUE; // just for safety -- never should occur - }; - - if (init_result_ != KERN_SUCCESS) - return init_result_; - - message.head.msgh_remote_port = send_port_; - - kern_return_t result = mach_msg(&message.head, - MACH_SEND_MSG | MACH_SEND_TIMEOUT, - message.head.msgh_size, - 0, - MACH_PORT_NULL, - timeout, // timeout in ms - MACH_PORT_NULL); - - return result; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc deleted file mode 100644 index 4e5f5534a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.cc +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/mac/arch_utilities.h" - -#include -#include -#include -#include - -#ifndef CPU_SUBTYPE_ARM_V7S -#define CPU_SUBTYPE_ARM_V7S (static_cast(11)) -#endif // CPU_SUBTYPE_ARM_V7S - -#ifndef CPU_TYPE_ARM64 -#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) -#endif // CPU_TYPE_ARM64 - -#ifndef CPU_SUBTYPE_ARM64_ALL -#define CPU_SUBTYPE_ARM64_ALL (static_cast(0)) -#endif // CPU_SUBTYPE_ARM64_ALL - -namespace { - -const NXArchInfo* ArchInfo_arm64() { - NXArchInfo* arm64 = new NXArchInfo; - *arm64 = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM, - CPU_SUBTYPE_ARM_V7); - arm64->name = "arm64"; - arm64->cputype = CPU_TYPE_ARM64; - arm64->cpusubtype = CPU_SUBTYPE_ARM64_ALL; - arm64->description = "arm 64"; - return arm64; -} - -const NXArchInfo* ArchInfo_armv7s() { - NXArchInfo* armv7s = new NXArchInfo; - *armv7s = *NXGetArchInfoFromCpuType(CPU_TYPE_ARM, - CPU_SUBTYPE_ARM_V7); - armv7s->name = "armv7s"; - armv7s->cpusubtype = CPU_SUBTYPE_ARM_V7S; - armv7s->description = "arm v7s"; - return armv7s; -} - -} // namespace - -namespace google_breakpad { - -const NXArchInfo* BreakpadGetArchInfoFromName(const char* arch_name) { - // TODO: Remove this when the OS knows about arm64. - if (!strcmp("arm64", arch_name)) - return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM64, - CPU_SUBTYPE_ARM64_ALL); - - // TODO: Remove this when the OS knows about armv7s. - if (!strcmp("armv7s", arch_name)) - return BreakpadGetArchInfoFromCpuType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S); - - return NXGetArchInfoFromName(arch_name); -} - -const NXArchInfo* BreakpadGetArchInfoFromCpuType(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype) { - // TODO: Remove this when the OS knows about arm64. - if (cpu_type == CPU_TYPE_ARM64 && cpu_subtype == CPU_SUBTYPE_ARM64_ALL) { - static const NXArchInfo* arm64 = ArchInfo_arm64(); - return arm64; - } - - // TODO: Remove this when the OS knows about armv7s. - if (cpu_type == CPU_TYPE_ARM && cpu_subtype == CPU_SUBTYPE_ARM_V7S) { - static const NXArchInfo* armv7s = ArchInfo_armv7s(); - return armv7s; - } - - return NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); -} - -} // namespace google_breakpad - -#ifndef __APPLE__ -namespace { - -enum Architecture { - kArch_i386 = 0, - kArch_x86_64, - kArch_arm, - kArch_arm64, - kArch_ppc, - // This must be last. - kNumArchitectures -}; - -// enum Architecture above and kKnownArchitectures below -// must be kept in sync. -const NXArchInfo kKnownArchitectures[] = { - { - "i386", - CPU_TYPE_I386, - CPU_SUBTYPE_I386_ALL, - NX_LittleEndian, - "Intel 80x86" - }, - { - "x86_64", - CPU_TYPE_X86_64, - CPU_SUBTYPE_X86_64_ALL, - NX_LittleEndian, - "Intel x86-64" - }, - { - "arm", - CPU_TYPE_ARM, - CPU_SUBTYPE_ARM_ALL, - NX_LittleEndian, - "ARM" - }, - { - "arm64", - CPU_TYPE_ARM64, - CPU_SUBTYPE_ARM64_ALL, - NX_LittleEndian, - "ARM64" - }, - { - "ppc", - CPU_TYPE_POWERPC, - CPU_SUBTYPE_POWERPC_ALL, - NX_BigEndian, - "PowerPC" - } -}; - -} // namespace - -const NXArchInfo *NXGetLocalArchInfo(void) { - Architecture arch; -#if defined(__i386__) - arch = kArch_i386; -#elif defined(__x86_64__) - arch = kArch_x86_64; -#elif defined(__arm64) - arch = kArch_arm64; -#elif defined(__arm__) - arch = kArch_arm; -#elif defined(__powerpc__) - arch = kArch_ppc; -#else - #error "Unsupported CPU architecture" -#endif - return &kKnownArchitectures[arch]; -} - -const NXArchInfo *NXGetArchInfoFromName(const char *name) { - for (int arch = 0; arch < kNumArchitectures; ++arch) { - if (!strcmp(name, kKnownArchitectures[arch].name)) { - return &kKnownArchitectures[arch]; - } - } - return NULL; -} - -const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype, - cpu_subtype_t cpusubtype) { - for (int arch = 0; arch < kNumArchitectures; ++arch) { - if (kKnownArchitectures[arch].cputype == cputype) { - return &kKnownArchitectures[arch]; - } - } - return NULL; -} - -struct fat_arch *NXFindBestFatArch(cpu_type_t cputype, - cpu_subtype_t cpusubtype, - struct fat_arch *fat_archs, - uint32_t nfat_archs) { - for (uint32_t f = 0; f < nfat_archs; ++f) { - if (fat_archs[f].cputype == cputype) { - return &fat_archs[f]; - } - } - return NULL; -} -#endif // !__APPLE__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.h b/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.h deleted file mode 100644 index 397c1f587..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/arch_utilities.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// arch_utilities.h: Utilities for architecture introspection for Mac platform. - -#ifndef COMMON_MAC_ARCH_UTILITIES_H__ -#define COMMON_MAC_ARCH_UTILITIES_H__ - -#include - -namespace google_breakpad { - -// Custom implementation of |NXGetArchInfoFromName| and -// |NXGetArchInfoFromCpuType| that handle newer CPU on older OSes. -const NXArchInfo* BreakpadGetArchInfoFromName(const char* arch_name); -const NXArchInfo* BreakpadGetArchInfoFromCpuType(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype); - -} // namespace google_breakpad - -#endif // COMMON_MAC_ARCH_UTILITIES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.cc deleted file mode 100644 index d875d95b5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/mac/bootstrap_compat.h" - -namespace breakpad { - -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -kern_return_t BootstrapRegister(mach_port_t bp, - name_t service_name, - mach_port_t sp) { - return bootstrap_register(bp, service_name, sp); -} -#pragma GCC diagnostic warning "-Wdeprecated-declarations" - -} // namesapce breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.h b/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.h deleted file mode 100644 index 8ca7357c3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/bootstrap_compat.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_MAC_BOOTSTRAP_COMPAT_H_ -#define COMMON_MAC_BOOTSTRAP_COMPAT_H_ - -#include - -namespace breakpad { - -// Wrapper for bootstrap_register to avoid deprecation warnings. -// -// In 10.6, it's possible to call bootstrap_check_in as the one-stop-shop for -// handling what bootstrap_register is used for. In 10.5, bootstrap_check_in -// can't check in a service whose name has not yet been registered, despite -// bootstrap_register being marked as deprecated in that OS release. Breakpad -// needs to register new service names, and in 10.5, calling -// bootstrap_register is the only way to achieve that. Attempts to call -// bootstrap_check_in for a new service name on 10.5 will result in -// BOOTSTRAP_UNKNOWN_SERVICE being returned rather than registration of the -// new service name. -kern_return_t BootstrapRegister(mach_port_t bp, - name_t service_name, - mach_port_t sp); - -} // namespace breakpad - -#endif // COMMON_MAC_BOOTSTRAP_COMPAT_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/byteswap.h b/toolkit/crashreporter/google-breakpad/src/common/mac/byteswap.h deleted file mode 100644 index b7bbc0b95..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/byteswap.h +++ /dev/null @@ -1,73 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// byteswap.h: Overloaded functions for conveniently byteswapping values. - -#ifndef COMMON_MAC_BYTESWAP_H_ -#define COMMON_MAC_BYTESWAP_H_ - -#ifdef __APPLE__ -#include - -static inline uint16_t ByteSwap(uint16_t v) { return OSSwapInt16(v); } -static inline uint32_t ByteSwap(uint32_t v) { return OSSwapInt32(v); } -static inline uint64_t ByteSwap(uint64_t v) { return OSSwapInt64(v); } -static inline int16_t ByteSwap(int16_t v) { return OSSwapInt16(v); } -static inline int32_t ByteSwap(int32_t v) { return OSSwapInt32(v); } -static inline int64_t ByteSwap(int64_t v) { return OSSwapInt64(v); } - -#elif defined(__linux__) -// For NXByteOrder -#include -#include -#include -#include_next - -static inline uint16_t ByteSwap(uint16_t v) { return bswap_16(v); } -static inline uint32_t ByteSwap(uint32_t v) { return bswap_32(v); } -static inline uint64_t ByteSwap(uint64_t v) { return bswap_64(v); } -static inline int16_t ByteSwap(int16_t v) { return bswap_16(v); } -static inline int32_t ByteSwap(int32_t v) { return bswap_32(v); } -static inline int64_t ByteSwap(int64_t v) { return bswap_64(v); } - -static inline NXByteOrder NXHostByteOrder() { -#ifdef __LITTLE_ENDIAN - return NX_LittleEndian; -#else - return NX_BigEndian; -#endif -} - -#endif // __APPLE__ - -#endif // COMMON_MAC_BYTESWAP_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.cc deleted file mode 100644 index b20a05586..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.cc +++ /dev/null @@ -1,646 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Jim Blandy - -// dump_syms.mm: Create a symbol file for use with minidumps - -#include "common/mac/dump_syms.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/dwarf/bytereader-inl.h" -#include "common/dwarf/dwarf2reader.h" -#include "common/dwarf_cfi_to_module.h" -#include "common/dwarf_cu_to_module.h" -#include "common/dwarf_line_to_module.h" -#include "common/mac/file_id.h" -#include "common/mac/arch_utilities.h" -#include "common/mac/macho_reader.h" -#include "common/module.h" -#include "common/scoped_ptr.h" -#include "common/stabs_reader.h" -#include "common/stabs_to_module.h" -#include "common/symbol_data.h" - -#ifndef CPU_TYPE_ARM -#define CPU_TYPE_ARM (static_cast(12)) -#endif // CPU_TYPE_ARM - -#ifndef CPU_TYPE_ARM64 -#define CPU_TYPE_ARM64 (static_cast(16777228)) -#endif // CPU_TYPE_ARM64 - -using dwarf2reader::ByteReader; -using google_breakpad::DwarfCUToModule; -using google_breakpad::DwarfLineToModule; -using google_breakpad::FileID; -using google_breakpad::mach_o::FatReader; -using google_breakpad::mach_o::Section; -using google_breakpad::mach_o::Segment; -using google_breakpad::Module; -using google_breakpad::StabsReader; -using google_breakpad::StabsToModule; -using google_breakpad::scoped_ptr; -using std::make_pair; -using std::pair; -using std::string; -using std::vector; - -namespace { -// Return a vector with absolute paths to all the entries -// in directory (excluding . and ..). -vector list_directory(const string& directory) { - vector entries; - DIR* dir = opendir(directory.c_str()); - if (!dir) { - return entries; - } - - string path = directory; - if (path[path.length() - 1] != '/') { - path += '/'; - } - - struct dirent* entry = NULL; - while ((entry = readdir(dir))) { - if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { - entries.push_back(path + entry->d_name); - } - } - - closedir(dir); - return entries; -} -} - -namespace google_breakpad { - -bool DumpSymbols::Read(const string &filename) { - struct stat st; - if (stat(filename.c_str(), &st) == -1) { - fprintf(stderr, "Could not access object file %s: %s\n", - filename.c_str(), strerror(errno)); - return false; - } - - input_pathname_ = filename; - - // Does this filename refer to a dSYM bundle? - string contents_path = input_pathname_ + "/Contents/Resources/DWARF"; - if (S_ISDIR(st.st_mode) && - access(contents_path.c_str(), F_OK) == 0) { - // If there's one file under Contents/Resources/DWARF then use that, - // otherwise bail out. - const vector entries = list_directory(contents_path); - if (entries.size() == 0) { - fprintf(stderr, "Unable to find DWARF-bearing file in bundle: %s\n", - input_pathname_.c_str()); - return false; - } - if (entries.size() > 1) { - fprintf(stderr, "Too many DWARF files in bundle: %s\n", - input_pathname_.c_str()); - return false; - } - - object_filename_ = entries[0]; - } else { - object_filename_ = input_pathname_; - } - - // Read the file's contents into memory. - bool read_ok = true; - string error; - if (stat(object_filename_.c_str(), &st) != -1) { - FILE* f = fopen(object_filename_.c_str(), "rb"); - if (f) { - contents_.reset(new uint8_t[st.st_size]); - off_t total = 0; - while (total < st.st_size && !feof(f)) { - size_t read = fread(&contents_[0] + total, 1, st.st_size - total, f); - if (read == 0) { - if (ferror(f)) { - read_ok = false; - error = strerror(errno); - } - break; - } - total += read; - } - fclose(f); - } else { - error = strerror(errno); - } - } - - if (!read_ok) { - fprintf(stderr, "Error reading object file: %s: %s\n", - object_filename_.c_str(), - error.c_str()); - return false; - } - - // Get the list of object files present in the file. - FatReader::Reporter fat_reporter(object_filename_); - FatReader fat_reader(&fat_reporter); - if (!fat_reader.Read(&contents_[0], - st.st_size)) { - return false; - } - - // Get our own copy of fat_reader's object file list. - size_t object_files_count; - const SuperFatArch *object_files = - fat_reader.object_files(&object_files_count); - if (object_files_count == 0) { - fprintf(stderr, "Fat binary file contains *no* architectures: %s\n", - object_filename_.c_str()); - return false; - } - object_files_.resize(object_files_count); - memcpy(&object_files_[0], object_files, - sizeof(SuperFatArch) * object_files_count); - - return true; -} - -bool DumpSymbols::SetArchitecture(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype) { - // Find the best match for the architecture the user requested. - const SuperFatArch *best_match = FindBestMatchForArchitecture( - cpu_type, cpu_subtype); - if (!best_match) return false; - - // Record the selected object file. - selected_object_file_ = best_match; - return true; -} - -bool DumpSymbols::SetArchitecture(const std::string &arch_name) { - bool arch_set = false; - const NXArchInfo *arch_info = - google_breakpad::BreakpadGetArchInfoFromName(arch_name.c_str()); - if (arch_info) { - arch_set = SetArchitecture(arch_info->cputype, arch_info->cpusubtype); - } - return arch_set; -} - -SuperFatArch* DumpSymbols::FindBestMatchForArchitecture( - cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { - // Check if all the object files can be converted to struct fat_arch. - bool can_convert_to_fat_arch = true; - vector fat_arch_vector; - for (vector::const_iterator it = object_files_.begin(); - it != object_files_.end(); - ++it) { - struct fat_arch arch; - bool success = it->ConvertToFatArch(&arch); - if (!success) { - can_convert_to_fat_arch = false; - break; - } - fat_arch_vector.push_back(arch); - } - - // If all the object files can be converted to struct fat_arch, use - // NXFindBestFatArch. - if (can_convert_to_fat_arch) { - const struct fat_arch *best_match - = NXFindBestFatArch(cpu_type, cpu_subtype, &fat_arch_vector[0], - static_cast(fat_arch_vector.size())); - - for (size_t i = 0; i < fat_arch_vector.size(); ++i) { - if (best_match == &fat_arch_vector[i]) - return &object_files_[i]; - } - assert(best_match == NULL); - return NULL; - } - - // Check for an exact match with cpu_type and cpu_subtype. - for (vector::iterator it = object_files_.begin(); - it != object_files_.end(); - ++it) { - if (static_cast(it->cputype) == cpu_type && - static_cast(it->cpusubtype) == cpu_subtype) - return &*it; - } - - // No exact match found. - // TODO(erikchen): If it becomes necessary, we can copy the implementation of - // NXFindBestFatArch, located at - // http://web.mit.edu/darwin/src/modules/cctools/libmacho/arch.c. - fprintf(stderr, "Failed to find an exact match for an object file with cpu " - "type: %d and cpu subtype: %d. Furthermore, at least one object file is " - "larger than 2**32.\n", cpu_type, cpu_subtype); - return NULL; -} - -string DumpSymbols::Identifier() { - FileID file_id(object_filename_.c_str()); - unsigned char identifier_bytes[16]; - cpu_type_t cpu_type = selected_object_file_->cputype; - cpu_subtype_t cpu_subtype = selected_object_file_->cpusubtype; - if (!file_id.MachoIdentifier(cpu_type, cpu_subtype, identifier_bytes)) { - fprintf(stderr, "Unable to calculate UUID of mach-o binary %s!\n", - object_filename_.c_str()); - return ""; - } - - char identifier_string[40]; - FileID::ConvertIdentifierToString(identifier_bytes, identifier_string, - sizeof(identifier_string)); - - string compacted(identifier_string); - for(size_t i = compacted.find('-'); i != string::npos; - i = compacted.find('-', i)) - compacted.erase(i, 1); - - return compacted; -} - -// A line-to-module loader that accepts line number info parsed by -// dwarf2reader::LineInfo and populates a Module and a line vector -// with the results. -class DumpSymbols::DumperLineToModule: - public DwarfCUToModule::LineToModuleHandler { - public: - // Create a line-to-module converter using BYTE_READER. - DumperLineToModule(dwarf2reader::ByteReader *byte_reader) - : byte_reader_(byte_reader) { } - - void StartCompilationUnit(const string& compilation_dir) { - compilation_dir_ = compilation_dir; - } - - void ReadProgram(const uint8_t *program, uint64 length, - Module *module, vector *lines) { - DwarfLineToModule handler(module, compilation_dir_, lines); - dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); - parser.Start(); - } - private: - string compilation_dir_; - dwarf2reader::ByteReader *byte_reader_; // WEAK -}; - -bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { - // Select an object file, if SetArchitecture hasn't been called to set one - // explicitly. - if (!selected_object_file_) { - // If there's only one architecture, that's the one. - if (object_files_.size() == 1) - selected_object_file_ = &object_files_[0]; - else { - // Look for an object file whose architecture matches our own. - const NXArchInfo *local_arch = NXGetLocalArchInfo(); - if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) { - fprintf(stderr, "%s: object file contains more than one" - " architecture, none of which match the current" - " architecture; specify an architecture explicitly" - " with '-a ARCH' to resolve the ambiguity\n", - object_filename_.c_str()); - return false; - } - } - } - - assert(selected_object_file_); - - // Find the name of the selected file's architecture, to appear in - // the MODULE record and in error messages. - const NXArchInfo *selected_arch_info = - google_breakpad::BreakpadGetArchInfoFromCpuType( - selected_object_file_->cputype, selected_object_file_->cpusubtype); - - const char *selected_arch_name = selected_arch_info->name; - if (strcmp(selected_arch_name, "i386") == 0) - selected_arch_name = "x86"; - - // Produce a name to use in error messages that includes the - // filename, and the architecture, if there is more than one. - selected_object_name_ = object_filename_; - if (object_files_.size() > 1) { - selected_object_name_ += ", architecture "; - selected_object_name_ + selected_arch_name; - } - - // Compute a module name, to appear in the MODULE record. - string module_name = object_filename_; - module_name = basename(&module_name[0]); - - // Choose an identifier string, to appear in the MODULE record. - string identifier = Identifier(); - if (identifier.empty()) - return false; - identifier += "0"; - - // Create a module to hold the debugging information. - module.reset(new Module(module_name, - "mac", - selected_arch_name, - identifier)); - return true; -} - -bool DumpSymbols::ReadDwarf(google_breakpad::Module *module, - const mach_o::Reader &macho_reader, - const mach_o::SectionMap &dwarf_sections, - bool handle_inter_cu_refs) const { - // Build a byte reader of the appropriate endianness. - ByteReader byte_reader(macho_reader.big_endian() - ? dwarf2reader::ENDIANNESS_BIG - : dwarf2reader::ENDIANNESS_LITTLE); - - // Construct a context for this file. - DwarfCUToModule::FileContext file_context(selected_object_name_, - module, - handle_inter_cu_refs); - - // Build a dwarf2reader::SectionMap from our mach_o::SectionMap. - for (mach_o::SectionMap::const_iterator it = dwarf_sections.begin(); - it != dwarf_sections.end(); ++it) { - file_context.AddSectionToSectionMap( - it->first, - it->second.contents.start, - it->second.contents.Size()); - } - - // Find the __debug_info section. - dwarf2reader::SectionMap::const_iterator debug_info_entry = - file_context.section_map().find("__debug_info"); - assert(debug_info_entry != file_context.section_map().end()); - const std::pair& debug_info_section = - debug_info_entry->second; - // There had better be a __debug_info section! - if (!debug_info_section.first) { - fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n", - selected_object_name_.c_str()); - return false; - } - - // Build a line-to-module loader for the root handler to use. - DumperLineToModule line_to_module(&byte_reader); - - // Walk the __debug_info section, one compilation unit at a time. - uint64 debug_info_length = debug_info_section.second; - for (uint64 offset = 0; offset < debug_info_length;) { - // Make a handler for the root DIE that populates MODULE with the - // debug info. - DwarfCUToModule::WarningReporter reporter(selected_object_name_, - offset); - DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter); - // Make a Dwarf2Handler that drives our DIEHandler. - dwarf2reader::DIEDispatcher die_dispatcher(&root_handler); - // Make a DWARF parser for the compilation unit at OFFSET. - dwarf2reader::CompilationUnit dwarf_reader(selected_object_name_, - file_context.section_map(), - offset, - &byte_reader, - &die_dispatcher); - // Process the entire compilation unit; get the offset of the next. - offset += dwarf_reader.Start(); - } - - return true; -} - -bool DumpSymbols::ReadCFI(google_breakpad::Module *module, - const mach_o::Reader &macho_reader, - const mach_o::Section §ion, - bool eh_frame) const { - // Find the appropriate set of register names for this file's - // architecture. - vector register_names; - switch (macho_reader.cpu_type()) { - case CPU_TYPE_X86: - register_names = DwarfCFIToModule::RegisterNames::I386(); - break; - case CPU_TYPE_X86_64: - register_names = DwarfCFIToModule::RegisterNames::X86_64(); - break; - case CPU_TYPE_ARM: - register_names = DwarfCFIToModule::RegisterNames::ARM(); - break; - case CPU_TYPE_ARM64: - register_names = DwarfCFIToModule::RegisterNames::ARM64(); - break; - default: { - const NXArchInfo *arch = google_breakpad::BreakpadGetArchInfoFromCpuType( - macho_reader.cpu_type(), macho_reader.cpu_subtype()); - fprintf(stderr, "%s: cannot convert DWARF call frame information for ", - selected_object_name_.c_str()); - if (arch) - fprintf(stderr, "architecture '%s'", arch->name); - else - fprintf(stderr, "architecture %d,%d", - macho_reader.cpu_type(), macho_reader.cpu_subtype()); - fprintf(stderr, " to Breakpad symbol file: no register name table\n"); - return false; - } - } - - // Find the call frame information and its size. - const uint8_t *cfi = section.contents.start; - size_t cfi_size = section.contents.Size(); - - // Plug together the parser, handler, and their entourages. - DwarfCFIToModule::Reporter module_reporter(selected_object_name_, - section.section_name); - DwarfCFIToModule handler(module, register_names, &module_reporter); - dwarf2reader::ByteReader byte_reader(macho_reader.big_endian() ? - dwarf2reader::ENDIANNESS_BIG : - dwarf2reader::ENDIANNESS_LITTLE); - byte_reader.SetAddressSize(macho_reader.bits_64() ? 8 : 4); - // At the moment, according to folks at Apple and some cursory - // investigation, Mac OS X only uses DW_EH_PE_pcrel-based pointers, so - // this is the only base address the CFI parser will need. - byte_reader.SetCFIDataBase(section.address, cfi); - - dwarf2reader::CallFrameInfo::Reporter dwarf_reporter(selected_object_name_, - section.section_name); - dwarf2reader::CallFrameInfo parser(cfi, cfi_size, - &byte_reader, &handler, &dwarf_reporter, - eh_frame); - parser.Start(); - return true; -} - -// A LoadCommandHandler that loads whatever debugging data it finds into a -// Module. -class DumpSymbols::LoadCommandDumper: - public mach_o::Reader::LoadCommandHandler { - public: - // Create a load command dumper handling load commands from READER's - // file, and adding data to MODULE. - LoadCommandDumper(const DumpSymbols &dumper, - google_breakpad::Module *module, - const mach_o::Reader &reader, - SymbolData symbol_data, - bool handle_inter_cu_refs) - : dumper_(dumper), - module_(module), - reader_(reader), - symbol_data_(symbol_data), - handle_inter_cu_refs_(handle_inter_cu_refs) { } - - bool SegmentCommand(const mach_o::Segment &segment); - bool SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings); - - private: - const DumpSymbols &dumper_; - google_breakpad::Module *module_; // WEAK - const mach_o::Reader &reader_; - const SymbolData symbol_data_; - const bool handle_inter_cu_refs_; -}; - -bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) { - mach_o::SectionMap section_map; - if (!reader_.MapSegmentSections(segment, §ion_map)) - return false; - - if (segment.name == "__TEXT") { - module_->SetLoadAddress(segment.vmaddr); - if (symbol_data_ != NO_CFI) { - mach_o::SectionMap::const_iterator eh_frame = - section_map.find("__eh_frame"); - if (eh_frame != section_map.end()) { - // If there is a problem reading this, don't treat it as a fatal error. - dumper_.ReadCFI(module_, reader_, eh_frame->second, true); - } - } - return true; - } - - if (segment.name == "__DWARF") { - if (symbol_data_ != ONLY_CFI) { - if (!dumper_.ReadDwarf(module_, reader_, section_map, - handle_inter_cu_refs_)) { - return false; - } - } - if (symbol_data_ != NO_CFI) { - mach_o::SectionMap::const_iterator debug_frame - = section_map.find("__debug_frame"); - if (debug_frame != section_map.end()) { - // If there is a problem reading this, don't treat it as a fatal error. - dumper_.ReadCFI(module_, reader_, debug_frame->second, false); - } - } - } - - return true; -} - -bool DumpSymbols::LoadCommandDumper::SymtabCommand(const ByteBuffer &entries, - const ByteBuffer &strings) { - StabsToModule stabs_to_module(module_); - // Mac OS X STABS are never "unitized", and the size of the 'value' field - // matches the address size of the executable. - StabsReader stabs_reader(entries.start, entries.Size(), - strings.start, strings.Size(), - reader_.big_endian(), - reader_.bits_64() ? 8 : 4, - true, - &stabs_to_module); - if (!stabs_reader.Process()) - return false; - stabs_to_module.Finalize(); - return true; -} - -bool DumpSymbols::ReadSymbolData(Module** out_module) { - scoped_ptr module; - if (!CreateEmptyModule(module)) - return false; - - // Parse the selected object file. - mach_o::Reader::Reporter reporter(selected_object_name_); - mach_o::Reader reader(&reporter); - if (!reader.Read(&contents_[0] - + selected_object_file_->offset, - selected_object_file_->size, - selected_object_file_->cputype, - selected_object_file_->cpusubtype)) - return false; - - // Walk its load commands, and deal with whatever is there. - LoadCommandDumper load_command_dumper(*this, module.get(), reader, - symbol_data_, handle_inter_cu_refs_); - if (!reader.WalkLoadCommands(&load_command_dumper)) - return false; - - *out_module = module.release(); - - return true; -} - -bool DumpSymbols::WriteSymbolFile(std::ostream &stream) { - Module* module = NULL; - - if (ReadSymbolData(&module) && module) { - bool res = module->Write(stream, symbol_data_); - delete module; - return res; - } - - return false; -} - -// Read the selected object file's debugging information, and write out the -// header only to |stream|. Return true on success; if an error occurs, report -// it and return false. -bool DumpSymbols::WriteSymbolFileHeader(std::ostream &stream) { - scoped_ptr module; - if (!CreateEmptyModule(module)) - return false; - - return module->Write(stream, symbol_data_); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.h b/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.h deleted file mode 100644 index 9463f7dc0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.h +++ /dev/null @@ -1,196 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Jim Blandy - -// dump_syms.h: Declaration of google_breakpad::DumpSymbols, a class for -// reading debugging information from Mach-O files and writing it out as a -// Breakpad symbol file. - -#include -#include -#include - -#include -#include -#include - -#include "common/byte_cursor.h" -#include "common/mac/macho_reader.h" -#include "common/mac/super_fat_arch.h" -#include "common/module.h" -#include "common/scoped_ptr.h" -#include "common/symbol_data.h" - -namespace google_breakpad { - -class DumpSymbols { - public: - DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs) - : symbol_data_(symbol_data), - handle_inter_cu_refs_(handle_inter_cu_refs), - input_pathname_(), - object_filename_(), - contents_(), - object_files_(), - selected_object_file_(), - selected_object_name_() { } - ~DumpSymbols() { - } - - // Prepare to read debugging information from |filename|. |filename| may be - // the name of a universal binary, a Mach-O file, or a dSYM bundle - // containing either of the above. On success, return true; if there is a - // problem reading |filename|, report it and return false. - bool Read(const std::string &filename); - - // If this dumper's file includes an object file for |cpu_type| and - // |cpu_subtype|, then select that object file for dumping, and return - // true. Otherwise, return false, and leave this dumper's selected - // architecture unchanged. - // - // By default, if this dumper's file contains only one object file, then - // the dumper will dump those symbols; and if it contains more than one - // object file, then the dumper will dump the object file whose - // architecture matches that of this dumper program. - bool SetArchitecture(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype); - - // If this dumper's file includes an object file for |arch_name|, then select - // that object file for dumping, and return true. Otherwise, return false, - // and leave this dumper's selected architecture unchanged. - // - // By default, if this dumper's file contains only one object file, then - // the dumper will dump those symbols; and if it contains more than one - // object file, then the dumper will dump the object file whose - // architecture matches that of this dumper program. - bool SetArchitecture(const std::string &arch_name); - - // Return a pointer to an array of SuperFatArch structures describing the - // object files contained in this dumper's file. Set *|count| to the number - // of elements in the array. The returned array is owned by this DumpSymbols - // instance. - // - // If there are no available architectures, this function - // may return NULL. - const SuperFatArch* AvailableArchitectures(size_t *count) { - *count = object_files_.size(); - if (object_files_.size() > 0) - return &object_files_[0]; - return NULL; - } - - // Read the selected object file's debugging information, and write it out to - // |stream|. Return true on success; if an error occurs, report it and - // return false. - bool WriteSymbolFile(std::ostream &stream); - - // Read the selected object file's debugging information, and write out the - // header only to |stream|. Return true on success; if an error occurs, report - // it and return false. - bool WriteSymbolFileHeader(std::ostream &stream); - - // As above, but simply return the debugging information in module - // instead of writing it to a stream. The caller owns the resulting - // module object and must delete it when finished. - bool ReadSymbolData(Module** module); - - private: - // Used internally. - class DumperLineToModule; - class LoadCommandDumper; - - // This method behaves similarly to NXFindBestFatArch, but it supports - // SuperFatArch. - SuperFatArch* FindBestMatchForArchitecture( - cpu_type_t cpu_type, cpu_subtype_t cpu_subtype); - - // Return an identifier string for the file this DumpSymbols is dumping. - std::string Identifier(); - - - // Creates an empty module object. - bool CreateEmptyModule(scoped_ptr& module); - - // Read debugging information from |dwarf_sections|, which was taken from - // |macho_reader|, and add it to |module|. On success, return true; - // on failure, report the problem and return false. - bool ReadDwarf(google_breakpad::Module *module, - const mach_o::Reader &macho_reader, - const mach_o::SectionMap &dwarf_sections, - bool handle_inter_cu_refs) const; - - // Read DWARF CFI or .eh_frame data from |section|, belonging to - // |macho_reader|, and record it in |module|. If |eh_frame| is true, - // then the data is .eh_frame-format data; otherwise, it is standard DWARF - // .debug_frame data. On success, return true; on failure, report - // the problem and return false. - bool ReadCFI(google_breakpad::Module *module, - const mach_o::Reader &macho_reader, - const mach_o::Section §ion, - bool eh_frame) const; - - // The selection of what type of symbol data to read/write. - const SymbolData symbol_data_; - - // Whether to handle references between compilation units. - const bool handle_inter_cu_refs_; - - // The name of the file or bundle whose symbols this will dump. - // This is the path given to Read, for use in error messages. - std::string input_pathname_; - - // The name of the file this DumpSymbols will actually read debugging - // information from. Normally, this is the same as input_pathname_, but if - // filename refers to a dSYM bundle, then this is the resource file - // within that bundle. - std::string object_filename_; - - // The complete contents of object_filename_, mapped into memory. - scoped_array contents_; - - // A vector of SuperFatArch structures describing the object files - // object_filename_ contains. If object_filename_ refers to a fat binary, - // this may have more than one element; if it refers to a Mach-O file, this - // has exactly one element. - vector object_files_; - - // The object file in object_files_ selected to dump, or NULL if - // SetArchitecture hasn't been called yet. - const SuperFatArch *selected_object_file_; - - // A string that identifies the selected object file, for use in error - // messages. This is usually object_filename_, but if that refers to a - // fat binary, it includes an indication of the particular architecture - // within that binary. - string selected_object_name_; -}; - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.cc deleted file mode 100644 index 4661d5d62..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_id.cc: Return a unique identifier for a file -// -// See file_id.h for documentation -// -// Author: Dan Waylonis - -#include -#include -#include -#include - -#include "common/mac/file_id.h" -#include "common/mac/macho_id.h" - -using MacFileUtilities::MachoID; - -namespace google_breakpad { - -FileID::FileID(const char *path) { - snprintf(path_, sizeof(path_), "%s", path); -} - -bool FileID::FileIdentifier(unsigned char identifier[16]) { - int fd = open(path_, O_RDONLY); - if (fd == -1) - return false; - - MD5Context md5; - MD5Init(&md5); - - // Read 4k x 2 bytes at a time. This is faster than just 4k bytes, but - // doesn't seem to be an unreasonable size for the stack. - unsigned char buffer[4096 * 2]; - size_t buffer_size = sizeof(buffer); - while ((buffer_size = read(fd, buffer, buffer_size) > 0)) { - MD5Update(&md5, buffer, static_cast(buffer_size)); - } - - close(fd); - MD5Final(identifier, &md5); - - return true; -} - -bool FileID::MachoIdentifier(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]) { - MachoID macho(path_); - - if (macho.UUIDCommand(cpu_type, cpu_subtype, identifier)) - return true; - - return macho.MD5(cpu_type, cpu_subtype, identifier); -} - -// static -void FileID::ConvertIdentifierToString(const unsigned char identifier[16], - char *buffer, int buffer_length) { - int buffer_idx = 0; - for (int idx = 0; (buffer_idx < buffer_length) && (idx < 16); ++idx) { - int hi = (identifier[idx] >> 4) & 0x0F; - int lo = (identifier[idx]) & 0x0F; - - if (idx == 4 || idx == 6 || idx == 8 || idx == 10) - buffer[buffer_idx++] = '-'; - - buffer[buffer_idx++] = - static_cast((hi >= 10) ? ('A' + hi - 10) : ('0' + hi)); - buffer[buffer_idx++] = - static_cast((lo >= 10) ? ('A' + lo - 10) : ('0' + lo)); - } - - // NULL terminate - buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.h b/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.h deleted file mode 100644 index 1d6dfde1b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_id.h: Return a unique identifier for a file -// -// Author: Dan Waylonis - -#ifndef COMMON_MAC_FILE_ID_H__ -#define COMMON_MAC_FILE_ID_H__ - -#include -#include - -namespace google_breakpad { - -class FileID { - public: - FileID(const char *path); - ~FileID() {}; - - // Load the identifier for the file path specified in the constructor into - // |identifier|. Return false if the identifier could not be created for the - // file. - // The current implementation will return the MD5 hash of the file's bytes. - bool FileIdentifier(unsigned char identifier[16]); - - // Treat the file as a mach-o file that will contain one or more archicture. - // Accepted values for |cpu_type| and |cpu_subtype| (e.g., CPU_TYPE_X86 or - // CPU_TYPE_POWERPC) are listed in /usr/include/mach/machine.h. - // If |cpu_type| is 0, then the native cpu type is used. If |cpu_subtype| is - // CPU_SUBTYPE_MULTIPLE, the match is only done on |cpu_type|. - // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype| - // is not present in the file. - // Return the unique identifier in |identifier|. - // The current implementation will look for the (in order of priority): - // LC_UUID, LC_ID_DYLIB, or MD5 hash of the given |cpu_type|. - bool MachoIdentifier(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]); - - // Convert the |identifier| data to a NULL terminated string. The string will - // be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE). - // The |buffer| should be at least 37 bytes long to receive all of the data - // and termination. Shorter buffers will contain truncated data. - static void ConvertIdentifierToString(const unsigned char identifier[16], - char *buffer, int buffer_length); - - private: - // Storage for the path specified - char path_[PATH_MAX]; -}; - -} // namespace google_breakpad - -#endif // COMMON_MAC_FILE_ID_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.cc deleted file mode 100644 index 245be8265..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -namespace google_breakpad { - -void LaunchReporter(const char *reporter_executable_path, - const char *config_file_path) { - const char* argv[] = { reporter_executable_path, config_file_path, NULL }; - - // Launch the reporter - pid_t pid = fork(); - - if (pid == -1) { - perror("fork"); - fprintf(stderr, "Failed to fork reporter process\n"); - return; - } - - // If we're in the child, load in our new executable and run. - // The parent will not wait for the child to complete. - if (pid == 0) { - execv(argv[0], (char* const*)argv); - perror("exec"); - fprintf(stderr, - "Failed to launch reporter process from path %s\n", - reporter_executable_path); - unlink(config_file_path); // launch failed - get rid of config file - _exit(1); - } - - // Wait until the Reporter child process exits. - // - - // We'll use a timeout of one minute. - int timeout_count = 60; // 60 seconds - - while (timeout_count-- > 0) { - int status; - pid_t result = waitpid(pid, &status, WNOHANG); - - if (result == 0) { - // The child has not yet finished. - sleep(1); - } else if (result == -1) { - // error occurred. - break; - } else { - // child has finished - break; - } - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.h b/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.h deleted file mode 100644 index 4531123c2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/launch_reporter.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_MAC_LAUNCH_REPORTER_H__ -#define COMMON_MAC_LAUNCH_REPORTER_H__ - -namespace google_breakpad { - -// Launch the crash dump sender app. -// |reporter_executable_path| is the path to the sender executable. -// |config_file_path| is the path to the config file. -void LaunchReporter(const char *reporter_executable_path, - const char *config_file_path); - -} // namespace google_breakpad - -#endif // COMMON_MAC_LAUNCH_REPORTER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.cc deleted file mode 100644 index c396ad888..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.cc +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_id.cc: Functions to gather identifying information from a macho file -// -// See macho_id.h for documentation -// -// Author: Dan Waylonis - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common/mac/macho_id.h" -#include "common/mac/macho_walker.h" -#include "common/mac/macho_utilities.h" - -namespace MacFileUtilities { - -using google_breakpad::MD5Init; -using google_breakpad::MD5Update; -using google_breakpad::MD5Final; - -MachoID::MachoID(const char *path) - : memory_(0), - memory_size_(0), - crc_(0), - md5_context_(), - update_function_(NULL) { - snprintf(path_, sizeof(path_), "%s", path); -} - -MachoID::MachoID(const char *path, void *memory, size_t size) - : memory_(memory), - memory_size_(size), - crc_(0), - md5_context_(), - update_function_(NULL) { - snprintf(path_, sizeof(path_), "%s", path); -} - -MachoID::~MachoID() { -} - -// The CRC info is from http://en.wikipedia.org/wiki/Adler-32 -// With optimizations from http://www.zlib.net/ - -// The largest prime smaller than 65536 -#define MOD_ADLER 65521 -// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1 -#define MAX_BLOCK 5552 - -void MachoID::UpdateCRC(unsigned char *bytes, size_t size) { -// Unrolled loops for summing -#define DO1(buf,i) {sum1 += (buf)[i]; sum2 += sum1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - // Split up the crc - uint32_t sum1 = crc_ & 0xFFFF; - uint32_t sum2 = (crc_ >> 16) & 0xFFFF; - - // Do large blocks - while (size >= MAX_BLOCK) { - size -= MAX_BLOCK; - int block_count = MAX_BLOCK / 16; - do { - DO16(bytes); - bytes += 16; - } while (--block_count); - sum1 %= MOD_ADLER; - sum2 %= MOD_ADLER; - } - - // Do remaining bytes - if (size) { - while (size >= 16) { - size -= 16; - DO16(bytes); - bytes += 16; - } - while (size--) { - sum1 += *bytes++; - sum2 += sum1; - } - sum1 %= MOD_ADLER; - sum2 %= MOD_ADLER; - crc_ = (sum2 << 16) | sum1; - } -} - -void MachoID::UpdateMD5(unsigned char *bytes, size_t size) { - MD5Update(&md5_context_, bytes, static_cast(size)); -} - -void MachoID::Update(MachoWalker *walker, off_t offset, size_t size) { - if (!update_function_ || !size) - return; - - // Read up to 4k bytes at a time - unsigned char buffer[4096]; - size_t buffer_size; - off_t file_offset = offset; - while (size > 0) { - if (size > sizeof(buffer)) { - buffer_size = sizeof(buffer); - size -= buffer_size; - } else { - buffer_size = size; - size = 0; - } - - if (!walker->ReadBytes(buffer, buffer_size, file_offset)) - return; - - (this->*update_function_)(buffer, buffer_size); - file_offset += buffer_size; - } -} - -bool MachoID::UUIDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char bytes[16]) { - struct breakpad_uuid_command uuid_cmd; - uuid_cmd.cmd = 0; - if (!WalkHeader(cpu_type, cpu_subtype, UUIDWalkerCB, &uuid_cmd)) - return false; - - // If we found the command, we'll have initialized the uuid_command - // structure - if (uuid_cmd.cmd == LC_UUID) { - memcpy(bytes, uuid_cmd.uuid, sizeof(uuid_cmd.uuid)); - return true; - } - - return false; -} - -bool MachoID::IDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]) { - struct dylib_command dylib_cmd; - dylib_cmd.cmd = 0; - if (!WalkHeader(cpu_type, cpu_subtype, IDWalkerCB, &dylib_cmd)) - return false; - - // If we found the command, we'll have initialized the dylib_command - // structure - if (dylib_cmd.cmd == LC_ID_DYLIB) { - // Take the hashed filename, version, and compatability version bytes - // to form the first 12 bytes, pad the rest with zeros - - // create a crude hash of the filename to generate the first 4 bytes - identifier[0] = 0; - identifier[1] = 0; - identifier[2] = 0; - identifier[3] = 0; - - for (int j = 0, i = (int)strlen(path_)-1; i>=0 && path_[i]!='/'; ++j, --i) { - identifier[j%4] += path_[i]; - } - - identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF; - identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF; - identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF; - identifier[7] = dylib_cmd.dylib.current_version & 0xFF; - identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF; - identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF; - identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF; - identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF; - identifier[12] = (cpu_type >> 24) & 0xFF; - identifier[13] = (cpu_type >> 16) & 0xFF; - identifier[14] = (cpu_type >> 8) & 0xFF; - identifier[15] = cpu_type & 0xFF; - - return true; - } - - return false; -} - -uint32_t MachoID::Adler32(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { - update_function_ = &MachoID::UpdateCRC; - crc_ = 0; - - if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this)) - return 0; - - return crc_; -} - -bool MachoID::MD5(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) { - update_function_ = &MachoID::UpdateMD5; - - MD5Init(&md5_context_); - - if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this)) - return false; - - MD5Final(identifier, &md5_context_); - return true; -} - -bool MachoID::WalkHeader(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - MachoWalker::LoadCommandCallback callback, - void *context) { - if (memory_) { - MachoWalker walker(memory_, memory_size_, callback, context); - return walker.WalkHeader(cpu_type, cpu_subtype); - } else { - MachoWalker walker(path_, callback, context); - return walker.WalkHeader(cpu_type, cpu_subtype); - } -} - -// static -bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context) { - MachoID *macho_id = (MachoID *)context; - - if (cmd->cmd == LC_SEGMENT) { - struct segment_command seg; - - if (!walker->ReadBytes(&seg, sizeof(seg), offset)) - return false; - - if (swap) - breakpad_swap_segment_command(&seg); - - struct mach_header_64 header; - off_t header_offset; - - if (!walker->CurrentHeader(&header, &header_offset)) - return false; - - // Process segments that have sections: - // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) - offset += sizeof(struct segment_command); - struct section sec; - for (unsigned long i = 0; i < seg.nsects; ++i) { - if (!walker->ReadBytes(&sec, sizeof(sec), offset)) - return false; - - if (swap) - breakpad_swap_section(&sec, 1); - - // sections of type S_ZEROFILL are "virtual" and contain no data - // in the file itself - if ((sec.flags & SECTION_TYPE) != S_ZEROFILL && sec.offset != 0) - macho_id->Update(walker, header_offset + sec.offset, sec.size); - - offset += sizeof(struct section); - } - } else if (cmd->cmd == LC_SEGMENT_64) { - struct segment_command_64 seg64; - - if (!walker->ReadBytes(&seg64, sizeof(seg64), offset)) - return false; - - if (swap) - breakpad_swap_segment_command_64(&seg64); - - struct mach_header_64 header; - off_t header_offset; - - if (!walker->CurrentHeader(&header, &header_offset)) - return false; - - // Process segments that have sections: - // (e.g., __TEXT, __DATA, __IMPORT, __OBJC) - offset += sizeof(struct segment_command_64); - struct section_64 sec64; - for (unsigned long i = 0; i < seg64.nsects; ++i) { - if (!walker->ReadBytes(&sec64, sizeof(sec64), offset)) - return false; - - if (swap) - breakpad_swap_section_64(&sec64, 1); - - // sections of type S_ZEROFILL are "virtual" and contain no data - // in the file itself - if ((sec64.flags & SECTION_TYPE) != S_ZEROFILL && sec64.offset != 0) - macho_id->Update(walker, - header_offset + sec64.offset, - (size_t)sec64.size); - - offset += sizeof(struct section_64); - } - } - - // Continue processing - return true; -} - -// static -bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context) { - if (cmd->cmd == LC_UUID) { - struct breakpad_uuid_command *uuid_cmd = - (struct breakpad_uuid_command *)context; - - if (!walker->ReadBytes(uuid_cmd, sizeof(struct breakpad_uuid_command), - offset)) - return false; - - if (swap) - breakpad_swap_uuid_command(uuid_cmd); - - return false; - } - - // Continue processing - return true; -} - -// static -bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context) { - if (cmd->cmd == LC_ID_DYLIB) { - struct dylib_command *dylib_cmd = (struct dylib_command *)context; - - if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) - return false; - - if (swap) - breakpad_swap_dylib_command(dylib_cmd); - - return false; - } - - // Continue processing - return true; -} - -} // namespace MacFileUtilities diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.h b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.h deleted file mode 100644 index 103754912..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_id.h: Functions to gather identifying information from a macho file -// -// Author: Dan Waylonis - -#ifndef COMMON_MAC_MACHO_ID_H__ -#define COMMON_MAC_MACHO_ID_H__ - -#include -#include -#include - -#include "common/mac/macho_walker.h" -#include "common/md5.h" - -namespace MacFileUtilities { - -class MachoID { - public: - MachoID(const char *path); - MachoID(const char *path, void *memory, size_t size); - ~MachoID(); - - // For the given |cpu_type| and |cpu_subtype|, return a UUID from the LC_UUID - // command. - // Return false if there isn't a LC_UUID command. - bool UUIDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]); - - // For the given |cpu_type| and |cpu_subtype|, return a UUID from the - // LC_ID_DYLIB command. - // Return false if there isn't a LC_ID_DYLIB command. - bool IDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]); - - // For the given |cpu_type| and |cpu_subtype|, return the Adler32 CRC for the - // mach-o data segment(s). - // Return 0 on error (e.g., if the file is not a mach-o file) - uint32_t Adler32(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype); - - // For the given |cpu_type|, and |cpu_subtype| return the MD5 for the mach-o - // data segment(s). - // Return true on success, false otherwise - bool MD5(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]); - - private: - // Signature of class member function to be called with data read from file - typedef void (MachoID::*UpdateFunction)(unsigned char *bytes, size_t size); - - // Update the CRC value by examining |size| |bytes| and applying the algorithm - // to each byte. - void UpdateCRC(unsigned char *bytes, size_t size); - - // Update the MD5 value by examining |size| |bytes| and applying the algorithm - // to each byte. - void UpdateMD5(unsigned char *bytes, size_t size); - - // Bottleneck for update routines - void Update(MachoWalker *walker, off_t offset, size_t size); - - // Factory for the MachoWalker - bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, - MachoWalker::LoadCommandCallback callback, void *context); - - // The callback from the MachoWalker for CRC and MD5 - static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context); - - // The callback from the MachoWalker for LC_UUID - static bool UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context); - - // The callback from the MachoWalker for LC_ID_DYLIB - static bool IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset, - bool swap, void *context); - - // File path - char path_[PATH_MAX]; - - // Memory region to read from - void *memory_; - - // Size of the memory region - size_t memory_size_; - - // The current crc value - uint32_t crc_; - - // The MD5 context - google_breakpad::MD5Context md5_context_; - - // The current update to call from the Update callback - UpdateFunction update_function_; -}; - -} // namespace MacFileUtilities - -#endif // COMMON_MAC_MACHO_ID_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.cc deleted file mode 100644 index 52f3c411b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.cc +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// macho_reader.cc: Implementation of google_breakpad::Mach_O::FatReader and -// google_breakpad::Mach_O::Reader. See macho_reader.h for details. - -#include "common/mac/macho_reader.h" - -#include -#include -#include - -// Unfortunately, CPU_TYPE_ARM is not define for 10.4. -#if !defined(CPU_TYPE_ARM) -#define CPU_TYPE_ARM 12 -#endif - -#if !defined(CPU_TYPE_ARM_64) -#define CPU_TYPE_ARM_64 16777228 -#endif - -namespace google_breakpad { -namespace mach_o { - -// If NDEBUG is #defined, then the 'assert' macro doesn't evaluate its -// arguments, so you can't place expressions that do necessary work in -// the argument of an assert. Nor can you assign the result of the -// expression to a variable and assert that the variable's value is -// true: you'll get unused variable warnings when NDEBUG is #defined. -// -// ASSERT_ALWAYS_EVAL always evaluates its argument, and asserts that -// the result is true if NDEBUG is not #defined. -#if defined(NDEBUG) -#define ASSERT_ALWAYS_EVAL(x) (x) -#else -#define ASSERT_ALWAYS_EVAL(x) assert(x) -#endif - -void FatReader::Reporter::BadHeader() { - fprintf(stderr, "%s: file is neither a fat binary file" - " nor a Mach-O object file\n", filename_.c_str()); -} - -void FatReader::Reporter::TooShort() { - fprintf(stderr, "%s: file too short for the data it claims to contain\n", - filename_.c_str()); -} - -void FatReader::Reporter::MisplacedObjectFile() { - fprintf(stderr, "%s: file too short for the object files it claims" - " to contain\n", filename_.c_str()); -} - -bool FatReader::Read(const uint8_t *buffer, size_t size) { - buffer_.start = buffer; - buffer_.end = buffer + size; - ByteCursor cursor(&buffer_); - - // Fat binaries always use big-endian, so read the magic number in - // that endianness. To recognize Mach-O magic numbers, which can use - // either endianness, check for both the proper and reversed forms - // of the magic numbers. - cursor.set_big_endian(true); - if (cursor >> magic_) { - if (magic_ == FAT_MAGIC) { - // How many object files does this fat binary contain? - uint32_t object_files_count; - if (!(cursor >> object_files_count)) { // nfat_arch - reporter_->TooShort(); - return false; - } - - // Read the list of object files. - object_files_.resize(object_files_count); - for (size_t i = 0; i < object_files_count; i++) { - struct fat_arch objfile; - - // Read this object file entry, byte-swapping as appropriate. - cursor >> objfile.cputype - >> objfile.cpusubtype - >> objfile.offset - >> objfile.size - >> objfile.align; - - SuperFatArch super_fat_arch(objfile); - object_files_[i] = super_fat_arch; - - if (!cursor) { - reporter_->TooShort(); - return false; - } - // Does the file actually have the bytes this entry refers to? - size_t fat_size = buffer_.Size(); - if (objfile.offset > fat_size || - objfile.size > fat_size - objfile.offset) { - reporter_->MisplacedObjectFile(); - return false; - } - } - - return true; - } else if (magic_ == MH_MAGIC || magic_ == MH_MAGIC_64 || - magic_ == MH_CIGAM || magic_ == MH_CIGAM_64) { - // If this is a little-endian Mach-O file, fix the cursor's endianness. - if (magic_ == MH_CIGAM || magic_ == MH_CIGAM_64) - cursor.set_big_endian(false); - // Record the entire file as a single entry in the object file list. - object_files_.resize(1); - - // Get the cpu type and subtype from the Mach-O header. - if (!(cursor >> object_files_[0].cputype - >> object_files_[0].cpusubtype)) { - reporter_->TooShort(); - return false; - } - - object_files_[0].offset = 0; - object_files_[0].size = static_cast(buffer_.Size()); - // This alignment is correct for 32 and 64-bit x86 and ppc. - // See get_align in the lipo source for other architectures: - // http://www.opensource.apple.com/source/cctools/cctools-773/misc/lipo.c - object_files_[0].align = 12; // 2^12 == 4096 - return true; - } - } - reporter_->BadHeader(); - return false; -} - -void Reader::Reporter::BadHeader() { - fprintf(stderr, "%s: file is not a Mach-O object file\n", filename_.c_str()); -} - -void Reader::Reporter::CPUTypeMismatch(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype) { - fprintf(stderr, "%s: CPU type %d, subtype %d does not match expected" - " type %d, subtype %d\n", - filename_.c_str(), cpu_type, cpu_subtype, - expected_cpu_type, expected_cpu_subtype); -} - -void Reader::Reporter::HeaderTruncated() { - fprintf(stderr, "%s: file does not contain a complete Mach-O header\n", - filename_.c_str()); -} - -void Reader::Reporter::LoadCommandRegionTruncated() { - fprintf(stderr, "%s: file too short to hold load command region" - " given in Mach-O header\n", filename_.c_str()); -} - -void Reader::Reporter::LoadCommandsOverrun(size_t claimed, size_t i, - LoadCommandType type) { - fprintf(stderr, "%s: file's header claims there are %zu" - " load commands, but load command #%zu", - filename_.c_str(), claimed, i); - if (type) fprintf(stderr, ", of type %d,", type); - fprintf(stderr, " extends beyond the end of the load command region\n"); -} - -void Reader::Reporter::LoadCommandTooShort(size_t i, LoadCommandType type) { - fprintf(stderr, "%s: the contents of load command #%zu, of type %d," - " extend beyond the size given in the load command's header\n", - filename_.c_str(), i, type); -} - -void Reader::Reporter::SectionsMissing(const string &name) { - fprintf(stderr, "%s: the load command for segment '%s'" - " is too short to hold the section headers it claims to have\n", - filename_.c_str(), name.c_str()); -} - -void Reader::Reporter::MisplacedSegmentData(const string &name) { - fprintf(stderr, "%s: the segment '%s' claims its contents lie beyond" - " the end of the file\n", filename_.c_str(), name.c_str()); -} - -void Reader::Reporter::MisplacedSectionData(const string §ion, - const string &segment) { - fprintf(stderr, "%s: the section '%s' in segment '%s'" - " claims its contents lie outside the segment's contents\n", - filename_.c_str(), section.c_str(), segment.c_str()); -} - -void Reader::Reporter::MisplacedSymbolTable() { - fprintf(stderr, "%s: the LC_SYMTAB load command claims that the symbol" - " table's contents are located beyond the end of the file\n", - filename_.c_str()); -} - -void Reader::Reporter::UnsupportedCPUType(cpu_type_t cpu_type) { - fprintf(stderr, "%s: CPU type %d is not supported\n", - filename_.c_str(), cpu_type); -} - -bool Reader::Read(const uint8_t *buffer, - size_t size, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype) { - assert(!buffer_.start); - buffer_.start = buffer; - buffer_.end = buffer + size; - ByteCursor cursor(&buffer_, true); - uint32_t magic; - if (!(cursor >> magic)) { - reporter_->HeaderTruncated(); - return false; - } - - if (expected_cpu_type != CPU_TYPE_ANY) { - uint32_t expected_magic; - // validate that magic matches the expected cpu type - switch (expected_cpu_type) { - case CPU_TYPE_ARM: - case CPU_TYPE_I386: - expected_magic = MH_CIGAM; - break; - case CPU_TYPE_POWERPC: - expected_magic = MH_MAGIC; - break; - case CPU_TYPE_ARM_64: - case CPU_TYPE_X86_64: - expected_magic = MH_CIGAM_64; - break; - case CPU_TYPE_POWERPC64: - expected_magic = MH_MAGIC_64; - break; - default: - reporter_->UnsupportedCPUType(expected_cpu_type); - return false; - } - - if (expected_magic != magic) { - reporter_->BadHeader(); - return false; - } - } - - // Since the byte cursor is in big-endian mode, a reversed magic number - // always indicates a little-endian file, regardless of our own endianness. - switch (magic) { - case MH_MAGIC: big_endian_ = true; bits_64_ = false; break; - case MH_CIGAM: big_endian_ = false; bits_64_ = false; break; - case MH_MAGIC_64: big_endian_ = true; bits_64_ = true; break; - case MH_CIGAM_64: big_endian_ = false; bits_64_ = true; break; - default: - reporter_->BadHeader(); - return false; - } - cursor.set_big_endian(big_endian_); - uint32_t commands_size, reserved; - cursor >> cpu_type_ >> cpu_subtype_ >> file_type_ >> load_command_count_ - >> commands_size >> flags_; - if (bits_64_) - cursor >> reserved; - if (!cursor) { - reporter_->HeaderTruncated(); - return false; - } - - if (expected_cpu_type != CPU_TYPE_ANY && - (expected_cpu_type != cpu_type_ || - expected_cpu_subtype != cpu_subtype_)) { - reporter_->CPUTypeMismatch(cpu_type_, cpu_subtype_, - expected_cpu_type, expected_cpu_subtype); - return false; - } - - cursor - .PointTo(&load_commands_.start, commands_size) - .PointTo(&load_commands_.end, 0); - if (!cursor) { - reporter_->LoadCommandRegionTruncated(); - return false; - } - - return true; -} - -bool Reader::WalkLoadCommands(Reader::LoadCommandHandler *handler) const { - ByteCursor list_cursor(&load_commands_, big_endian_); - - for (size_t index = 0; index < load_command_count_; ++index) { - // command refers to this load command alone, so that cursor will - // refuse to read past the load command's end. But since we haven't - // read the size yet, let command initially refer to the entire - // remainder of the load command series. - ByteBuffer command(list_cursor.here(), list_cursor.Available()); - ByteCursor cursor(&command, big_endian_); - - // Read the command type and size --- fields common to all commands. - uint32_t type, size; - if (!(cursor >> type)) { - reporter_->LoadCommandsOverrun(load_command_count_, index, 0); - return false; - } - if (!(cursor >> size) || size > command.Size()) { - reporter_->LoadCommandsOverrun(load_command_count_, index, type); - return false; - } - - // Now that we've read the length, restrict command's range to this - // load command only. - command.end = command.start + size; - - switch (type) { - case LC_SEGMENT: - case LC_SEGMENT_64: { - Segment segment; - segment.bits_64 = (type == LC_SEGMENT_64); - size_t word_size = segment.bits_64 ? 8 : 4; - cursor.CString(&segment.name, 16); - size_t file_offset, file_size; - cursor - .Read(word_size, false, &segment.vmaddr) - .Read(word_size, false, &segment.vmsize) - .Read(word_size, false, &file_offset) - .Read(word_size, false, &file_size); - cursor >> segment.maxprot - >> segment.initprot - >> segment.nsects - >> segment.flags; - if (!cursor) { - reporter_->LoadCommandTooShort(index, type); - return false; - } - if (file_offset > buffer_.Size() || - file_size > buffer_.Size() - file_offset) { - reporter_->MisplacedSegmentData(segment.name); - return false; - } - // Mach-O files in .dSYM bundles have the contents of the loaded - // segments removed, and their file offsets and file sizes zeroed - // out. To help us handle this special case properly, give such - // segments' contents NULL starting and ending pointers. - if (file_offset == 0 && file_size == 0) { - segment.contents.start = segment.contents.end = NULL; - } else { - segment.contents.start = buffer_.start + file_offset; - segment.contents.end = segment.contents.start + file_size; - } - // The section list occupies the remainder of this load command's space. - segment.section_list.start = cursor.here(); - segment.section_list.end = command.end; - - if (!handler->SegmentCommand(segment)) - return false; - break; - } - - case LC_SYMTAB: { - uint32_t symoff, nsyms, stroff, strsize; - cursor >> symoff >> nsyms >> stroff >> strsize; - if (!cursor) { - reporter_->LoadCommandTooShort(index, type); - return false; - } - // How big are the entries in the symbol table? - // sizeof(struct nlist_64) : sizeof(struct nlist), - // but be paranoid about alignment vs. target architecture. - size_t symbol_size = bits_64_ ? 16 : 12; - // How big is the entire symbol array? - size_t symbols_size = nsyms * symbol_size; - if (symoff > buffer_.Size() || symbols_size > buffer_.Size() - symoff || - stroff > buffer_.Size() || strsize > buffer_.Size() - stroff) { - reporter_->MisplacedSymbolTable(); - return false; - } - ByteBuffer entries(buffer_.start + symoff, symbols_size); - ByteBuffer names(buffer_.start + stroff, strsize); - if (!handler->SymtabCommand(entries, names)) - return false; - break; - } - - default: { - if (!handler->UnknownCommand(type, command)) - return false; - break; - } - } - - list_cursor.set_here(command.end); - } - - return true; -} - -// A load command handler that looks for a segment of a given name. -class Reader::SegmentFinder : public LoadCommandHandler { - public: - // Create a load command handler that looks for a segment named NAME, - // and sets SEGMENT to describe it if found. - SegmentFinder(const string &name, Segment *segment) - : name_(name), segment_(segment), found_() { } - - // Return true if the traversal found the segment, false otherwise. - bool found() const { return found_; } - - bool SegmentCommand(const Segment &segment) { - if (segment.name == name_) { - *segment_ = segment; - found_ = true; - return false; - } - return true; - } - - private: - // The name of the segment our creator is looking for. - const string &name_; - - // Where we should store the segment if found. (WEAK) - Segment *segment_; - - // True if we found the segment. - bool found_; -}; - -bool Reader::FindSegment(const string &name, Segment *segment) const { - SegmentFinder finder(name, segment); - WalkLoadCommands(&finder); - return finder.found(); -} - -bool Reader::WalkSegmentSections(const Segment &segment, - SectionHandler *handler) const { - size_t word_size = segment.bits_64 ? 8 : 4; - ByteCursor cursor(&segment.section_list, big_endian_); - - for (size_t i = 0; i < segment.nsects; i++) { - Section section; - section.bits_64 = segment.bits_64; - uint64_t size; - uint32_t offset, dummy32; - cursor - .CString(§ion.section_name, 16) - .CString(§ion.segment_name, 16) - .Read(word_size, false, §ion.address) - .Read(word_size, false, &size) - >> offset - >> section.align - >> dummy32 - >> dummy32 - >> section.flags - >> dummy32 - >> dummy32; - if (section.bits_64) - cursor >> dummy32; - if (!cursor) { - reporter_->SectionsMissing(segment.name); - return false; - } - const uint32_t section_type = section.flags & SECTION_TYPE; - if (section_type == S_ZEROFILL || section_type == S_THREAD_LOCAL_ZEROFILL || - section_type == S_GB_ZEROFILL) { - // Zero-fill sections have a size, but no contents. - section.contents.start = section.contents.end = NULL; - } else if (segment.contents.start == NULL && - segment.contents.end == NULL) { - // Mach-O files in .dSYM bundles have the contents of the loaded - // segments removed, and their file offsets and file sizes zeroed - // out. However, the sections within those segments still have - // non-zero sizes. There's no reason to call MisplacedSectionData in - // this case; the caller may just need the section's load - // address. But do set the contents' limits to NULL, for safety. - section.contents.start = section.contents.end = NULL; - } else { - if (offset < size_t(segment.contents.start - buffer_.start) || - offset > size_t(segment.contents.end - buffer_.start) || - size > size_t(segment.contents.end - buffer_.start - offset)) { - reporter_->MisplacedSectionData(section.section_name, - section.segment_name); - return false; - } - section.contents.start = buffer_.start + offset; - section.contents.end = section.contents.start + size; - } - if (!handler->HandleSection(section)) - return false; - } - return true; -} - -// A SectionHandler that builds a SectionMap for the sections within a -// given segment. -class Reader::SectionMapper: public SectionHandler { - public: - // Create a SectionHandler that populates MAP with an entry for - // each section it is given. - SectionMapper(SectionMap *map) : map_(map) { } - bool HandleSection(const Section §ion) { - (*map_)[section.section_name] = section; - return true; - } - private: - // The map under construction. (WEAK) - SectionMap *map_; -}; - -bool Reader::MapSegmentSections(const Segment &segment, - SectionMap *section_map) const { - section_map->clear(); - SectionMapper mapper(section_map); - return WalkSegmentSections(segment, &mapper); -} - -} // namespace mach_o -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.h b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.h deleted file mode 100644 index 30db742db..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader.h +++ /dev/null @@ -1,460 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// macho_reader.h: A class for parsing Mach-O files. - -#ifndef BREAKPAD_COMMON_MAC_MACHO_READER_H_ -#define BREAKPAD_COMMON_MAC_MACHO_READER_H_ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/byte_cursor.h" -#include "common/mac/super_fat_arch.h" - -namespace google_breakpad { -namespace mach_o { - -using std::map; -using std::string; -using std::vector; - -// The Mac headers don't specify particular types for these groups of -// constants, but defining them here provides some documentation -// value. We also give them the same width as the fields in which -// they appear, which makes them a bit easier to use with ByteCursors. -typedef uint32_t Magic; -typedef uint32_t FileType; -typedef uint32_t FileFlags; -typedef uint32_t LoadCommandType; -typedef uint32_t SegmentFlags; -typedef uint32_t SectionFlags; - -// A parser for fat binary files, used to store universal binaries. -// When applied to a (non-fat) Mach-O file, this behaves as if the -// file were a fat file containing a single object file. -class FatReader { - public: - - // A class for reporting errors found while parsing fat binary files. The - // default definitions of these methods print messages to stderr. - class Reporter { - public: - // Create a reporter that attributes problems to |filename|. - explicit Reporter(const string &filename) : filename_(filename) { } - - virtual ~Reporter() { } - - // The data does not begin with a fat binary or Mach-O magic number. - // This is a fatal error. - virtual void BadHeader(); - - // The Mach-O fat binary file ends abruptly, without enough space - // to contain an object file it claims is present. - virtual void MisplacedObjectFile(); - - // The file ends abruptly: either it is not large enough to hold a - // complete header, or the header implies that contents are present - // beyond the actual end of the file. - virtual void TooShort(); - - private: - // The filename to which the reader should attribute problems. - string filename_; - }; - - // Create a fat binary file reader that uses |reporter| to report problems. - explicit FatReader(Reporter *reporter) : reporter_(reporter) { } - - // Read the |size| bytes at |buffer| as a fat binary file. On success, - // return true; on failure, report the problem to reporter_ and return - // false. - // - // If the data is a plain Mach-O file, rather than a fat binary file, - // then the reader behaves as if it had found a fat binary file whose - // single object file is the Mach-O file. - bool Read(const uint8_t *buffer, size_t size); - - // Return an array of 'SuperFatArch' structures describing the - // object files present in this fat binary file. Set |size| to the - // number of elements in the array. - // - // Assuming Read returned true, the entries are validated: it is safe to - // assume that the offsets and sizes in each SuperFatArch refer to subranges - // of the bytes passed to Read. - // - // If there are no object files in this fat binary, then this - // function can return NULL. - // - // The array is owned by this FatReader instance; it will be freed when - // this FatReader is destroyed. - // - // This function returns a C-style array instead of a vector to make it - // possible to use the result with OS X functions like NXFindBestFatArch, - // so that the symbol dumper will behave consistently with other OS X - // utilities that work with fat binaries. - const SuperFatArch* object_files(size_t *count) const { - *count = object_files_.size(); - if (object_files_.size() > 0) - return &object_files_[0]; - return NULL; - } - - private: - // We use this to report problems parsing the file's contents. (WEAK) - Reporter *reporter_; - - // The contents of the fat binary or Mach-O file we're parsing. We do not - // own the storage it refers to. - ByteBuffer buffer_; - - // The magic number of this binary, in host byte order. - Magic magic_; - - // The list of object files in this binary. - // object_files_.size() == fat_header.nfat_arch - vector object_files_; -}; - -// A segment in a Mach-O file. All these fields have been byte-swapped as -// appropriate for use by the executing architecture. -struct Segment { - // The ByteBuffers below point into the bytes passed to the Reader that - // created this Segment. - - ByteBuffer section_list; // This segment's section list. - ByteBuffer contents; // This segment's contents. - - // This segment's name. - string name; - - // The address at which this segment should be loaded in memory. If - // bits_64 is false, only the bottom 32 bits of this value are valid. - uint64_t vmaddr; - - // The size of this segment when loaded into memory. This may be larger - // than contents.Size(), in which case the extra area will be - // initialized with zeros. If bits_64 is false, only the bottom 32 bits - // of this value are valid. - uint64_t vmsize; - - // The maximum and initial VM protection of this segment's contents. - uint32_t maxprot; - uint32_t initprot; - - // The number of sections in section_list. - uint32_t nsects; - - // Flags describing this segment, from SegmentFlags. - uint32_t flags; - - // True if this is a 64-bit section; false if it is a 32-bit section. - bool bits_64; -}; - -// A section in a Mach-O file. All these fields have been byte-swapped as -// appropriate for use by the executing architecture. -struct Section { - // This section's contents. This points into the bytes passed to the - // Reader that created this Section. - ByteBuffer contents; - - // This section's name. - string section_name; // section[_64].sectname - // The name of the segment this section belongs to. - string segment_name; // section[_64].segname - - // The address at which this section's contents should be loaded in - // memory. If bits_64 is false, only the bottom 32 bits of this value - // are valid. - uint64_t address; - - // The contents of this section should be loaded into memory at an - // address which is a multiple of (two raised to this power). - uint32_t align; - - // Flags from SectionFlags describing the section's contents. - uint32_t flags; - - // We don't support reading relocations yet. - - // True if this is a 64-bit section; false if it is a 32-bit section. - bool bits_64; -}; - -// A map from section names to Sections. -typedef map SectionMap; - -// A reader for a Mach-O file. -// -// This does not handle fat binaries; see FatReader above. FatReader -// provides a friendly interface for parsing data that could be either a -// fat binary or a Mach-O file. -class Reader { - public: - - // A class for reporting errors found while parsing Mach-O files. The - // default definitions of these member functions print messages to - // stderr. - class Reporter { - public: - // Create a reporter that attributes problems to |filename|. - explicit Reporter(const string &filename) : filename_(filename) { } - virtual ~Reporter() { } - - // Reporter functions for fatal errors return void; the reader will - // definitely return an error to its caller after calling them - - // The data does not begin with a Mach-O magic number, or the magic - // number does not match the expected value for the cpu architecture. - // This is a fatal error. - virtual void BadHeader(); - - // The data contained in a Mach-O fat binary (|cpu_type|, |cpu_subtype|) - // does not match the expected CPU architecture - // (|expected_cpu_type|, |expected_cpu_subtype|). - virtual void CPUTypeMismatch(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype); - - // The file ends abruptly: either it is not large enough to hold a - // complete header, or the header implies that contents are present - // beyond the actual end of the file. - virtual void HeaderTruncated(); - - // The file's load command region, as given in the Mach-O header, is - // too large for the file. - virtual void LoadCommandRegionTruncated(); - - // The file's Mach-O header claims the file contains |claimed| load - // commands, but the I'th load command, of type |type|, extends beyond - // the end of the load command region, as given by the Mach-O header. - // If |type| is zero, the command's type was unreadable. - virtual void LoadCommandsOverrun(size_t claimed, size_t i, - LoadCommandType type); - - // The contents of the |i|'th load command, of type |type|, extend beyond - // the size given in the load command's header. - virtual void LoadCommandTooShort(size_t i, LoadCommandType type); - - // The LC_SEGMENT or LC_SEGMENT_64 load command for the segment named - // |name| is too short to hold the sections that its header says it does. - // (This more specific than LoadCommandTooShort.) - virtual void SectionsMissing(const string &name); - - // The segment named |name| claims that its contents lie beyond the end - // of the file. - virtual void MisplacedSegmentData(const string &name); - - // The section named |section| in the segment named |segment| claims that - // its contents do not lie entirely within the segment. - virtual void MisplacedSectionData(const string §ion, - const string &segment); - - // The LC_SYMTAB command claims that symbol table contents are located - // beyond the end of the file. - virtual void MisplacedSymbolTable(); - - // An attempt was made to read a Mach-O file of the unsupported - // CPU architecture |cpu_type|. - virtual void UnsupportedCPUType(cpu_type_t cpu_type); - - private: - string filename_; - }; - - // A handler for sections parsed from a segment. The WalkSegmentSections - // member function accepts an instance of this class, and applies it to - // each section defined in a given segment. - class SectionHandler { - public: - virtual ~SectionHandler() { } - - // Called to report that the segment's section list contains |section|. - // This should return true if the iteration should continue, or false - // if it should stop. - virtual bool HandleSection(const Section §ion) = 0; - }; - - // A handler for the load commands in a Mach-O file. - class LoadCommandHandler { - public: - LoadCommandHandler() { } - virtual ~LoadCommandHandler() { } - - // When called from WalkLoadCommands, the following handler functions - // should return true if they wish to continue iterating over the load - // command list, or false if they wish to stop iterating. - // - // When called from LoadCommandIterator::Handle or Reader::Handle, - // these functions' return values are simply passed through to Handle's - // caller. - // - // The definitions provided by this base class simply return true; the - // default is to silently ignore sections whose member functions the - // subclass doesn't override. - - // COMMAND is load command we don't recognize. We provide only the - // command type and a ByteBuffer enclosing the command's data (If we - // cannot parse the command type or its size, we call - // reporter_->IncompleteLoadCommand instead.) - virtual bool UnknownCommand(LoadCommandType type, - const ByteBuffer &contents) { - return true; - } - - // The load command is LC_SEGMENT or LC_SEGMENT_64, defining a segment - // with the properties given in |segment|. - virtual bool SegmentCommand(const Segment &segment) { - return true; - } - - // The load command is LC_SYMTAB. |entries| holds the array of nlist - // entries, and |names| holds the strings the entries refer to. - virtual bool SymtabCommand(const ByteBuffer &entries, - const ByteBuffer &names) { - return true; - } - - // Add handler functions for more load commands here as needed. - }; - - // Create a Mach-O file reader that reports problems to |reporter|. - explicit Reader(Reporter *reporter) - : reporter_(reporter) { } - - // Read the given data as a Mach-O file. The reader retains pointers - // into the data passed, so the data should live as long as the reader - // does. On success, return true; on failure, return false. - // - // At most one of these functions should be invoked once on each Reader - // instance. - bool Read(const uint8_t *buffer, - size_t size, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype); - bool Read(const ByteBuffer &buffer, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype) { - return Read(buffer.start, - buffer.Size(), - expected_cpu_type, - expected_cpu_subtype); - } - - // Return this file's characteristics, as found in the Mach-O header. - cpu_type_t cpu_type() const { return cpu_type_; } - cpu_subtype_t cpu_subtype() const { return cpu_subtype_; } - FileType file_type() const { return file_type_; } - FileFlags flags() const { return flags_; } - - // Return true if this is a 64-bit Mach-O file, false if it is a 32-bit - // Mach-O file. - bool bits_64() const { return bits_64_; } - - // Return true if this is a big-endian Mach-O file, false if it is - // little-endian. - bool big_endian() const { return big_endian_; } - - // Apply |handler| to each load command in this Mach-O file, stopping when - // a handler function returns false. If we encounter a malformed load - // command, report it via reporter_ and return false. Return true if all - // load commands were parseable and all handlers returned true. - bool WalkLoadCommands(LoadCommandHandler *handler) const; - - // Set |segment| to describe the segment named |name|, if present. If - // found, |segment|'s byte buffers refer to a subregion of the bytes - // passed to Read. If we find the section, return true; otherwise, - // return false. - bool FindSegment(const string &name, Segment *segment) const; - - // Apply |handler| to each section defined in |segment|. If |handler| returns - // false, stop iterating and return false. If all calls to |handler| return - // true and we reach the end of the section list, return true. - bool WalkSegmentSections(const Segment &segment, SectionHandler *handler) - const; - - // Clear |section_map| and then populate it with a map of the sections - // in |segment|, from section names to Section structures. - // Each Section's contents refer to bytes in |segment|'s contents. - // On success, return true; if a problem occurs, report it and return false. - bool MapSegmentSections(const Segment &segment, SectionMap *section_map) - const; - - private: - // Used internally. - class SegmentFinder; - class SectionMapper; - - // We use this to report problems parsing the file's contents. (WEAK) - Reporter *reporter_; - - // The contents of the Mach-O file we're parsing. We do not own the - // storage it refers to. - ByteBuffer buffer_; - - // True if this file is big-endian. - bool big_endian_; - - // True if this file is a 64-bit Mach-O file. - bool bits_64_; - - // This file's cpu type and subtype. - cpu_type_t cpu_type_; // mach_header[_64].cputype - cpu_subtype_t cpu_subtype_; // mach_header[_64].cpusubtype - - // This file's type. - FileType file_type_; // mach_header[_64].filetype - - // The region of buffer_ occupied by load commands. - ByteBuffer load_commands_; - - // The number of load commands in load_commands_. - uint32_t load_command_count_; // mach_header[_64].ncmds - - // This file's header flags. - FileFlags flags_; -}; - -} // namespace mach_o -} // namespace google_breakpad - -#endif // BREAKPAD_COMMON_MAC_MACHO_READER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader_unittest.cc deleted file mode 100644 index 8ceab14bf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_reader_unittest.cc +++ /dev/null @@ -1,1902 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// macho_reader_unittest.cc: Unit tests for google_breakpad::Mach_O::FatReader -// and google_breakpad::Mach_O::Reader. - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/mac/macho_reader.h" -#include "common/test_assembler.h" - -namespace mach_o = google_breakpad::mach_o; -namespace test_assembler = google_breakpad::test_assembler; - -using mach_o::FatReader; -using mach_o::FileFlags; -using mach_o::FileType; -using mach_o::LoadCommandType; -using mach_o::Reader; -using mach_o::Section; -using mach_o::SectionMap; -using mach_o::Segment; -using test_assembler::Endianness; -using test_assembler::Label; -using test_assembler::kBigEndian; -using test_assembler::kLittleEndian; -using test_assembler::kUnsetEndian; -using google_breakpad::ByteBuffer; -using std::map; -using std::string; -using std::vector; -using testing::AllOf; -using testing::DoAll; -using testing::Field; -using testing::InSequence; -using testing::Matcher; -using testing::Return; -using testing::SaveArg; -using testing::Test; -using testing::_; - - -// Mock classes for the reader's various reporters and handlers. - -class MockFatReaderReporter: public FatReader::Reporter { - public: - MockFatReaderReporter(const string &filename) - : FatReader::Reporter(filename) { } - MOCK_METHOD0(BadHeader, void()); - MOCK_METHOD0(MisplacedObjectFile, void()); - MOCK_METHOD0(TooShort, void()); -}; - -class MockReaderReporter: public Reader::Reporter { - public: - MockReaderReporter(const string &filename) : Reader::Reporter(filename) { } - MOCK_METHOD0(BadHeader, void()); - MOCK_METHOD4(CPUTypeMismatch, void(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype)); - MOCK_METHOD0(HeaderTruncated, void()); - MOCK_METHOD0(LoadCommandRegionTruncated, void()); - MOCK_METHOD3(LoadCommandsOverrun, void(size_t claimed, size_t i, - LoadCommandType type)); - MOCK_METHOD2(LoadCommandTooShort, void(size_t i, LoadCommandType type)); - MOCK_METHOD1(SectionsMissing, void(const string &name)); - MOCK_METHOD1(MisplacedSegmentData, void(const string &name)); - MOCK_METHOD2(MisplacedSectionData, void(const string §ion, - const string &segment)); - MOCK_METHOD0(MisplacedSymbolTable, void()); - MOCK_METHOD1(UnsupportedCPUType, void(cpu_type_t cpu_type)); -}; - -class MockLoadCommandHandler: public Reader::LoadCommandHandler { - public: - MOCK_METHOD2(UnknownCommand, bool(LoadCommandType, const ByteBuffer &)); - MOCK_METHOD1(SegmentCommand, bool(const Segment &)); - MOCK_METHOD2(SymtabCommand, bool(const ByteBuffer &, const ByteBuffer &)); -}; - -class MockSectionHandler: public Reader::SectionHandler { - public: - MOCK_METHOD1(HandleSection, bool(const Section §ion)); -}; - - -// Tests for mach_o::FatReader. - -// Since the effect of these functions is to write to stderr, the -// results of these tests must be inspected by hand. -TEST(FatReaderReporter, BadHeader) { - FatReader::Reporter reporter("filename"); - reporter.BadHeader(); -} - -TEST(FatReaderReporter, MisplacedObjectFile) { - FatReader::Reporter reporter("filename"); - reporter.MisplacedObjectFile(); -} - -TEST(FatReaderReporter, TooShort) { - FatReader::Reporter reporter("filename"); - reporter.TooShort(); -} - -TEST(MachOReaderReporter, BadHeader) { - Reader::Reporter reporter("filename"); - reporter.BadHeader(); -} - -TEST(MachOReaderReporter, CPUTypeMismatch) { - Reader::Reporter reporter("filename"); - reporter.CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, - CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL); -} - -TEST(MachOReaderReporter, HeaderTruncated) { - Reader::Reporter reporter("filename"); - reporter.HeaderTruncated(); -} - -TEST(MachOReaderReporter, LoadCommandRegionTruncated) { - Reader::Reporter reporter("filename"); - reporter.LoadCommandRegionTruncated(); -} - -TEST(MachOReaderReporter, LoadCommandsOverrun) { - Reader::Reporter reporter("filename"); - reporter.LoadCommandsOverrun(10, 9, LC_DYSYMTAB); - reporter.LoadCommandsOverrun(10, 9, 0); -} - -TEST(MachOReaderReporter, LoadCommandTooShort) { - Reader::Reporter reporter("filename"); - reporter.LoadCommandTooShort(11, LC_SYMTAB); -} - -TEST(MachOReaderReporter, SectionsMissing) { - Reader::Reporter reporter("filename"); - reporter.SectionsMissing("segment name"); -} - -TEST(MachOReaderReporter, MisplacedSegmentData) { - Reader::Reporter reporter("filename"); - reporter.MisplacedSegmentData("segment name"); -} - -TEST(MachOReaderReporter, MisplacedSectionData) { - Reader::Reporter reporter("filename"); - reporter.MisplacedSectionData("section name", "segment name"); -} - -TEST(MachOReaderReporter, MisplacedSymbolTable) { - Reader::Reporter reporter("filename"); - reporter.MisplacedSymbolTable(); -} - -TEST(MachOReaderReporter, UnsupportedCPUType) { - Reader::Reporter reporter("filename"); - reporter.UnsupportedCPUType(CPU_TYPE_HPPA); -} - -struct FatReaderFixture { - FatReaderFixture() - : fat(kBigEndian), - reporter("reporter filename"), - reader(&reporter), object_files() { - EXPECT_CALL(reporter, BadHeader()).Times(0); - EXPECT_CALL(reporter, TooShort()).Times(0); - - // here, start, and Mark are file offsets in 'fat'. - fat.start() = 0; - } - // Append a 'fat_arch' entry to 'fat', with the given field values. - void AppendFatArch(cpu_type_t type, cpu_subtype_t subtype, - Label offset, Label size, uint32_t align) { - fat - .B32(type) - .B32(subtype) - .B32(offset) - .B32(size) - .B32(align); - } - // Append |n| dummy 'fat_arch' entries to 'fat'. The cpu type and - // subtype have unrealistic values. - void AppendDummyArchEntries(int n) { - for (int i = 0; i < n; i++) - AppendFatArch(0xb68ad617, 0x715a0840, 0, 0, 1); - } - void ReadFat(bool expect_parse_success = true) { - ASSERT_TRUE(fat.GetContents(&contents)); - fat_bytes = reinterpret_cast(contents.data()); - if (expect_parse_success) { - EXPECT_TRUE(reader.Read(fat_bytes, contents.size())); - size_t fat_files_count; - const SuperFatArch* fat_files = reader.object_files(&fat_files_count); - object_files.resize(fat_files_count); - for (size_t i = 0; i < fat_files_count; ++i) { - EXPECT_TRUE(fat_files[i].ConvertToFatArch(&object_files[i])); - } - } - else - EXPECT_FALSE(reader.Read(fat_bytes, contents.size())); - } - test_assembler::Section fat; - MockFatReaderReporter reporter; - FatReader reader; - string contents; - const uint8_t *fat_bytes; - vector object_files; -}; - -class FatReaderTest: public FatReaderFixture, public Test { }; - -TEST_F(FatReaderTest, BadMagic) { - EXPECT_CALL(reporter, BadHeader()).Times(1); - fat - .B32(0xcafed00d) // magic number (incorrect) - .B32(10); // number of architectures - AppendDummyArchEntries(10); - ReadFat(false); -} - -TEST_F(FatReaderTest, HeaderTooShort) { - EXPECT_CALL(reporter, TooShort()).Times(1); - fat - .B32(0xcafebabe); // magic number - ReadFat(false); -} - -TEST_F(FatReaderTest, ObjectListTooShort) { - EXPECT_CALL(reporter, TooShort()).Times(1); - fat - .B32(0xcafebabe) // magic number - .B32(10); // number of architectures - AppendDummyArchEntries(9); // nine dummy architecture entries... - fat // and a tenth, missing a byte at the end - .B32(0x3d46c8fc) // cpu type - .B32(0x8a7bfb01) // cpu subtype - .B32(0) // offset - .B32(0) // size - .Append(3, '*'); // one byte short of a four-byte alignment - ReadFat(false); -} - -TEST_F(FatReaderTest, DataTooShort) { - EXPECT_CALL(reporter, MisplacedObjectFile()).Times(1); - Label arch_data; - fat - .B32(0xcafebabe) // magic number - .B32(1); // number of architectures - AppendFatArch(0xb4d4a366, 0x4ba4f525, arch_data, 40, 0); - fat - .Mark(&arch_data) // file data begins here - .Append(30, '*'); // only 30 bytes, not 40 as header claims - ReadFat(false); -} - -TEST_F(FatReaderTest, NoObjectFiles) { - fat - .B32(0xcafebabe) // magic number - .B32(0); // number of architectures - ReadFat(); - EXPECT_EQ(0U, object_files.size()); -} - -TEST_F(FatReaderTest, OneObjectFile) { - Label obj1_offset; - fat - .B32(0xcafebabe) // magic number - .B32(1); // number of architectures - // First object file list entry - AppendFatArch(0x5e3a6e91, 0x52ccd852, obj1_offset, 0x42, 0x355b15b2); - // First object file data - fat - .Mark(&obj1_offset) - .Append(0x42, '*'); // dummy contents - ReadFat(); - ASSERT_EQ(1U, object_files.size()); - EXPECT_EQ(0x5e3a6e91, object_files[0].cputype); - EXPECT_EQ(0x52ccd852, object_files[0].cpusubtype); - EXPECT_EQ(obj1_offset.Value(), object_files[0].offset); - EXPECT_EQ(0x42U, object_files[0].size); - EXPECT_EQ(0x355b15b2U, object_files[0].align); -} - -TEST_F(FatReaderTest, ThreeObjectFiles) { - Label obj1, obj2, obj3; - fat - .B32(0xcafebabe) // magic number - .B32(3); // number of architectures - // Three object file list entries. - AppendFatArch(0x0cb92c30, 0x6a159a71, obj1, 0xfb4, 0x2615dbe8); - AppendFatArch(0x0f3f1cbb, 0x6c55e90f, obj2, 0xc31, 0x83af6ffd); - AppendFatArch(0x3717276d, 0x10ecdc84, obj3, 0x4b3, 0x035267d7); - fat - // First object file data - .Mark(&obj1) - .Append(0xfb4, '*') // dummy contents - // Second object file data - .Mark(&obj2) - .Append(0xc31, '%') // dummy contents - // Third object file data - .Mark(&obj3) - .Append(0x4b3, '^'); // dummy contents - - ReadFat(); - - ASSERT_EQ(3U, object_files.size()); - - // First object file. - EXPECT_EQ(0x0cb92c30, object_files[0].cputype); - EXPECT_EQ(0x6a159a71, object_files[0].cpusubtype); - EXPECT_EQ(obj1.Value(), object_files[0].offset); - EXPECT_EQ(0xfb4U, object_files[0].size); - EXPECT_EQ(0x2615dbe8U, object_files[0].align); - - // Second object file. - EXPECT_EQ(0x0f3f1cbb, object_files[1].cputype); - EXPECT_EQ(0x6c55e90f, object_files[1].cpusubtype); - EXPECT_EQ(obj2.Value(), object_files[1].offset); - EXPECT_EQ(0xc31U, object_files[1].size); - EXPECT_EQ(0x83af6ffdU, object_files[1].align); - - // Third object file. - EXPECT_EQ(0x3717276d, object_files[2].cputype); - EXPECT_EQ(0x10ecdc84, object_files[2].cpusubtype); - EXPECT_EQ(obj3.Value(), object_files[2].offset); - EXPECT_EQ(0x4b3U, object_files[2].size); - EXPECT_EQ(0x035267d7U, object_files[2].align); -} - -TEST_F(FatReaderTest, BigEndianMachO32) { - fat.set_endianness(kBigEndian); - fat - .D32(0xfeedface) // Mach-O file magic number - .D32(0x1a9d0518) // cpu type - .D32(0x1b779357) // cpu subtype - .D32(0x009df67e) // file type - .D32(0) // no load commands - .D32(0) // the load commands occupy no bytes - .D32(0x21987a99); // flags - - ReadFat(); - - // FatReader should treat a Mach-O file as if it were a fat binary file - // containing one object file --- the whole thing. - ASSERT_EQ(1U, object_files.size()); - EXPECT_EQ(0x1a9d0518, object_files[0].cputype); - EXPECT_EQ(0x1b779357, object_files[0].cpusubtype); - EXPECT_EQ(0U, object_files[0].offset); - EXPECT_EQ(contents.size(), object_files[0].size); -} - -TEST_F(FatReaderTest, BigEndianMachO64) { - fat.set_endianness(kBigEndian); - fat - .D32(0xfeedfacf) // Mach-O 64-bit file magic number - .D32(0x5aff8487) // cpu type - .D32(0x4c6a57f7) // cpu subtype - .D32(0x4392d2c8) // file type - .D32(0) // no load commands - .D32(0) // the load commands occupy no bytes - .D32(0x1b033eea); // flags - - ReadFat(); - - // FatReader should treat a Mach-O file as if it were a fat binary file - // containing one object file --- the whole thing. - ASSERT_EQ(1U, object_files.size()); - EXPECT_EQ(0x5aff8487, object_files[0].cputype); - EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype); - EXPECT_EQ(0U, object_files[0].offset); - EXPECT_EQ(contents.size(), object_files[0].size); -} - -TEST_F(FatReaderTest, LittleEndianMachO32) { - fat.set_endianness(kLittleEndian); - fat - .D32(0xfeedface) // Mach-O file magic number - .D32(0x1a9d0518) // cpu type - .D32(0x1b779357) // cpu subtype - .D32(0x009df67e) // file type - .D32(0) // no load commands - .D32(0) // the load commands occupy no bytes - .D32(0x21987a99); // flags - - ReadFat(); - - // FatReader should treat a Mach-O file as if it were a fat binary file - // containing one object file --- the whole thing. - ASSERT_EQ(1U, object_files.size()); - EXPECT_EQ(0x1a9d0518, object_files[0].cputype); - EXPECT_EQ(0x1b779357, object_files[0].cpusubtype); - EXPECT_EQ(0U, object_files[0].offset); - EXPECT_EQ(contents.size(), object_files[0].size); -} - -TEST_F(FatReaderTest, LittleEndianMachO64) { - fat.set_endianness(kLittleEndian); - fat - .D32(0xfeedfacf) // Mach-O 64-bit file magic number - .D32(0x5aff8487) // cpu type - .D32(0x4c6a57f7) // cpu subtype - .D32(0x4392d2c8) // file type - .D32(0) // no load commands - .D32(0) // the load commands occupy no bytes - .D32(0x1b033eea); // flags - - ReadFat(); - - // FatReader should treat a Mach-O file as if it were a fat binary file - // containing one object file --- the whole thing. - ASSERT_EQ(1U, object_files.size()); - EXPECT_EQ(0x5aff8487, object_files[0].cputype); - EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype); - EXPECT_EQ(0U, object_files[0].offset); - EXPECT_EQ(contents.size(), object_files[0].size); -} - -TEST_F(FatReaderTest, IncompleteMach) { - fat.set_endianness(kLittleEndian); - fat - .D32(0xfeedfacf) // Mach-O 64-bit file magic number - .D32(0x5aff8487); // cpu type - // Truncated! - - EXPECT_CALL(reporter, TooShort()).WillOnce(Return()); - - ReadFat(false); -} - - -// General mach_o::Reader tests. - -// Dynamically scoped configuration data. -class WithConfiguration { - public: - // Establish the given parameters as the default for SizedSections - // created within the dynamic scope of this instance. - WithConfiguration(Endianness endianness, size_t word_size) - : endianness_(endianness), word_size_(word_size), saved_(current_) { - current_ = this; - } - ~WithConfiguration() { current_ = saved_; } - static Endianness endianness() { - assert(current_); - return current_->endianness_; - } - static size_t word_size() { - assert(current_); - return current_->word_size_; - } - - private: - // The innermost WithConfiguration in whose dynamic scope we are - // currently executing. - static WithConfiguration *current_; - - // The innermost WithConfiguration whose dynamic scope encloses this - // WithConfiguration. - Endianness endianness_; - size_t word_size_; - WithConfiguration *saved_; -}; - -WithConfiguration *WithConfiguration::current_ = NULL; - -// A test_assembler::Section with a size that we can cite. The start(), -// Here() and Mark() member functions of a SizedSection always represent -// offsets within the overall file. -class SizedSection: public test_assembler::Section { - public: - // Construct a section of the given endianness and word size. - explicit SizedSection(Endianness endianness, size_t word_size) - : test_assembler::Section(endianness), word_size_(word_size) { - assert(word_size_ == 32 || word_size_ == 64); - } - SizedSection() - : test_assembler::Section(WithConfiguration::endianness()), - word_size_(WithConfiguration::word_size()) { - assert(word_size_ == 32 || word_size_ == 64); - } - - // Access/set this section's word size. - size_t word_size() const { return word_size_; } - void set_word_size(size_t word_size) { - assert(word_size_ == 32 || word_size_ == 64); - word_size_ = word_size; - } - - // Return a label representing the size this section will have when it - // is Placed in some containing section. - Label final_size() const { return final_size_; } - - // Append SECTION to the end of this section, and call its Finish member. - // Return a reference to this section. - SizedSection &Place(SizedSection *section) { - assert(section->endianness() == endianness()); - section->Finish(); - section->start() = Here(); - test_assembler::Section::Append(*section); - return *this; - } - - protected: - // Mark this section's contents as complete. For plain SizedSections, we - // set SECTION's start to its position in this section, and its final_size - // label to its current size. Derived classes can extend this as needed - // for their additional semantics. - virtual void Finish() { - final_size_ = Size(); - } - - // The word size for this data: either 32 or 64. - size_t word_size_; - - private: - // This section's final size, set when we are placed in some other - // SizedSection. - Label final_size_; -}; - -// A SizedSection that is loaded into memory at a particular address. -class LoadedSection: public SizedSection { - public: - explicit LoadedSection(Label address = Label()) : address_(address) { } - - // Return a label representing this section's address. - Label address() const { return address_; } - - // Placing a loaded section within a loaded section sets the relationship - // between their addresses. - LoadedSection &Place(LoadedSection *section) { - section->address() = address() + Size(); - SizedSection::Place(section); - return *this; - } - - protected: - // The address at which this section's contents will be loaded. - Label address_; -}; - -// A SizedSection representing a segment load command. -class SegmentLoadCommand: public SizedSection { - public: - SegmentLoadCommand() : section_count_(0) { } - - // Append a segment load command header with the given characteristics. - // The load command will refer to CONTENTS, which must be Placed in the - // file separately, at the desired position. Return a reference to this - // section. - SegmentLoadCommand &Header(const string &name, const LoadedSection &contents, - uint32_t maxprot, uint32_t initprot, - uint32_t flags) { - assert(contents.word_size() == word_size()); - D32(word_size() == 32 ? LC_SEGMENT : LC_SEGMENT_64); - D32(final_size()); - AppendCString(name, 16); - Append(endianness(), word_size() / 8, contents.address()); - Append(endianness(), word_size() / 8, vmsize_); - Append(endianness(), word_size() / 8, contents.start()); - Append(endianness(), word_size() / 8, contents.final_size()); - D32(maxprot); - D32(initprot); - D32(final_section_count_); - D32(flags); - - content_final_size_ = contents.final_size(); - - return *this; - } - - // Return a label representing the size of this segment when loaded into - // memory. If this label is still undefined by the time we place this - // segment, it defaults to the final size of the segment's in-file - // contents. Return a reference to this load command. - Label &vmsize() { return vmsize_; } - - // Add a section entry with the given characteristics to this segment - // load command. Return a reference to this. The section entry will refer - // to CONTENTS, which must be Placed in the segment's contents - // separately, at the desired position. - SegmentLoadCommand &AppendSectionEntry(const string §ion_name, - const string &segment_name, - uint32_t alignment, uint32_t flags, - const LoadedSection &contents) { - AppendCString(section_name, 16); - AppendCString(segment_name, 16); - Append(endianness(), word_size() / 8, contents.address()); - Append(endianness(), word_size() / 8, contents.final_size()); - D32(contents.start()); - D32(alignment); - D32(0); // relocations start - D32(0); // relocations size - D32(flags); - D32(0x93656b95); // reserved1 - D32(0xc35a2473); // reserved2 - if (word_size() == 64) - D32(0x70284b95); // reserved3 - - section_count_++; - - return *this; - } - - protected: - void Finish() { - final_section_count_ = section_count_; - if (!vmsize_.IsKnownConstant()) - vmsize_ = content_final_size_; - SizedSection::Finish(); - } - - private: - // The number of sections that have been added to this segment so far. - size_t section_count_; - - // A label representing the final number of sections this segment will hold. - Label final_section_count_; - - // The size of the contents for this segment present in the file. - Label content_final_size_; - - // A label representing the size of this segment when loaded; this can be - // larger than the size of its file contents, the difference being - // zero-filled. If not set explicitly by calling set_vmsize, this is set - // equal to the size of the contents. - Label vmsize_; -}; - -// A SizedSection holding a list of Mach-O load commands. -class LoadCommands: public SizedSection { - public: - LoadCommands() : command_count_(0) { } - - // Return a label representing the final load command count. - Label final_command_count() const { return final_command_count_; } - - // Increment the command count; return a reference to this section. - LoadCommands &CountCommand() { - command_count_++; - return *this; - } - - // Place COMMAND, containing a load command, at the end of this section. - // Return a reference to this section. - LoadCommands &Place(SizedSection *section) { - SizedSection::Place(section); - CountCommand(); - return *this; - } - - protected: - // Mark this load command list as complete. - void Finish() { - SizedSection::Finish(); - final_command_count_ = command_count_; - } - - private: - // The number of load commands we have added to this file so far. - size_t command_count_; - - // A label representing the final command count. - Label final_command_count_; -}; - -// A SizedSection holding the contents of a Mach-O file. Within a -// MachOFile, the start, Here, and Mark members refer to file offsets. -class MachOFile: public SizedSection { - public: - MachOFile() { - start() = 0; - } - - // Create a Mach-O file header using the given characteristics and load - // command list. This Places COMMANDS immediately after the header. - // Return a reference to this section. - MachOFile &Header(LoadCommands *commands, - cpu_type_t cpu_type = CPU_TYPE_X86, - cpu_subtype_t cpu_subtype = CPU_SUBTYPE_I386_ALL, - FileType file_type = MH_EXECUTE, - uint32_t file_flags = (MH_TWOLEVEL | - MH_DYLDLINK | - MH_NOUNDEFS)) { - D32(word_size() == 32 ? 0xfeedface : 0xfeedfacf); // magic number - D32(cpu_type); // cpu type - D32(cpu_subtype); // cpu subtype - D32(file_type); // file type - D32(commands->final_command_count()); // number of load commands - D32(commands->final_size()); // their size in bytes - D32(file_flags); // flags - if (word_size() == 64) - D32(0x55638b90); // reserved - Place(commands); - return *this; - } -}; - - -struct ReaderFixture { - ReaderFixture() - : reporter("reporter filename"), - reader(&reporter) { - EXPECT_CALL(reporter, BadHeader()).Times(0); - EXPECT_CALL(reporter, CPUTypeMismatch(_, _, _, _)).Times(0); - EXPECT_CALL(reporter, HeaderTruncated()).Times(0); - EXPECT_CALL(reporter, LoadCommandRegionTruncated()).Times(0); - EXPECT_CALL(reporter, LoadCommandsOverrun(_, _, _)).Times(0); - EXPECT_CALL(reporter, LoadCommandTooShort(_, _)).Times(0); - EXPECT_CALL(reporter, SectionsMissing(_)).Times(0); - EXPECT_CALL(reporter, MisplacedSegmentData(_)).Times(0); - EXPECT_CALL(reporter, MisplacedSectionData(_, _)).Times(0); - EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(0); - EXPECT_CALL(reporter, UnsupportedCPUType(_)).Times(0); - - EXPECT_CALL(load_command_handler, UnknownCommand(_, _)).Times(0); - EXPECT_CALL(load_command_handler, SegmentCommand(_)).Times(0); - } - - void ReadFile(MachOFile *file, - bool expect_parse_success, - cpu_type_t expected_cpu_type, - cpu_subtype_t expected_cpu_subtype) { - ASSERT_TRUE(file->GetContents(&file_contents)); - file_bytes = reinterpret_cast(file_contents.data()); - if (expect_parse_success) { - EXPECT_TRUE(reader.Read(file_bytes, - file_contents.size(), - expected_cpu_type, - expected_cpu_subtype)); - } else { - EXPECT_FALSE(reader.Read(file_bytes, - file_contents.size(), - expected_cpu_type, - expected_cpu_subtype)); - } - } - - string file_contents; - const uint8_t *file_bytes; - MockReaderReporter reporter; - Reader reader; - MockLoadCommandHandler load_command_handler; - MockSectionHandler section_handler; -}; - -class ReaderTest: public ReaderFixture, public Test { }; - -TEST_F(ReaderTest, BadMagic) { - WithConfiguration config(kLittleEndian, 32); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0x67bdebe1) // Not a proper magic number. - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - EXPECT_CALL(reporter, BadHeader()).WillOnce(Return()); - ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); -} - -TEST_F(ReaderTest, MismatchedMagic) { - WithConfiguration config(kLittleEndian, 32); - const cpu_type_t kCPUType = CPU_TYPE_I386; - const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL; - MachOFile file; - file - .D32(MH_CIGAM) // Right magic, but winds up wrong - // due to bitswapping - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - EXPECT_CALL(reporter, BadHeader()).WillOnce(Return()); - ReadFile(&file, false, kCPUType, kCPUSubType); -} - -TEST_F(ReaderTest, ShortMagic) { - WithConfiguration config(kBigEndian, 32); - MachOFile file; - file - .D16(0xfeed); // magic number - // truncated! - EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return()); - ReadFile(&file, false, CPU_TYPE_ANY, 0); -} - -TEST_F(ReaderTest, ShortHeader) { - WithConfiguration config(kBigEndian, 32); - const cpu_type_t kCPUType = CPU_TYPE_ANY; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedface) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0); // they occupy no bytes - EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return()); - ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); -} - -TEST_F(ReaderTest, MismatchedCPU) { - WithConfiguration config(kBigEndian, 32); - const cpu_type_t kCPUType = CPU_TYPE_I386; - const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL; - MachOFile file; - file - .D32(MH_MAGIC) // Right magic for PPC (once bitswapped) - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - EXPECT_CALL(reporter, - CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, - CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL)) - .WillOnce(Return()); - ReadFile(&file, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL); -} - -TEST_F(ReaderTest, LittleEndian32Bit) { - WithConfiguration config(kLittleEndian, 32); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedface) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); - EXPECT_FALSE(reader.bits_64()); - EXPECT_FALSE(reader.big_endian()); - EXPECT_EQ(kCPUType, reader.cpu_type()); - EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); - EXPECT_EQ(FileType(0x149fc717), reader.file_type()); - EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); -} - -TEST_F(ReaderTest, LittleEndian64Bit) { - WithConfiguration config(kLittleEndian, 64); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedfacf) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); - EXPECT_TRUE(reader.bits_64()); - EXPECT_FALSE(reader.big_endian()); - EXPECT_EQ(kCPUType, reader.cpu_type()); - EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); - EXPECT_EQ(FileType(0x149fc717), reader.file_type()); - EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); -} - -TEST_F(ReaderTest, BigEndian32Bit) { - WithConfiguration config(kBigEndian, 32); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedface) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); - EXPECT_FALSE(reader.bits_64()); - EXPECT_TRUE(reader.big_endian()); - EXPECT_EQ(kCPUType, reader.cpu_type()); - EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); - EXPECT_EQ(FileType(0x149fc717), reader.file_type()); - EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); -} - -TEST_F(ReaderTest, BigEndian64Bit) { - WithConfiguration config(kBigEndian, 64); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedfacf) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(0) // no load commands - .D32(0) // they occupy no bytes - .D32(0x80e71d64) // flags - .D32(0); // reserved - ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); - EXPECT_TRUE(reader.bits_64()); - EXPECT_TRUE(reader.big_endian()); - EXPECT_EQ(kCPUType, reader.cpu_type()); - EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); - EXPECT_EQ(FileType(0x149fc717), reader.file_type()); - EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); -} - - -// Load command tests. - -class LoadCommand: public ReaderFixture, public Test { }; - -TEST_F(LoadCommand, RegionTruncated) { - WithConfiguration config(kBigEndian, 64); - const cpu_type_t kCPUType = 0x46b760df; - const cpu_subtype_t kCPUSubType = 0x76a0e7f7; - MachOFile file; - file - .D32(0xfeedfacf) // magic number - .D32(kCPUType) // cpu type - .D32(kCPUSubType) // cpu subtype - .D32(0x149fc717) // file type - .D32(1) // one load command - .D32(40) // occupying 40 bytes - .D32(0x80e71d64) // flags - .D32(0) // reserved - .Append(20, 0); // load command region, not as long as - // Mach-O header promised - - EXPECT_CALL(reporter, LoadCommandRegionTruncated()).WillOnce(Return()); - - ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); -} - -TEST_F(LoadCommand, None) { - WithConfiguration config(kLittleEndian, 32); - LoadCommands load_commands; - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_X86, CPU_SUBTYPE_I386_ALL); - - EXPECT_FALSE(reader.bits_64()); - EXPECT_FALSE(reader.big_endian()); - EXPECT_EQ(CPU_TYPE_X86, reader.cpu_type()); - EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype()); - EXPECT_EQ(static_cast(MH_EXECUTE), reader.file_type()); - EXPECT_EQ(FileFlags(MH_TWOLEVEL | - MH_DYLDLINK | - MH_NOUNDEFS), - FileFlags(reader.flags())); - - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, Unknown) { - WithConfiguration config(kBigEndian, 32); - LoadCommands load_commands; - load_commands - .CountCommand() - .D32(0x33293d4a) // unknown load command - .D32(40) // total size in bytes - .Append(32, '*'); // dummy data - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_FALSE(reader.bits_64()); - EXPECT_TRUE(reader.big_endian()); - EXPECT_EQ(CPU_TYPE_X86, reader.cpu_type()); - EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype()); - EXPECT_EQ(static_cast(MH_EXECUTE), reader.file_type()); - EXPECT_EQ(FileFlags(MH_TWOLEVEL | - MH_DYLDLINK | - MH_NOUNDEFS), - reader.flags()); - - ByteBuffer expected; - expected.start = file_bytes + load_commands.start().Value(); - expected.end = expected.start + load_commands.final_size().Value(); - EXPECT_CALL(load_command_handler, UnknownCommand(0x33293d4a, - expected)) - .WillOnce(Return(true)); - - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, TypeIncomplete) { - WithConfiguration config(kLittleEndian, 32); - LoadCommands load_commands; - load_commands - .CountCommand() - .Append(3, 0); // load command type, incomplete - - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, 0)) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, LengthIncomplete) { - WithConfiguration config(kBigEndian, 64); - LoadCommands load_commands; - load_commands - .CountCommand() - .D32(LC_SEGMENT); // load command - // no length - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT)) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, ContentIncomplete) { - WithConfiguration config(kLittleEndian, 64); - LoadCommands load_commands; - load_commands - .CountCommand() - .D32(LC_SEGMENT) // load command - .D32(40) // total size in bytes - .Append(28, '*'); // not enough dummy data - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT)) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, SegmentBE32) { - WithConfiguration config(kBigEndian, 32); - LoadedSection segment; - segment.address() = 0x1891139c; - segment.Append(42, '*'); // segment contents - SegmentLoadCommand segment_command; - segment_command - .Header("froon", segment, 0x94d6dd22, 0x8bdbc319, 0x990a16dd); - segment_command.vmsize() = 0xcb76584fU; - LoadCommands load_commands; - load_commands.Place(&segment_command); - MachOFile file; - file - .Header(&load_commands) - .Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_CALL(load_command_handler, SegmentCommand(_)) - .WillOnce(DoAll(SaveArg<0>(&actual_segment), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(false, actual_segment.bits_64); - EXPECT_EQ("froon", actual_segment.name); - EXPECT_EQ(0x1891139cU, actual_segment.vmaddr); - EXPECT_EQ(0xcb76584fU, actual_segment.vmsize); - EXPECT_EQ(0x94d6dd22U, actual_segment.maxprot); - EXPECT_EQ(0x8bdbc319U, actual_segment.initprot); - EXPECT_EQ(0x990a16ddU, actual_segment.flags); - EXPECT_EQ(0U, actual_segment.nsects); - EXPECT_EQ(0U, actual_segment.section_list.Size()); - EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); -} - -TEST_F(LoadCommand, SegmentLE32) { - WithConfiguration config(kLittleEndian, 32); - LoadedSection segment; - segment.address() = 0x4b877866; - segment.Append(42, '*'); // segment contents - SegmentLoadCommand segment_command; - segment_command - .Header("sixteenprecisely", segment, - 0x350759ed, 0x6cf5a62e, 0x990a16dd); - segment_command.vmsize() = 0xcb76584fU; - LoadCommands load_commands; - load_commands.Place(&segment_command); - MachOFile file; - file - .Header(&load_commands) - .Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_CALL(load_command_handler, SegmentCommand(_)) - .WillOnce(DoAll(SaveArg<0>(&actual_segment), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(false, actual_segment.bits_64); - EXPECT_EQ("sixteenprecisely", actual_segment.name); - EXPECT_EQ(0x4b877866U, actual_segment.vmaddr); - EXPECT_EQ(0xcb76584fU, actual_segment.vmsize); - EXPECT_EQ(0x350759edU, actual_segment.maxprot); - EXPECT_EQ(0x6cf5a62eU, actual_segment.initprot); - EXPECT_EQ(0x990a16ddU, actual_segment.flags); - EXPECT_EQ(0U, actual_segment.nsects); - EXPECT_EQ(0U, actual_segment.section_list.Size()); - EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); -} - -TEST_F(LoadCommand, SegmentBE64) { - WithConfiguration config(kBigEndian, 64); - LoadedSection segment; - segment.address() = 0x79f484f77009e511ULL; - segment.Append(42, '*'); // segment contents - SegmentLoadCommand segment_command; - segment_command - .Header("froon", segment, 0x42b45da5, 0x8bdbc319, 0xb2335220); - segment_command.vmsize() = 0x8d92397ce6248abaULL; - LoadCommands load_commands; - load_commands.Place(&segment_command); - MachOFile file; - file - .Header(&load_commands) - .Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_CALL(load_command_handler, SegmentCommand(_)) - .WillOnce(DoAll(SaveArg<0>(&actual_segment), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(true, actual_segment.bits_64); - EXPECT_EQ("froon", actual_segment.name); - EXPECT_EQ(0x79f484f77009e511ULL, actual_segment.vmaddr); - EXPECT_EQ(0x8d92397ce6248abaULL, actual_segment.vmsize); - EXPECT_EQ(0x42b45da5U, actual_segment.maxprot); - EXPECT_EQ(0x8bdbc319U, actual_segment.initprot); - EXPECT_EQ(0xb2335220U, actual_segment.flags); - EXPECT_EQ(0U, actual_segment.nsects); - EXPECT_EQ(0U, actual_segment.section_list.Size()); - EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); -} - -TEST_F(LoadCommand, SegmentLE64) { - WithConfiguration config(kLittleEndian, 64); - LoadedSection segment; - segment.address() = 0x50c0501dc5922d35ULL; - segment.Append(42, '*'); // segment contents - SegmentLoadCommand segment_command; - segment_command - .Header("sixteenprecisely", segment, - 0x917c339d, 0xdbc446fa, 0xb650b563); - segment_command.vmsize() = 0x84ae73e7c75469bfULL; - LoadCommands load_commands; - load_commands.Place(&segment_command); - MachOFile file; - file - .Header(&load_commands) - .Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_CALL(load_command_handler, SegmentCommand(_)) - .WillOnce(DoAll(SaveArg<0>(&actual_segment), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(true, actual_segment.bits_64); - EXPECT_EQ("sixteenprecisely", actual_segment.name); - EXPECT_EQ(0x50c0501dc5922d35ULL, actual_segment.vmaddr); - EXPECT_EQ(0x84ae73e7c75469bfULL, actual_segment.vmsize); - EXPECT_EQ(0x917c339dU, actual_segment.maxprot); - EXPECT_EQ(0xdbc446faU, actual_segment.initprot); - EXPECT_EQ(0xb650b563U, actual_segment.flags); - EXPECT_EQ(0U, actual_segment.nsects); - EXPECT_EQ(0U, actual_segment.section_list.Size()); - EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); -} - -TEST_F(LoadCommand, SegmentCommandTruncated) { - WithConfiguration config(kBigEndian, 32); - LoadedSection segment_contents; - segment_contents.Append(20, '*'); // lah di dah - SizedSection command; - command - .D32(LC_SEGMENT) // command type - .D32(command.final_size()) // command size - .AppendCString("too-short", 16) // segment name - .D32(0x9c759211) // vmaddr - .D32(segment_contents.final_size()) // vmsize - .D32(segment_contents.start()) // file offset - .D32(segment_contents.final_size()) // file size - .D32(0x56f28446) // max protection - .D32(0xe7910dcb) // initial protection - .D32(0) // no sections - .Append(3, 0); // flags (one byte short!) - LoadCommands load_commands; - load_commands.Place(&command); - MachOFile file; - file - .Header(&load_commands) - .Place(&segment_contents); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, LoadCommandTooShort(0, LC_SEGMENT)) - .WillOnce(Return()); - - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, SegmentBadContentOffset) { - WithConfiguration config(kLittleEndian, 32); - // Instead of letting a Place call set the segment's file offset and size, - // set them ourselves, to check that the parser catches invalid offsets - // instead of handing us bogus pointers. - LoadedSection segment; - segment.address() = 0x4db5489c; - segment.start() = 0x7e189e76; // beyond end of file - segment.final_size() = 0x98b9c3ab; - SegmentLoadCommand segment_command; - segment_command - .Header("notmerelyfifteen", segment, 0xcbab25ee, 0x359a20db, 0x68a3933f); - LoadCommands load_commands; - load_commands.Place(&segment_command); - MachOFile file; - file.Header(&load_commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, MisplacedSegmentData("notmerelyfifteen")) - .WillOnce(Return()); - - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(LoadCommand, ThreeLoadCommands) { - WithConfiguration config(kBigEndian, 32); - LoadedSection seg1, seg2, seg3; - SegmentLoadCommand cmd1, cmd2, cmd3; - - seg1.Append(128, '@'); - seg1.address() = 0xa7f61ef6; - cmd1.Header("head", seg1, 0x88bf1cc7, 0x889a26a4, 0xe9b80d87); - // Include some dummy data at the end of the load command. Since we - // didn't claim to have any sections, the reader should ignore this. But - // making sure the commands have different lengths ensures that we're - // using the right command's length to advance the LoadCommandIterator. - cmd1.Append(128, '!'); - - seg2.Append(42, '*'); - seg2.address() = 0xc70fc909; - cmd2.Header("thorax", seg2, 0xde7327f4, 0xfdaf771d, 0x65e74b30); - // More dummy data at the end of the load command. - cmd2.Append(32, '^'); - - seg3.Append(42, '%'); - seg3.address() = 0x46b3ab05; - cmd3.Header("abdomen", seg3, 0x7098b70d, 0x8d8d7728, 0x5131419b); - // More dummy data at the end of the load command. - cmd3.Append(64, '&'); - - LoadCommands load_commands; - load_commands.Place(&cmd1).Place(&cmd2).Place(&cmd3); - - MachOFile file; - file.Header(&load_commands).Place(&seg1).Place(&seg2).Place(&seg3); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - { - InSequence s; - EXPECT_CALL(load_command_handler, - SegmentCommand(Field(&Segment::name, "head"))) - .WillOnce(Return(true)); - EXPECT_CALL(load_command_handler, - SegmentCommand(Field(&Segment::name, "thorax"))) - .WillOnce(Return(true)); - EXPECT_CALL(load_command_handler, - SegmentCommand(Field(&Segment::name, "abdomen"))) - .WillOnce(Return(true)); - } - - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); -} - -static inline Matcher MatchSection( - Matcher bits_64, - Matcher section_name, - Matcher segment_name, - Matcher address, - Matcher alignment, - Matcher flags, - Matcher contents) { - return AllOf(AllOf(Field(&Section::bits_64, bits_64), - Field(&Section::section_name, section_name), - Field(&Section::segment_name, segment_name), - Field(&Section::address, address)), - AllOf(Field(&Section::align, alignment), - Field(&Section::flags, flags), - Field(&Section::contents, contents))); -} - -static inline Matcher MatchSection( - Matcher bits_64, - Matcher section_name, - Matcher segment_name, - Matcher address) { - return AllOf(Field(&Section::bits_64, bits_64), - Field(&Section::section_name, section_name), - Field(&Section::segment_name, segment_name), - Field(&Section::address, address)); -} - -TEST_F(LoadCommand, OneSegmentTwoSections) { - WithConfiguration config(kBigEndian, 64); - - // Create some sections with some data. - LoadedSection section1, section2; - section1.Append("buddha's hand"); - section2.Append("kumquat"); - - // Create a segment to hold them. - LoadedSection segment; - segment.address() = 0xe1d0eeec; - segment.Place(§ion2).Place(§ion1); - - SegmentLoadCommand segment_command; - segment_command - .Header("head", segment, 0x92c9568c, 0xa89f2627, 0x4dc7a1e2) - .AppendSectionEntry("mandarin", "kishu", 12, 0x8cd4604bU, section1) - .AppendSectionEntry("bergamot", "cara cara", 12, 0x98746efaU, section2); - - LoadCommands commands; - commands.Place(&segment_command); - - MachOFile file; - file.Header(&commands).Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_CALL(load_command_handler, SegmentCommand(_)) - .WillOnce(DoAll(SaveArg<0>(&actual_segment), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - { - InSequence s; - ByteBuffer contents1; - contents1.start = file_bytes + section1.start().Value(); - contents1.end = contents1.start + section1.final_size().Value(); - EXPECT_EQ("buddha's hand", - string(reinterpret_cast(contents1.start), - contents1.Size())); - EXPECT_CALL(section_handler, - HandleSection(MatchSection(true, "mandarin", "kishu", - section1.address().Value(), 12, - 0x8cd4604bU, contents1))) - .WillOnce(Return(true)); - - ByteBuffer contents2; - contents2.start = file_bytes + section2.start().Value(); - contents2.end = contents2.start + section2.final_size().Value(); - EXPECT_EQ("kumquat", - string(reinterpret_cast(contents2.start), - contents2.Size())); - EXPECT_CALL(section_handler, - HandleSection(MatchSection(true, "bergamot", "cara cara", - section2.address().Value(), 12, - 0x98746efaU, contents2))) - .WillOnce(Return(true)); - } - - EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, §ion_handler)); -} - -TEST_F(LoadCommand, MisplacedSectionBefore) { - WithConfiguration config(kLittleEndian, 64); - - // The segment. - LoadedSection segment; - segment.address() = 0x696d83cc; - segment.Append(10, '0'); - - // The contents of the following sections don't matter, because - // we're not really going to Place them in segment; we're just going - // to set all their labels by hand to get the (impossible) - // configurations we want. - - // A section whose starting offset is before that of its section. - LoadedSection before; - before.Append(10, '1'); - before.start() = segment.start() - 1; - before.address() = segment.address() - 1; - before.final_size() = before.Size(); - - SegmentLoadCommand command; - command - .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) - .AppendSectionEntry("before", "segment", 0, 0x686c6921, before); - - LoadCommands commands; - commands.Place(&command); - - MachOFile file; - file.Header(&commands).Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); - - EXPECT_CALL(reporter, MisplacedSectionData("before", "segment")) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); -} - -TEST_F(LoadCommand, MisplacedSectionAfter) { - WithConfiguration config(kLittleEndian, 64); - - // The segment. - LoadedSection segment; - segment.address() = 0x696d83cc; - segment.Append(10, '0'); - - // The contents of the following sections don't matter, because - // we're not really going to Place them in segment; we're just going - // to set all their labels by hand to get the (impossible) - // configurations we want. - - // A section whose starting offset is after the end of its section. - LoadedSection after; - after.Append(10, '2'); - after.start() = segment.start() + 11; - after.address() = segment.address() + 11; - after.final_size() = after.Size(); - - SegmentLoadCommand command; - command - .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) - .AppendSectionEntry("after", "segment", 0, 0x2ee50124, after); - - LoadCommands commands; - commands.Place(&command); - - MachOFile file; - file.Header(&commands).Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); - - EXPECT_CALL(reporter, MisplacedSectionData("after", "segment")) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); -} - -TEST_F(LoadCommand, MisplacedSectionTooBig) { - WithConfiguration config(kLittleEndian, 64); - - // The segment. - LoadedSection segment; - segment.address() = 0x696d83cc; - segment.Append(10, '0'); - - // The contents of the following sections don't matter, because - // we're not really going to Place them in segment; we're just going - // to set all their labels by hand to get the (impossible) - // configurations we want. - - // A section that extends beyond the end of its section. - LoadedSection too_big; - too_big.Append(10, '3'); - too_big.start() = segment.start() + 1; - too_big.address() = segment.address() + 1; - too_big.final_size() = too_big.Size(); - - SegmentLoadCommand command; - command - .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) - .AppendSectionEntry("too big", "segment", 0, 0x8b53ae5c, too_big); - - LoadCommands commands; - commands.Place(&command); - - MachOFile file; - file.Header(&commands).Place(&segment); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); - - EXPECT_CALL(reporter, MisplacedSectionData("too big", "segment")) - .WillOnce(Return()); - EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); -} - - -// The segments in a .dSYM bundle's Mach-O file have their file offset -// and size set to zero, but the sections don't. The reader shouldn't -// report an error in this case. -TEST_F(LoadCommand, ZappedSegment) { - WithConfiguration config(kBigEndian, 32); - - // The segment. - LoadedSection segment; - segment.address() = 0x696d83cc; - segment.start() = 0; - segment.final_size() = 0; - - // The section. - LoadedSection section; - section.address() = segment.address(); - section.start() = 0; - section.final_size() = 1000; // extends beyond its segment - - SegmentLoadCommand command; - command - .Header("zapped", segment, 0x0861a5cb, 0x68ccff67, 0x0b66255c) - .AppendSectionEntry("twitching", "zapped", 0, 0x93b3bd42, section); - - LoadCommands commands; - commands.Place(&command); - - MachOFile file; - file.Header(&commands); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - EXPECT_TRUE(reader.FindSegment("zapped", &actual_segment)); - - ByteBuffer zapped_extent(NULL, 0); - EXPECT_CALL(section_handler, - HandleSection(MatchSection(false, "twitching", "zapped", - 0x696d83cc, 0, 0x93b3bd42, - zapped_extent))) - .WillOnce(Return(true)); - - EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, §ion_handler)); -} - -TEST_F(LoadCommand, MapSegmentSections) { - WithConfiguration config(kLittleEndian, 32); - - // Create some sections with some data. - LoadedSection section1, section2, section3, section4; - section1.Append("buddha's hand"); - section2.start() = 0; // Section 2 is an S_ZEROFILL section. - section2.final_size() = 0; - section3.Append("shasta gold"); - section4.Append("satsuma"); - - // Create two segments to hold them. - LoadedSection segment1, segment2; - segment1.address() = 0x13e6c8a9; - segment1.Place(§ion3).Place(§ion1); - segment2.set_word_size(64); - segment2.address() = 0x04d462e2; - segment2.Place(§ion4); - section2.address() = segment2.address() + segment2.Size(); - - SegmentLoadCommand segment_command1, segment_command2; - segment_command1 - .Header("head", segment1, 0x67d955a6, 0x7a61c13e, 0xe3e50c64) - .AppendSectionEntry("mandarin", "head", 12, 0x5bb565d7, section1) - .AppendSectionEntry("bergamot", "head", 12, 0x8620de73, section3); - segment_command2.set_word_size(64); - segment_command2 - .Header("thorax", segment2, 0x7aab2419, 0xe908007f, 0x17961d33) - .AppendSectionEntry("sixteenprecisely", "thorax", - 12, S_ZEROFILL, section2) - .AppendSectionEntry("cara cara", "thorax", 12, 0xb6c5dd8a, section4); - - LoadCommands commands; - commands.Place(&segment_command1).Place(&segment_command2); - - MachOFile file; - file.Header(&commands).Place(&segment1).Place(&segment2); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment segment; - SectionMap section_map; - - EXPECT_FALSE(reader.FindSegment("smoot", &segment)); - - ASSERT_TRUE(reader.FindSegment("thorax", &segment)); - ASSERT_TRUE(reader.MapSegmentSections(segment, §ion_map)); - - EXPECT_FALSE(section_map.find("sixteenpreciselyandthensome") - != section_map.end()); - EXPECT_FALSE(section_map.find("mandarin") != section_map.end()); - ASSERT_TRUE(section_map.find("cara cara") != section_map.end()); - EXPECT_THAT(section_map["cara cara"], - MatchSection(true, "cara cara", "thorax", 0x04d462e2)); - ASSERT_TRUE(section_map.find("sixteenprecisely") - != section_map.end()); - ByteBuffer sixteenprecisely_contents(NULL, 0); - EXPECT_THAT(section_map["sixteenprecisely"], - MatchSection(true, "sixteenprecisely", "thorax", - 0x04d462e2 + 7, 12, S_ZEROFILL, - sixteenprecisely_contents)); - - ASSERT_TRUE(reader.FindSegment("head", &segment)); - ASSERT_TRUE(reader.MapSegmentSections(segment, §ion_map)); - - ASSERT_TRUE(section_map.find("mandarin") != section_map.end()); - EXPECT_THAT(section_map["mandarin"], - MatchSection(false, "mandarin", "head", 0x13e6c8a9 + 11)); - ASSERT_TRUE(section_map.find("bergamot") != section_map.end()); - EXPECT_THAT(section_map["bergamot"], - MatchSection(false, "bergamot", "head", 0x13e6c8a9)); -} - -TEST_F(LoadCommand, FindSegment) { - WithConfiguration config(kBigEndian, 32); - - LoadedSection segment1, segment2, segment3; - segment1.address() = 0xb8ae5752; - segment1.Append("Some contents!"); - segment2.address() = 0xd6b0ce83; - segment2.Append("Different stuff."); - segment3.address() = 0x7374fd2a; - segment3.Append("Further materials."); - - SegmentLoadCommand cmd1, cmd2, cmd3; - cmd1.Header("first", segment1, 0xfadb6932, 0x175bf529, 0x0de790ad); - cmd2.Header("second", segment2, 0xeef716e0, 0xe103a9d7, 0x7d38a8ef); - cmd3.Header("third", segment3, 0xe172b39e, 0x86012f07, 0x080ac94d); - - LoadCommands commands; - commands.Place(&cmd1).Place(&cmd2).Place(&cmd3); - - MachOFile file; - file.Header(&commands).Place(&segment1).Place(&segment2).Place(&segment3); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - Segment actual_segment; - - EXPECT_FALSE(reader.FindSegment("murphy", &actual_segment)); - - EXPECT_TRUE(reader.FindSegment("second", &actual_segment)); - EXPECT_EQ(0xd6b0ce83, actual_segment.vmaddr); -} - - -// Symtab tests. - -// A StringAssembler is a class for generating .stabstr sections to present -// as input to the STABS parser. -class StringAssembler: public SizedSection { - public: - // Add the string S to this StringAssembler, and return the string's - // offset within this compilation unit's strings. - size_t Add(const string &s) { - size_t offset = Size(); - AppendCString(s); - return offset; - } -}; - -// A SymbolAssembler is a class for generating .stab sections to present as -// test input for the STABS parser. -class SymbolAssembler: public SizedSection { - public: - // Create a SymbolAssembler that uses StringAssembler for its strings. - explicit SymbolAssembler(StringAssembler *string_assembler) - : string_assembler_(string_assembler), - entry_count_(0) { } - - // Append a STAB entry to the end of this section with the given - // characteristics. NAME is the offset of this entry's name string within - // its compilation unit's portion of the .stabstr section; this can be a - // value generated by a StringAssembler. Return a reference to this - // SymbolAssembler. - SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor, - Label value, Label name) { - D32(name); - D8(type); - D8(other); - D16(descriptor); - Append(endianness(), word_size_ / 8, value); - entry_count_++; - return *this; - } - - // As above, but automatically add NAME to our StringAssembler. - SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor, - Label value, const string &name) { - return Symbol(type, other, descriptor, value, string_assembler_->Add(name)); - } - - private: - // The strings for our STABS entries. - StringAssembler *string_assembler_; - - // The number of entries in this compilation unit so far. - size_t entry_count_; -}; - -class Symtab: public ReaderFixture, public Test { }; - -TEST_F(Symtab, Symtab32) { - WithConfiguration config(kLittleEndian, 32); - - StringAssembler strings; - SymbolAssembler symbols(&strings); - symbols - .Symbol(0x52, 0x7c, 0x3470, 0x9bb02e7c, "hrududu") - .Symbol(0x50, 0x90, 0x7520, 0x1122525d, "Frith"); - - SizedSection symtab_command; - symtab_command - .D32(LC_SYMTAB) // command - .D32(symtab_command.final_size()) // size - .D32(symbols.start()) // file offset of symbols - .D32(2) // symbol count - .D32(strings.start()) // file offset of strings - .D32(strings.final_size()); // strings size - - LoadCommands load_commands; - load_commands.Place(&symtab_command); - - MachOFile file; - file.Header(&load_commands).Place(&symbols).Place(&strings); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - ByteBuffer symbols_found, strings_found; - EXPECT_CALL(load_command_handler, SymtabCommand(_, _)) - .WillOnce(DoAll(SaveArg<0>(&symbols_found), - SaveArg<1>(&strings_found), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(24U, symbols_found.Size()); - EXPECT_EQ(14U, strings_found.Size()); -} - -TEST_F(Symtab, Symtab64) { - WithConfiguration config(kBigEndian, 64); - - StringAssembler strings; - SymbolAssembler symbols(&strings); - symbols - .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") - .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); - - SizedSection symtab_command; - symtab_command - .D32(LC_SYMTAB) // command - .D32(symtab_command.final_size()) // size - .D32(symbols.start()) // file offset of symbols - .D32(2) // symbol count - .D32(strings.start()) // file offset of strings - .D32(strings.final_size()); // strings size - - LoadCommands load_commands; - load_commands.Place(&symtab_command); - - MachOFile file; - file.Header(&load_commands).Place(&symbols).Place(&strings); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - ByteBuffer symbols_found, strings_found; - EXPECT_CALL(load_command_handler, SymtabCommand(_, _)) - .WillOnce(DoAll(SaveArg<0>(&symbols_found), - SaveArg<1>(&strings_found), - Return(true))); - EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); - - EXPECT_EQ(32U, symbols_found.Size()); - EXPECT_EQ(8U, strings_found.Size()); -} - -TEST_F(Symtab, SymtabMisplacedSymbols) { - WithConfiguration config(kBigEndian, 32); - - StringAssembler strings; - SymbolAssembler symbols(&strings); - symbols - .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") - .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); - - SizedSection symtab_command; - symtab_command - .D32(LC_SYMTAB) // command - .D32(symtab_command.final_size()) // size - .D32(symbols.start()) // file offset of symbols - .D32(3) // symbol count (too many) - .D32(strings.start()) // file offset of strings - .D32(strings.final_size()); // strings size - - LoadCommands load_commands; - load_commands.Place(&symtab_command); - - MachOFile file; - // Put symbols at end, so the excessive length will be noticed. - file.Header(&load_commands).Place(&strings).Place(&symbols); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1); - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - -TEST_F(Symtab, SymtabMisplacedStrings) { - WithConfiguration config(kLittleEndian, 32); - - StringAssembler strings; - SymbolAssembler symbols(&strings); - symbols - .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") - .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); - - SizedSection symtab_command; - symtab_command - .D32(LC_SYMTAB) // command - .D32(symtab_command.final_size()) // size - .D32(symbols.start()) // file offset of symbols - .D32(2) // symbol count - .D32(strings.start()) // file offset of strings - .D32(strings.final_size() + 1); // strings size (too long) - - LoadCommands load_commands; - load_commands.Place(&symtab_command); - - MachOFile file; - // Put strings at end, so the excessive length will be noticed. - file.Header(&load_commands).Place(&symbols).Place(&strings); - - ReadFile(&file, true, CPU_TYPE_ANY, 0); - - EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1); - EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); -} - diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.cc deleted file mode 100644 index f56fe768c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_utilties.cc: Utilities for dealing with mach-o files -// -// Author: Dave Camp - -#include "common/mac/byteswap.h" -#include "common/mac/macho_utilities.h" - -#include -#include - -void breakpad_swap_uuid_command(struct breakpad_uuid_command *uc) { - uc->cmd = ByteSwap(uc->cmd); - uc->cmdsize = ByteSwap(uc->cmdsize); -} - -void breakpad_swap_load_command(struct load_command *lc) { - lc->cmd = ByteSwap(lc->cmd); - lc->cmdsize = ByteSwap(lc->cmdsize); -} - -void breakpad_swap_dylib_command(struct dylib_command *dc) { - dc->cmd = ByteSwap(dc->cmd); - dc->cmdsize = ByteSwap(dc->cmdsize); - - dc->dylib.name.offset = ByteSwap(dc->dylib.name.offset); - dc->dylib.timestamp = ByteSwap(dc->dylib.timestamp); - dc->dylib.current_version = ByteSwap(dc->dylib.current_version); - dc->dylib.compatibility_version = ByteSwap(dc->dylib.compatibility_version); -} - -void breakpad_swap_segment_command(struct segment_command *sc) { - sc->cmd = ByteSwap(sc->cmd); - sc->cmdsize = ByteSwap(sc->cmdsize); - - sc->vmaddr = ByteSwap(sc->vmaddr); - sc->vmsize = ByteSwap(sc->vmsize); - sc->fileoff = ByteSwap(sc->fileoff); - sc->filesize = ByteSwap(sc->filesize); - sc->maxprot = ByteSwap(sc->maxprot); - sc->initprot = ByteSwap(sc->initprot); - sc->nsects = ByteSwap(sc->nsects); - sc->flags = ByteSwap(sc->flags); -} - -void breakpad_swap_segment_command_64(struct segment_command_64 *sg) { - sg->cmd = ByteSwap(sg->cmd); - sg->cmdsize = ByteSwap(sg->cmdsize); - - sg->vmaddr = ByteSwap(sg->vmaddr); - sg->vmsize = ByteSwap(sg->vmsize); - sg->fileoff = ByteSwap(sg->fileoff); - sg->filesize = ByteSwap(sg->filesize); - - sg->maxprot = ByteSwap(sg->maxprot); - sg->initprot = ByteSwap(sg->initprot); - sg->nsects = ByteSwap(sg->nsects); - sg->flags = ByteSwap(sg->flags); -} - -void breakpad_swap_fat_header(struct fat_header *fh) { - fh->magic = ByteSwap(fh->magic); - fh->nfat_arch = ByteSwap(fh->nfat_arch); -} - -void breakpad_swap_fat_arch(struct fat_arch *fa, uint32_t narchs) { - for (uint32_t i = 0; i < narchs; ++i) { - fa[i].cputype = ByteSwap(fa[i].cputype); - fa[i].cpusubtype = ByteSwap(fa[i].cpusubtype); - fa[i].offset = ByteSwap(fa[i].offset); - fa[i].size = ByteSwap(fa[i].size); - fa[i].align = ByteSwap(fa[i].align); - } -} - -void breakpad_swap_mach_header(struct mach_header *mh) { - mh->magic = ByteSwap(mh->magic); - mh->cputype = ByteSwap(mh->cputype); - mh->cpusubtype = ByteSwap(mh->cpusubtype); - mh->filetype = ByteSwap(mh->filetype); - mh->ncmds = ByteSwap(mh->ncmds); - mh->sizeofcmds = ByteSwap(mh->sizeofcmds); - mh->flags = ByteSwap(mh->flags); -} - -void breakpad_swap_mach_header_64(struct mach_header_64 *mh) { - mh->magic = ByteSwap(mh->magic); - mh->cputype = ByteSwap(mh->cputype); - mh->cpusubtype = ByteSwap(mh->cpusubtype); - mh->filetype = ByteSwap(mh->filetype); - mh->ncmds = ByteSwap(mh->ncmds); - mh->sizeofcmds = ByteSwap(mh->sizeofcmds); - mh->flags = ByteSwap(mh->flags); - mh->reserved = ByteSwap(mh->reserved); -} - -void breakpad_swap_section(struct section *s, - uint32_t nsects) { - for (uint32_t i = 0; i < nsects; i++) { - s[i].addr = ByteSwap(s[i].addr); - s[i].size = ByteSwap(s[i].size); - - s[i].offset = ByteSwap(s[i].offset); - s[i].align = ByteSwap(s[i].align); - s[i].reloff = ByteSwap(s[i].reloff); - s[i].nreloc = ByteSwap(s[i].nreloc); - s[i].flags = ByteSwap(s[i].flags); - s[i].reserved1 = ByteSwap(s[i].reserved1); - s[i].reserved2 = ByteSwap(s[i].reserved2); - } -} - -void breakpad_swap_section_64(struct section_64 *s, - uint32_t nsects) { - for (uint32_t i = 0; i < nsects; i++) { - s[i].addr = ByteSwap(s[i].addr); - s[i].size = ByteSwap(s[i].size); - - s[i].offset = ByteSwap(s[i].offset); - s[i].align = ByteSwap(s[i].align); - s[i].reloff = ByteSwap(s[i].reloff); - s[i].nreloc = ByteSwap(s[i].nreloc); - s[i].flags = ByteSwap(s[i].flags); - s[i].reserved1 = ByteSwap(s[i].reserved1); - s[i].reserved2 = ByteSwap(s[i].reserved2); - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.h b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.h deleted file mode 100644 index 00563a77c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_utilities.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_utilities.h: Utilities for dealing with mach-o files -// -// Author: Dave Camp - -#ifndef COMMON_MAC_MACHO_UTILITIES_H__ -#define COMMON_MAC_MACHO_UTILITIES_H__ - -#include -#include - -/* Some #defines and structs that aren't defined in older SDKs */ -#ifndef CPU_ARCH_ABI64 -# define CPU_ARCH_ABI64 0x01000000 -#endif - -#ifndef CPU_TYPE_X86 -# define CPU_TYPE_X86 CPU_TYPE_I386 -#endif - -#ifndef CPU_TYPE_POWERPC64 -# define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) -#endif - -#ifndef LC_UUID -# define LC_UUID 0x1b /* the uuid */ -#endif - -// The uuid_command struct/swap routines were added during the 10.4 series. -// Their presence isn't guaranteed. -struct breakpad_uuid_command { - uint32_t cmd; /* LC_UUID */ - uint32_t cmdsize; /* sizeof(struct uuid_command) */ - uint8_t uuid[16]; /* the 128-bit uuid */ -}; - -void breakpad_swap_uuid_command(struct breakpad_uuid_command *uc); - -void breakpad_swap_load_command(struct load_command *lc); - -void breakpad_swap_dylib_command(struct dylib_command *dc); - -// Older SDKs defines thread_state_data_t as an int[] instead -// of the natural_t[] it should be. -typedef natural_t breakpad_thread_state_data_t[THREAD_STATE_MAX]; - -void breakpad_swap_segment_command(struct segment_command *sc); - -// The 64-bit swap routines were added during the 10.4 series, their -// presence isn't guaranteed. -void breakpad_swap_segment_command_64(struct segment_command_64 *sg); - -void breakpad_swap_fat_header(struct fat_header *fh); - -void breakpad_swap_fat_arch(struct fat_arch *fa, uint32_t narchs); - -void breakpad_swap_mach_header(struct mach_header *mh); - -void breakpad_swap_mach_header_64(struct mach_header_64 *mh); - -void breakpad_swap_section(struct section *s, - uint32_t nsects); - -void breakpad_swap_section_64(struct section_64 *s, - uint32_t nsects); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.cc deleted file mode 100644 index 1acd86656..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.cc +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_walker.cc: Iterate over the load commands in a mach-o file -// -// See macho_walker.h for documentation -// -// Author: Dan Waylonis - -#include -#include -#include -#include -#include -#include -#include - -#include "common/mac/byteswap.h" -#include "common/mac/macho_walker.h" -#include "common/mac/macho_utilities.h" - -namespace MacFileUtilities { - -MachoWalker::MachoWalker(const char *path, LoadCommandCallback callback, - void *context) - : file_(-1), - memory_(NULL), - memory_size_(0), - callback_(callback), - callback_context_(context), - current_header_(NULL), - current_header_size_(0), - current_header_offset_(0) { - file_ = open(path, O_RDONLY); -} - -MachoWalker::MachoWalker(void *memory, size_t size, - LoadCommandCallback callback, void *context) - : file_(-1), - memory_(memory), - memory_size_(size), - callback_(callback), - callback_context_(context), - current_header_(NULL), - current_header_size_(0), - current_header_offset_(0) { -} - -MachoWalker::~MachoWalker() { - if (file_ != -1) - close(file_); -} - -bool MachoWalker::WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { - cpu_type_t valid_cpu_type = cpu_type; - cpu_subtype_t valid_cpu_subtype = cpu_subtype; - // if |cpu_type| is 0, use the native cpu type. - if (cpu_type == 0) { - const NXArchInfo *arch = NXGetLocalArchInfo(); - assert(arch); - valid_cpu_type = arch->cputype; - valid_cpu_subtype = CPU_SUBTYPE_MULTIPLE; - } - off_t offset; - if (FindHeader(valid_cpu_type, valid_cpu_subtype, offset)) { - if (cpu_type & CPU_ARCH_ABI64) - return WalkHeader64AtOffset(offset); - - return WalkHeaderAtOffset(offset); - } - - return false; -} - -bool MachoWalker::ReadBytes(void *buffer, size_t size, off_t offset) { - if (memory_) { - if (offset < 0) - return false; - bool result = true; - if (offset + size > memory_size_) { - if (static_cast(offset) >= memory_size_) - return false; - size = memory_size_ - static_cast(offset); - result = false; - } - memcpy(buffer, static_cast(memory_) + offset, size); - return result; - } else { - return pread(file_, buffer, size, offset) == (ssize_t)size; - } -} - -bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) { - if (current_header_) { - memcpy(header, current_header_, sizeof(mach_header_64)); - *offset = current_header_offset_; - return true; - } - - return false; -} - -bool MachoWalker::FindHeader(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - off_t &offset) { - // Read the magic bytes that's common amongst all mach-o files - uint32_t magic; - if (!ReadBytes(&magic, sizeof(magic), 0)) - return false; - - offset = sizeof(magic); - - // Figure out what type of file we've got - bool is_fat = false; - if (magic == FAT_MAGIC || magic == FAT_CIGAM) { - is_fat = true; - } - else if (magic != MH_MAGIC && magic != MH_CIGAM && magic != MH_MAGIC_64 && - magic != MH_CIGAM_64) { - return false; - } - - if (!is_fat) { - // If we don't have a fat header, check if the cpu type matches the single - // header - struct mach_header header; - if (!ReadBytes(&header, sizeof(header), 0)) - return false; - - if (magic == MH_CIGAM || magic == MH_CIGAM_64) - breakpad_swap_mach_header(&header); - - if (cpu_type != header.cputype || - (cpu_subtype != CPU_SUBTYPE_MULTIPLE && - cpu_subtype != header.cpusubtype)) { - return false; - } - - offset = 0; - return true; - } else { - // Read the fat header and find an appropriate architecture - offset = 0; - struct fat_header fat; - if (!ReadBytes(&fat, sizeof(fat), offset)) - return false; - - if (NXHostByteOrder() != NX_BigEndian) - breakpad_swap_fat_header(&fat); - - offset += sizeof(fat); - - // Search each architecture for the desired one - struct fat_arch arch; - for (uint32_t i = 0; i < fat.nfat_arch; ++i) { - if (!ReadBytes(&arch, sizeof(arch), offset)) - return false; - - if (NXHostByteOrder() != NX_BigEndian) - breakpad_swap_fat_arch(&arch, 1); - - if (arch.cputype == cpu_type && - (cpu_subtype == CPU_SUBTYPE_MULTIPLE || - arch.cpusubtype == cpu_subtype)) { - offset = arch.offset; - return true; - } - - offset += sizeof(arch); - } - } - - return false; -} - -bool MachoWalker::WalkHeaderAtOffset(off_t offset) { - struct mach_header header; - if (!ReadBytes(&header, sizeof(header), offset)) - return false; - - bool swap = (header.magic == MH_CIGAM); - if (swap) - breakpad_swap_mach_header(&header); - - // Copy the data into the mach_header_64 structure. Since the 32-bit and - // 64-bit only differ in the last field (reserved), this is safe to do. - struct mach_header_64 header64; - memcpy((void *)&header64, (const void *)&header, sizeof(header)); - header64.reserved = 0; - - current_header_ = &header64; - current_header_size_ = sizeof(header); // 32-bit, not 64-bit - current_header_offset_ = offset; - offset += current_header_size_; - bool result = WalkHeaderCore(offset, header.ncmds, swap); - current_header_ = NULL; - current_header_size_ = 0; - current_header_offset_ = 0; - return result; -} - -bool MachoWalker::WalkHeader64AtOffset(off_t offset) { - struct mach_header_64 header; - if (!ReadBytes(&header, sizeof(header), offset)) - return false; - - bool swap = (header.magic == MH_CIGAM_64); - if (swap) - breakpad_swap_mach_header_64(&header); - - current_header_ = &header; - current_header_size_ = sizeof(header); - current_header_offset_ = offset; - offset += current_header_size_; - bool result = WalkHeaderCore(offset, header.ncmds, swap); - current_header_ = NULL; - current_header_size_ = 0; - current_header_offset_ = 0; - return result; -} - -bool MachoWalker::WalkHeaderCore(off_t offset, uint32_t number_of_commands, - bool swap) { - for (uint32_t i = 0; i < number_of_commands; ++i) { - struct load_command cmd; - if (!ReadBytes(&cmd, sizeof(cmd), offset)) - return false; - - if (swap) - breakpad_swap_load_command(&cmd); - - // Call the user callback - if (callback_ && !callback_(this, &cmd, offset, swap, callback_context_)) - break; - - offset += cmd.cmdsize; - } - - return true; -} - -} // namespace MacFileUtilities diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.h b/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.h deleted file mode 100644 index dd535814a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// macho_walker.h: Iterate over the load commands in a mach-o file -// -// Author: Dan Waylonis - -#ifndef COMMON_MAC_MACHO_WALKER_H__ -#define COMMON_MAC_MACHO_WALKER_H__ - -#include -#include -#include - -namespace MacFileUtilities { - -class MachoWalker { - public: - // A callback function executed when a new load command is read. If no - // further processing of load commands is desired, return false. Otherwise, - // return true. - // |cmd| is the current command, and |offset| is the location relative to the - // beginning of the file (not header) where the command was read. If |swap| - // is set, then any command data (other than the returned load_command) should - // be swapped when read - typedef bool (*LoadCommandCallback)(MachoWalker *walker, load_command *cmd, - off_t offset, bool swap, void *context); - - MachoWalker(const char *path, LoadCommandCallback callback, void *context); - MachoWalker(void *memory, size_t size, LoadCommandCallback callback, - void *context); - ~MachoWalker(); - - // Begin walking the header for |cpu_type| and |cpu_subtype|. If |cpu_type| - // is 0, then the native cpu type is used. Otherwise, accepted values are - // listed in /usr/include/mach/machine.h (e.g., CPU_TYPE_X86 or - // CPU_TYPE_POWERPC). If |cpu_subtype| is CPU_SUBTYPE_MULTIPLE, the match is - // only done on |cpu_type|. - // Returns false if opening the file failed or if the |cpu_type|/|cpu_subtype| - // is not present in the file. - bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype); - - // Read |size| bytes from the opened file at |offset| into |buffer| - bool ReadBytes(void *buffer, size_t size, off_t offset); - - // Return the current header and header offset - bool CurrentHeader(struct mach_header_64 *header, off_t *offset); - - private: - // Locate (if any) the header offset for |cpu_type| and return in |offset|. - // Return true if found, false otherwise. - bool FindHeader(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - off_t &offset); - - // Process an individual header starting at |offset| from the start of the - // file. Return true if successful, false otherwise. - bool WalkHeaderAtOffset(off_t offset); - bool WalkHeader64AtOffset(off_t offset); - - // Bottleneck for walking the load commands - bool WalkHeaderCore(off_t offset, uint32_t number_of_commands, bool swap); - - // File descriptor to the opened file - int file_; - - // Memory location to read from. - void *memory_; - - // Size of the memory segment we can read from. - size_t memory_size_; - - // User specified callback & context - LoadCommandCallback callback_; - void *callback_context_; - - // Current header, size, and offset. The mach_header_64 is used for both - // 32-bit and 64-bit headers because they only differ in their last field - // (reserved). By adding the |current_header_size_| and the - // |current_header_offset_|, you can determine the offset in the file just - // after the header. - struct mach_header_64 *current_header_; - unsigned long current_header_size_; - off_t current_header_offset_; - - private: - MachoWalker(const MachoWalker &); - MachoWalker &operator=(const MachoWalker &); -}; - -} // namespace MacFileUtilities - -#endif // COMMON_MAC_MACHO_WALKER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/moz.build b/toolkit/crashreporter/google-breakpad/src/common/mac/moz.build deleted file mode 100644 index 6d6df28e2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/moz.build +++ /dev/null @@ -1,52 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'arch_utilities.cc', - 'file_id.cc', - 'macho_id.cc', - 'macho_reader.cc', - 'macho_utilities.cc', - 'macho_walker.cc', -] - -if CONFIG['HOST_OS_ARCH'] != 'Darwin': - HOST_CXXFLAGS += [ - '-I%s/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/' % TOPSRCDIR, - ] - -# This is a little weird, but we're building a host and a target lib here. -# The host lib is used for dump_syms, and the target lib for the -# crash reporter client. Therefore, we don't need all the srcs in both. -if CONFIG['MOZ_CRASHREPORTER']: - HOST_SOURCES += UNIFIED_SOURCES - HOST_SOURCES += [ - 'dump_syms.cc', - ] - HOST_CXXFLAGS += [ - '-O2', - '-g', - '-stdlib=libc++', - ] - HostLibrary('host_breakpad_mac_common_s') - -SOURCES += [ - 'bootstrap_compat.cc', - 'HTTPMultipartUpload.m', - 'MachIPC.mm', - 'string_utilities.cc', -] - -Library('breakpad_mac_common_s') - -# We allow warnings for third-party code that can be updated from upstream. -ALLOW_COMPILER_WARNINGS = True - -FINAL_LIBRARY = 'xul' - -CMFLAGS += ['-std=c99'] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/scoped_task_suspend-inl.h b/toolkit/crashreporter/google-breakpad/src/common/mac/scoped_task_suspend-inl.h deleted file mode 100644 index d6d1bef97..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/scoped_task_suspend-inl.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Inline implementation of ScopedTaskSuspend, which suspends a Mach -// task for the duration of its scope. - -#ifndef GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_ -#define GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_ - -#include - -namespace google_breakpad { - -class ScopedTaskSuspend { - public: - explicit ScopedTaskSuspend(mach_port_t target) : target_(target) { - task_suspend(target_); - } - - ~ScopedTaskSuspend() { - task_resume(target_); - } - - private: - mach_port_t target_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.cc b/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.cc deleted file mode 100644 index 07c0f4268..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/scoped_ptr.h" -#include "common/mac/string_utilities.h" - -namespace MacStringUtils { - -using google_breakpad::scoped_array; - -std::string ConvertToString(CFStringRef str) { - CFIndex length = CFStringGetLength(str); - std::string result; - - if (!length) - return result; - - CFIndex maxUTF8Length = - CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); - scoped_array buffer(new UInt8[maxUTF8Length + 1]); - CFIndex actualUTF8Length; - CFStringGetBytes(str, CFRangeMake(0, length), kCFStringEncodingUTF8, 0, - false, buffer.get(), maxUTF8Length, &actualUTF8Length); - buffer[actualUTF8Length] = 0; - result.assign((const char *)buffer.get()); - - return result; -} - -unsigned int IntegerValueAtIndex(string &str, unsigned int idx) { - string digits("0123456789"), temp; - size_t start = 0; - size_t end; - size_t found = 0; - unsigned int result = 0; - - for (; found <= idx; ++found) { - end = str.find_first_not_of(digits, start); - - if (end == string::npos) - end = str.size(); - - temp = str.substr(start, end - start); - - if (found == idx) { - result = atoi(temp.c_str()); - } - - start = str.find_first_of(digits, end + 1); - - if (start == string::npos) - break; - } - - return result; -} - -} // namespace MacStringUtils diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.h b/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.h deleted file mode 100644 index 6d89c834e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// string_utilities.h: Utilities for strings for Mac platform - -#ifndef COMMON_MAC_STRING_UTILITIES_H__ -#define COMMON_MAC_STRING_UTILITIES_H__ - -#include - -#include - -namespace MacStringUtils { - -using std::string; - -// Convert a CoreFoundation string into a std::string -string ConvertToString(CFStringRef str); - -// Return the idx'th decimal integer in str, separated by non-decimal-digits -// E.g., str = 10.4.8, idx = 1 -> 4 -unsigned int IntegerValueAtIndex(string &str, unsigned int idx); - -} // namespace MacStringUtils - -#endif // COMMON_MAC_STRING_UTILITIES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/super_fat_arch.h b/toolkit/crashreporter/google-breakpad/src/common/mac/super_fat_arch.h deleted file mode 100644 index 501c8652a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/super_fat_arch.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Erik Chen - -// super_fat_arch.h: A class to handle 64-bit object files. Has conversions to -// and from struct fat_arch. - -#ifndef BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_ -#define BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_ - -#include -#include -#include - -// Similar to struct fat_arch, except size-related parameters support -// 64-bits. -class SuperFatArch { - public: - uint32_t cputype; - uint32_t cpusubtype; - uint64_t offset; - uint64_t size; - uint64_t align; - - SuperFatArch() : - cputype(0), - cpusubtype(0), - offset(0), - size(0), - align(0) { - } - - explicit SuperFatArch(const struct fat_arch &arch) : - cputype(arch.cputype), - cpusubtype(arch.cpusubtype), - offset(arch.offset), - size(arch.size), - align(arch.align) { - } - - // Returns false if the conversion cannot be made. - // If the conversion succeeds, the result is placed in |output_arch|. - bool ConvertToFatArch(struct fat_arch* output_arch) const { - if (offset > std::numeric_limits::max()) - return false; - if (size > std::numeric_limits::max()) - return false; - if (align > std::numeric_limits::max()) - return false; - struct fat_arch arch; - arch.cputype = cputype; - arch.cpusubtype = cpusubtype; - arch.offset = offset; - arch.size = size; - arch.align = align; - *output_arch = arch; - return true; - } -}; - -#endif // BREAKPAD_COMMON_MAC_SUPER_FAT_ARCH_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.h b/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.h deleted file mode 100644 index ce3d9022c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.h +++ /dev/null @@ -1,1110 +0,0 @@ -// -// GTMSenTestCase.h -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// Portions of this file fall under the following license, marked with -// SENTE_BEGIN - SENTE_END -// -// Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved. -// -// Use of this source code is governed by the following license: -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Note: this license is equivalent to the FreeBSD license. -// -// This notice may not be removed from this file. - -// Some extra test case macros that would have been convenient for SenTestingKit -// to provide. I didn't stick GTM in front of the Macro names, so that they would -// be easy to remember. - -#import "GTMDefines.h" - -#if (!GTM_IPHONE_SDK) || (GTM_IPHONE_USE_SENTEST) -#import -#else -#import -#ifdef __cplusplus -extern "C" { -#endif - -#if defined __clang__ -// gcc and gcc-llvm do not allow you to use STAssert(blah, nil) with nil -// as a description if you have the NS_FORMAT_FUNCTION on. -// clang however will not compile without warnings if you don't have it. -NSString *STComposeString(NSString *, ...) NS_FORMAT_FUNCTION(1, 2); -#else -NSString *STComposeString(NSString *, ...); -#endif // __clang__ - -#ifdef __cplusplus -} -#endif - -#endif // !GTM_IPHONE_SDK || GTM_IPHONE_USE_SENTEST - -// Generates a failure when a1 != noErr -// Args: -// a1: should be either an OSErr or an OSStatus -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNoErr(a1, description, ...) \ -do { \ - @try { \ - OSStatus a1value = (a1); \ - if (a1value != noErr) { \ - NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", (long)a1value, #a1]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when a1 != a2 -// Args: -// a1: received value. Should be either an OSErr or an OSStatus -// a2: expected value. Should be either an OSErr or an OSStatus -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertErr(a1, a2, description, ...) \ -do { \ - @try { \ - OSStatus a1value = (a1); \ - OSStatus a2value = (a2); \ - if (a1value != a2value) { \ - NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, (long)a2value, (long)a1value, #a1]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s) fails", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - - -// Generates a failure when a1 is NULL -// Args: -// a1: should be a pointer (use STAssertNotNil for an object) -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNotNULL(a1, description, ...) \ -do { \ - @try { \ - __typeof__(a1) a1value = (a1); \ - if (a1value == (__typeof__(a1))NULL) { \ - NSString *_expression = [NSString stringWithFormat:@"((%s) != NULL)", #a1]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when a1 is not NULL -// Args: -// a1: should be a pointer (use STAssertNil for an object) -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNULL(a1, description, ...) \ -do { \ - @try { \ - __typeof__(a1) a1value = (a1); \ - if (a1value != (__typeof__(a1))NULL) { \ - NSString *_expression = [NSString stringWithFormat:@"((%s) == NULL)", #a1]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when a1 is equal to a2. This test is for C scalars, -// structs and unions. -// Args: -// a1: argument 1 -// a2: argument 2 -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNotEquals(a1, a2, description, ...) \ -do { \ - @try { \ - if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \ - } else { \ - __typeof__(a1) a1value = (a1); \ - __typeof__(a2) a2value = (a2); \ - NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \ - NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \ - if ([a1encoded isEqualToValue:a2encoded]) { \ - NSString *_expression = [NSString stringWithFormat:@"((%s) != (%s))", #a1, #a2]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - }\ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when a1 is equal to a2. This test is for objects. -// Args: -// a1: argument 1. object. -// a2: argument 2. object. -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNotEqualObjects(a1, a2, description, ...) \ -do { \ - @try {\ - id a1value = (a1); \ - id a2value = (a2); \ - if ( (strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \ - (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \ - (![(id)a1value isEqual:(id)a2value]) ) continue; \ - [self failWithException:([NSException failureInEqualityBetweenObject:a1value \ - andObject:a2value \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - }\ - @catch (id anException) {\ - [self failWithException:([NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - }\ -} while(0) - -// Generates a failure when a1 is not 'op' to a2. This test is for C scalars. -// Args: -// a1: argument 1 -// a2: argument 2 -// op: operation -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertOperation(a1, a2, op, description, ...) \ -do { \ - @try { \ - if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \ - } else { \ - __typeof__(a1) a1value = (a1); \ - __typeof__(a2) a2value = (a2); \ - if (!(a1value op a2value)) { \ - double a1DoubleValue = a1value; \ - double a2DoubleValue = a2value; \ - NSString *_expression = [NSString stringWithFormat:@"(%s (%lg) %s %s (%lg))", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \ - [self failWithException:([NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ - } \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException \ - failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when a1 is not > a2. This test is for C scalars. -// Args: -// a1: argument 1 -// a2: argument 2 -// op: operation -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertGreaterThan(a1, a2, description, ...) \ - STAssertOperation(a1, a2, >, description, ##__VA_ARGS__) - -// Generates a failure when a1 is not >= a2. This test is for C scalars. -// Args: -// a1: argument 1 -// a2: argument 2 -// op: operation -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertGreaterThanOrEqual(a1, a2, description, ...) \ - STAssertOperation(a1, a2, >=, description, ##__VA_ARGS__) - -// Generates a failure when a1 is not < a2. This test is for C scalars. -// Args: -// a1: argument 1 -// a2: argument 2 -// op: operation -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertLessThan(a1, a2, description, ...) \ - STAssertOperation(a1, a2, <, description, ##__VA_ARGS__) - -// Generates a failure when a1 is not <= a2. This test is for C scalars. -// Args: -// a1: argument 1 -// a2: argument 2 -// op: operation -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertLessThanOrEqual(a1, a2, description, ...) \ - STAssertOperation(a1, a2, <=, description, ##__VA_ARGS__) - -// Generates a failure when string a1 is not equal to string a2. This call -// differs from STAssertEqualObjects in that strings that are different in -// composition (precomposed vs decomposed) will compare equal if their final -// representation is equal. -// ex O + umlaut decomposed is the same as O + umlaut composed. -// Args: -// a1: string 1 -// a2: string 2 -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertEqualStrings(a1, a2, description, ...) \ -do { \ - @try { \ - id a1value = (a1); \ - id a2value = (a2); \ - if (a1value == a2value) continue; \ - if ([a1value isKindOfClass:[NSString class]] && \ - [a2value isKindOfClass:[NSString class]] && \ - [a1value compare:a2value options:0] == NSOrderedSame) continue; \ - [self failWithException:[NSException failureInEqualityBetweenObject:a1value \ - andObject:a2value \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when string a1 is equal to string a2. This call -// differs from STAssertEqualObjects in that strings that are different in -// composition (precomposed vs decomposed) will compare equal if their final -// representation is equal. -// ex O + umlaut decomposed is the same as O + umlaut composed. -// Args: -// a1: string 1 -// a2: string 2 -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNotEqualStrings(a1, a2, description, ...) \ -do { \ - @try { \ - id a1value = (a1); \ - id a2value = (a2); \ - if ([a1value isKindOfClass:[NSString class]] && \ - [a2value isKindOfClass:[NSString class]] && \ - [a1value compare:a2value options:0] != NSOrderedSame) continue; \ - [self failWithException:[NSException failureInEqualityBetweenObject:a1value \ - andObject:a2value \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when c-string a1 is not equal to c-string a2. -// Args: -// a1: string 1 -// a2: string 2 -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertEqualCStrings(a1, a2, description, ...) \ -do { \ - @try { \ - const char* a1value = (a1); \ - const char* a2value = (a2); \ - if (a1value == a2value) continue; \ - if (strcmp(a1value, a2value) == 0) continue; \ - [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \ - andObject:[NSString stringWithUTF8String:a2value] \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -// Generates a failure when c-string a1 is equal to c-string a2. -// Args: -// a1: string 1 -// a2: string 2 -// description: A format string as in the printf() function. Can be nil or -// an empty string but must be present. -// ...: A variable number of arguments to the format string. Can be absent. -#define STAssertNotEqualCStrings(a1, a2, description, ...) \ -do { \ - @try { \ - const char* a1value = (a1); \ - const char* a2value = (a2); \ - if (strcmp(a1value, a2value) != 0) continue; \ - [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \ - andObject:[NSString stringWithUTF8String:a2value] \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false. - This test is for GLKit types (GLKVector, GLKMatrix) where small differences - could make these items not exactly equal. Do not use this version directly. - Use the explicit STAssertEqualGLKVectors and STAssertEqualGLKMatrices defined - below. - _{a1 The GLKType on the left.} - _{a2 The GLKType on the right.} - _{accuracy The maximum difference between a1 and a2 for these values to be - considered equal.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ - -#define STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ...) \ -do { \ - @try { \ - if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \ - } else { \ - __typeof__(a1) a1GLKValue = (a1); \ - __typeof__(a2) a2GLKValue = (a2); \ - __typeof__(accuracy) accuracyvalue = (accuracy); \ - float *a1FloatValue = ((float*)&a1GLKValue); \ - float *a2FloatValue = ((float*)&a2GLKValue); \ - for (size_t i = 0; i < sizeof(__typeof__(a1)) / sizeof(float); ++i) { \ - float a1value = a1FloatValue[i]; \ - float a2value = a2FloatValue[i]; \ - if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \ - NSMutableArray *strings = [NSMutableArray arrayWithCapacity:sizeof(a1) / sizeof(float)]; \ - NSString *string; \ - for (size_t j = 0; j < sizeof(__typeof__(a1)) / sizeof(float); ++j) { \ - string = [NSString stringWithFormat:@"(%0.3f == %0.3f)", a1FloatValue[j], a2FloatValue[j]]; \ - [strings addObject:string]; \ - } \ - string = [strings componentsJoinedByString:@", "]; \ - NSString *desc = STComposeString(description, ##__VA_ARGS__); \ - desc = [NSString stringWithFormat:@"%@ With Accuracy %0.3f: %@", string, (float)accuracyvalue, desc]; \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", desc]]; \ - break; \ - } \ - } \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -#define STAssertEqualGLKVectors(a1, a2, accuracy, description, ...) \ - STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__) - -#define STAssertEqualGLKMatrices(a1, a2, accuracy, description, ...) \ - STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__) - -#define STAssertEqualGLKQuaternions(a1, a2, accuracy, description, ...) \ - STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__) - -#if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST -// When not using the Xcode provided version, define everything ourselves. - -// SENTE_BEGIN -/*" Generates a failure when !{ [a1 isEqualTo:a2] } is false - (or one is nil and the other is not). - _{a1 The object on the left.} - _{a2 The object on the right.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertEqualObjects(a1, a2, description, ...) \ -do { \ - @try { \ - id a1value = (a1); \ - id a2value = (a2); \ - if (a1value == a2value) continue; \ - if ((strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \ - (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \ - [(id)a1value isEqual:(id)a2value]) continue; \ - [self failWithException:[NSException failureInEqualityBetweenObject:a1value \ - andObject:a2value \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - - -/*" Generates a failure when a1 is not equal to a2. This test is for - C scalars, structs and unions. - _{a1 The argument on the left.} - _{a2 The argument on the right.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertEquals(a1, a2, description, ...) \ -do { \ - @try { \ - if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \ - } else { \ - __typeof__(a1) a1value = (a1); \ - __typeof__(a2) a2value = (a2); \ - NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \ - NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \ - if (![a1encoded isEqualToValue:a2encoded]) { \ - [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \ - andValue:a2encoded \ - withAccuracy:nil \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - -#define STAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right)) - - -/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false. - This test is for scalars such as floats and doubles where small differences - could make these items not exactly equal, but also works for all scalars. - _{a1 The scalar on the left.} - _{a2 The scalar on the right.} - _{accuracy The maximum difference between a1 and a2 for these values to be - considered equal.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ - -#define STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \ -do { \ - @try { \ - if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \ - [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \ - } else { \ - __typeof__(a1) a1value = (a1); \ - __typeof__(a2) a2value = (a2); \ - __typeof__(accuracy) accuracyvalue = (accuracy); \ - if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \ - NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \ - NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \ - NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \ - [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \ - andValue:a2encoded \ - withAccuracy:accuracyencoded \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - - - -/*" Generates a failure unconditionally. - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STFail(description, ...) \ -[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]] - - - -/*" Generates a failure when a1 is not nil. - _{a1 An object.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertNil(a1, description, ...) \ -do { \ - @try { \ - id a1value = (a1); \ - if (a1value != nil) { \ - NSString *_a1 = [NSString stringWithUTF8String:#a1]; \ - NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == nil fails", #a1] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - - -/*" Generates a failure when a1 is nil. - _{a1 An object.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertNotNil(a1, description, ...) \ -do { \ - @try { \ - id a1value = (a1); \ - if (a1value == nil) { \ - NSString *_a1 = [NSString stringWithUTF8String:#a1]; \ - NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != nil fails", #a1] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while(0) - - -/*" Generates a failure when expression evaluates to false. - _{expr The expression that is tested.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertTrue(expr, description, ...) \ -do { \ - BOOL _evaluatedExpression = (expr); \ - if (!_evaluatedExpression) { \ - NSString *_expression = [NSString stringWithUTF8String:#expr]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while (0) - - -/*" Generates a failure when expression evaluates to false and in addition will - generate error messages if an exception is encountered. - _{expr The expression that is tested.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertTrueNoThrow(expr, description, ...) \ -do { \ - @try { \ - BOOL _evaluatedExpression = (expr); \ - if (!_evaluatedExpression) { \ - NSString *_expression = [NSString stringWithUTF8String:#expr]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:NO \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) ", #expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while (0) - - -/*" Generates a failure when the expression evaluates to true. - _{expr The expression that is tested.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertFalse(expr, description, ...) \ -do { \ - BOOL _evaluatedExpression = (expr); \ - if (_evaluatedExpression) { \ - NSString *_expression = [NSString stringWithUTF8String:#expr]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:YES \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while (0) - - -/*" Generates a failure when the expression evaluates to true and in addition - will generate error messages if an exception is encountered. - _{expr The expression that is tested.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertFalseNoThrow(expr, description, ...) \ -do { \ - @try { \ - BOOL _evaluatedExpression = (expr); \ - if (_evaluatedExpression) { \ - NSString *_expression = [NSString stringWithUTF8String:#expr]; \ - [self failWithException:[NSException failureInCondition:_expression \ - isTrue:YES \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"!(%s) ", #expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while (0) - - -/*" Generates a failure when expression does not throw an exception. - _{expression The expression that is evaluated.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent. -"*/ -#define STAssertThrows(expr, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (id anException) { \ - continue; \ - } \ - [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:nil \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ -} while (0) - - -/*" Generates a failure when expression does not throw an exception of a - specific class. - _{expression The expression that is evaluated.} - _{specificException The specified class of the exception.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertThrowsSpecific(expr, specificException, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (specificException *anException) { \ - continue; \ - } \ - @catch (id anException) { \ - NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \ - [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ - continue; \ - } \ - NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \ - [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:nil \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ -} while (0) - - -/*" Generates a failure when expression does not throw an exception of a - specific class with a specific name. Useful for those frameworks like - AppKit or Foundation that throw generic NSException w/specific names - (NSInvalidArgumentException, etc). - _{expression The expression that is evaluated.} - _{specificException The specified class of the exception.} - _{aName The name of the specified exception.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} - -"*/ -#define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (specificException *anException) { \ - if ([aName isEqualToString:[anException name]]) continue; \ - NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \ - [self failWithException: \ - [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ - continue; \ - } \ - @catch (id anException) { \ - NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \ - [self failWithException: \ - [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ - continue; \ - } \ - NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \ - [self failWithException: \ - [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:nil \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ -} while (0) - - -/*" Generates a failure when expression does throw an exception. - _{expression The expression that is evaluated.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertNoThrow(expr, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (id anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ -} while (0) - - -/*" Generates a failure when expression does throw an exception of the specitied - class. Any other exception is okay (i.e. does not generate a failure). - _{expression The expression that is evaluated.} - _{specificException The specified class of the exception.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} -"*/ -#define STAssertNoThrowSpecific(expr, specificException, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (specificException *anException) { \ - [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \ - } \ - @catch (id anythingElse) { \ - ; \ - } \ -} while (0) - - -/*" Generates a failure when expression does throw an exception of a - specific class with a specific name. Useful for those frameworks like - AppKit or Foundation that throw generic NSException w/specific names - (NSInvalidArgumentException, etc). - _{expression The expression that is evaluated.} - _{specificException The specified class of the exception.} - _{aName The name of the specified exception.} - _{description A format string as in the printf() function. Can be nil or - an empty string but must be present.} - _{... A variable number of arguments to the format string. Can be absent.} - -"*/ -#define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \ -do { \ - @try { \ - (expr); \ - } \ - @catch (specificException *anException) { \ - if ([aName isEqualToString:[anException name]]) { \ - NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \ - [self failWithException: \ - [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \ - exception:anException \ - inFile:[NSString stringWithUTF8String:__FILE__] \ - atLine:__LINE__ \ - withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \ - } \ - continue; \ - } \ - @catch (id anythingElse) { \ - ; \ - } \ -} while (0) - - - -@interface NSException (GTMSenTestAdditions) -+ (NSException *)failureInFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(3, 4); -+ (NSException *)failureInCondition:(NSString *)condition - isTrue:(BOOL)isTrue - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6); -+ (NSException *)failureInEqualityBetweenObject:(id)left - andObject:(id)right - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6); -+ (NSException *)failureInEqualityBetweenValue:(NSValue *)left - andValue:(NSValue *)right - withAccuracy:(NSValue *)accuracy - inFile:(NSString *)filename - atLine:(int) ineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(6, 7); -+ (NSException *)failureInRaise:(NSString *)expression - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(4, 5); -+ (NSException *)failureInRaise:(NSString *)expression - exception:(NSException *)exception - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6); -@end - -// SENTE_END - -@protocol SenTestCase -+ (id)testCaseWithInvocation:(NSInvocation *)anInvocation; -- (id)initWithInvocation:(NSInvocation *)anInvocation; -- (void)setUp; -- (void)invokeTest; -- (void)tearDown; -- (void)performTest; -- (void)failWithException:(NSException*)exception; -- (NSInvocation *)invocation; -- (SEL)selector; -+ (NSArray *)testInvocations; -@end - -@interface SenTestCase : NSObject { - @private - NSInvocation *invocation_; -} -@end - -GTM_EXTERN NSString *const SenTestFailureException; - -GTM_EXTERN NSString *const SenTestFilenameKey; -GTM_EXTERN NSString *const SenTestLineNumberKey; - -#endif // GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST - -// All unittest cases in GTM should inherit from GTMTestCase. It makes sure -// to set up our logging system correctly to verify logging calls. -// See GTMUnitTestDevLog.h for details -@interface GTMTestCase : SenTestCase - -// Returns YES if this is an abstract testCase class as opposed to a concrete -// testCase class that you want tests run against. SenTestCase is not designed -// out of the box to handle an abstract class hierarchy descending from it with -// some concrete subclasses. In some cases we want all the "concrete" -// subclasses of an abstract subclass of SenTestCase to run a test, but we don't -// want that test to be run against an instance of an abstract subclass itself. -// By returning "YES" here, the tests defined by this class won't be run against -// an instance of this class. As an example class hierarchy: -// -// FooExtensionTestCase -// GTMTestCase <- ExtensionAbstractTestCase < -// BarExtensionTestCase -// -// So FooExtensionTestCase and BarExtensionTestCase inherit from -// ExtensionAbstractTestCase (and probably FooExtension and BarExtension inherit -// from a class named Extension). We want the tests in ExtensionAbstractTestCase -// to be run as part of FooExtensionTestCase and BarExtensionTestCase, but we -// don't want them run against ExtensionAbstractTestCase. The default -// implementation checks to see if the name of the class contains the word -// "AbstractTest" (case sensitive). -+ (BOOL)isAbstractTestCase; - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.m b/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.m deleted file mode 100644 index 162f01e97..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.m +++ /dev/null @@ -1,428 +0,0 @@ -// -// GTMSenTestCase.m -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" - -#import -#if GTM_IPHONE_SIMULATOR -#import -#endif - -#import "GTMObjC2Runtime.h" -#import "GTMUnitTestDevLog.h" - -#if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST -#import - -@interface NSException (GTMSenTestPrivateAdditions) -+ (NSException *)failureInFile:(NSString *)filename - atLine:(int)lineNumber - reason:(NSString *)reason; -@end - -@implementation NSException (GTMSenTestPrivateAdditions) -+ (NSException *)failureInFile:(NSString *)filename - atLine:(int)lineNumber - reason:(NSString *)reason { - NSDictionary *userInfo = - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInteger:lineNumber], SenTestLineNumberKey, - filename, SenTestFilenameKey, - nil]; - - return [self exceptionWithName:SenTestFailureException - reason:reason - userInfo:userInfo]; -} -@end - -@implementation NSException (GTMSenTestAdditions) - -+ (NSException *)failureInFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason = testDescription; - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -+ (NSException *)failureInCondition:(NSString *)condition - isTrue:(BOOL)isTrue - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason = [NSString stringWithFormat:@"'%@' should be %s. %@", - condition, isTrue ? "false" : "true", testDescription]; - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -+ (NSException *)failureInEqualityBetweenObject:(id)left - andObject:(id)right - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason = - [NSString stringWithFormat:@"'%@' should be equal to '%@'. %@", - [left description], [right description], testDescription]; - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -+ (NSException *)failureInEqualityBetweenValue:(NSValue *)left - andValue:(NSValue *)right - withAccuracy:(NSValue *)accuracy - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason; - if (accuracy) { - reason = - [NSString stringWithFormat:@"'%@' should be equal to '%@'. %@", - left, right, testDescription]; - } else { - reason = - [NSString stringWithFormat:@"'%@' should be equal to '%@' +/-'%@'. %@", - left, right, accuracy, testDescription]; - } - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -+ (NSException *)failureInRaise:(NSString *)expression - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason = [NSString stringWithFormat:@"'%@' should raise. %@", - expression, testDescription]; - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -+ (NSException *)failureInRaise:(NSString *)expression - exception:(NSException *)exception - inFile:(NSString *)filename - atLine:(int)lineNumber - withDescription:(NSString *)formatString, ... { - - NSString *testDescription = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - testDescription = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - - NSString *reason; - if ([[exception name] isEqualToString:SenTestFailureException]) { - // it's our exception, assume it has the right description on it. - reason = [exception reason]; - } else { - // not one of our exception, use the exceptions reason and our description - reason = [NSString stringWithFormat:@"'%@' raised '%@'. %@", - expression, [exception reason], testDescription]; - } - - return [self failureInFile:filename atLine:lineNumber reason:reason]; -} - -@end - -NSString *STComposeString(NSString *formatString, ...) { - NSString *reason = @""; - if (formatString) { - va_list vl; - va_start(vl, formatString); - reason = - [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease]; - va_end(vl); - } - return reason; -} - -NSString *const SenTestFailureException = @"SenTestFailureException"; -NSString *const SenTestFilenameKey = @"SenTestFilenameKey"; -NSString *const SenTestLineNumberKey = @"SenTestLineNumberKey"; - -@interface SenTestCase (SenTestCasePrivate) -// our method of logging errors -+ (void)printException:(NSException *)exception fromTestName:(NSString *)name; -@end - -@implementation SenTestCase -+ (id)testCaseWithInvocation:(NSInvocation *)anInvocation { - return [[[self alloc] initWithInvocation:anInvocation] autorelease]; -} - -- (id)initWithInvocation:(NSInvocation *)anInvocation { - if ((self = [super init])) { - invocation_ = [anInvocation retain]; - } - return self; -} - -- (void)dealloc { - [invocation_ release]; - [super dealloc]; -} - -- (void)failWithException:(NSException*)exception { - [exception raise]; -} - -- (void)setUp { -} - -- (void)performTest { - @try { - [self invokeTest]; - } @catch (NSException *exception) { - [[self class] printException:exception - fromTestName:NSStringFromSelector([self selector])]; - [exception raise]; - } -} - -- (NSInvocation *)invocation { - return invocation_; -} - -- (SEL)selector { - return [invocation_ selector]; -} - -+ (void)printException:(NSException *)exception fromTestName:(NSString *)name { - NSDictionary *userInfo = [exception userInfo]; - NSString *filename = [userInfo objectForKey:SenTestFilenameKey]; - NSNumber *lineNumber = [userInfo objectForKey:SenTestLineNumberKey]; - NSString *className = NSStringFromClass([self class]); - if ([filename length] == 0) { - filename = @"Unknown.m"; - } - fprintf(stderr, "%s:%ld: error: -[%s %s] : %s\n", - [filename UTF8String], - (long)[lineNumber integerValue], - [className UTF8String], - [name UTF8String], - [[exception reason] UTF8String]); - fflush(stderr); -} - -- (void)invokeTest { - NSException *e = nil; - @try { - // Wrap things in autorelease pools because they may - // have an STMacro in their dealloc which may get called - // when the pool is cleaned up - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - // We don't log exceptions here, instead we let the person that called - // this log the exception. This ensures they are only logged once but the - // outer layers get the exceptions to report counts, etc. - @try { - [self setUp]; - @try { - NSInvocation *invocation = [self invocation]; -#if GTM_IPHONE_SIMULATOR - // We don't call [invocation invokeWithTarget:self]; because of - // Radar 8081169: NSInvalidArgumentException can't be caught - // It turns out that on iOS4 (and 3.2) exceptions thrown inside an - // [invocation invoke] on the simulator cannot be caught. - // http://openradar.appspot.com/8081169 - objc_msgSend(self, [invocation selector]); -#else - [invocation invokeWithTarget:self]; -#endif - } @catch (NSException *exception) { - e = [exception retain]; - } - [self tearDown]; - } @catch (NSException *exception) { - e = [exception retain]; - } - [pool release]; - } @catch (NSException *exception) { - e = [exception retain]; - } - if (e) { - [e autorelease]; - [e raise]; - } -} - -- (void)tearDown { -} - -- (NSString *)description { - // This matches the description OCUnit would return to you - return [NSString stringWithFormat:@"-[%@ %@]", [self class], - NSStringFromSelector([self selector])]; -} - -// Used for sorting methods below -static int MethodSort(id a, id b, void *context) { - NSInvocation *invocationA = a; - NSInvocation *invocationB = b; - const char *nameA = sel_getName([invocationA selector]); - const char *nameB = sel_getName([invocationB selector]); - return strcmp(nameA, nameB); -} - - -+ (NSArray *)testInvocations { - NSMutableArray *invocations = nil; - // Need to walk all the way up the parent classes collecting methods (in case - // a test is a subclass of another test). - Class senTestCaseClass = [SenTestCase class]; - for (Class currentClass = self; - currentClass && (currentClass != senTestCaseClass); - currentClass = class_getSuperclass(currentClass)) { - unsigned int methodCount; - Method *methods = class_copyMethodList(currentClass, &methodCount); - if (methods) { - // This handles disposing of methods for us even if an exception should fly. - [NSData dataWithBytesNoCopy:methods - length:sizeof(Method) * methodCount]; - if (!invocations) { - invocations = [NSMutableArray arrayWithCapacity:methodCount]; - } - for (size_t i = 0; i < methodCount; ++i) { - Method currMethod = methods[i]; - SEL sel = method_getName(currMethod); - char *returnType = NULL; - const char *name = sel_getName(sel); - // If it starts with test, takes 2 args (target and sel) and returns - // void run it. - if (strstr(name, "test") == name) { - returnType = method_copyReturnType(currMethod); - if (returnType) { - // This handles disposing of returnType for us even if an - // exception should fly. Length +1 for the terminator, not that - // the length really matters here, as we never reference inside - // the data block. - [NSData dataWithBytesNoCopy:returnType - length:strlen(returnType) + 1]; - } - } - // TODO: If a test class is a subclass of another, and they reuse the - // same selector name (ie-subclass overrides it), this current loop - // and test here will cause cause it to get invoked twice. To fix this - // the selector would have to be checked against all the ones already - // added, so it only gets done once. - if (returnType // True if name starts with "test" - && strcmp(returnType, @encode(void)) == 0 - && method_getNumberOfArguments(currMethod) == 2) { - NSMethodSignature *sig = [self instanceMethodSignatureForSelector:sel]; - NSInvocation *invocation - = [NSInvocation invocationWithMethodSignature:sig]; - [invocation setSelector:sel]; - [invocations addObject:invocation]; - } - } - } - } - // Match SenTestKit and run everything in alphbetical order. - [invocations sortUsingFunction:MethodSort context:nil]; - return invocations; -} - -@end - -#endif // GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST - -@implementation GTMTestCase : SenTestCase -- (void)invokeTest { - NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init]; - Class devLogClass = NSClassFromString(@"GTMUnitTestDevLog"); - if (devLogClass) { - [devLogClass performSelector:@selector(enableTracking)]; - [devLogClass performSelector:@selector(verifyNoMoreLogsExpected)]; - - } - [super invokeTest]; - if (devLogClass) { - [devLogClass performSelector:@selector(verifyNoMoreLogsExpected)]; - [devLogClass performSelector:@selector(disableTracking)]; - } - [localPool drain]; -} - -+ (BOOL)isAbstractTestCase { - NSString *name = NSStringFromClass(self); - return [name rangeOfString:@"AbstractTest"].location != NSNotFound; -} - -+ (NSArray *)testInvocations { - NSArray *invocations = nil; - if (![self isAbstractTestCase]) { - invocations = [super testInvocations]; - } - return invocations; -} - -@end diff --git a/toolkit/crashreporter/google-breakpad/src/common/md5.cc b/toolkit/crashreporter/google-breakpad/src/common/md5.cc deleted file mode 100644 index a0d9a1bdd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/md5.cc +++ /dev/null @@ -1,251 +0,0 @@ -/* - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -#include - -#include "common/md5.h" - -namespace google_breakpad { - -#ifndef WORDS_BIGENDIAN -#define byteReverse(buf, len) /* Nothing */ -#else -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - u32 t; - do { - t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(u32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif - -static void MD5Transform(u32 buf[4], u32 const in[16]); - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Init(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Update(struct MD5Context *ctx, unsigned char const *buf, size_t len) -{ - u32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((u32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (u32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (u32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Final(unsigned char digest[16], struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (u32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((u32 *) ctx->in)[14] = ctx->bits[0]; - ((u32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Transform(ctx->buf, (u32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ -} - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void MD5Transform(u32 buf[4], u32 const in[16]) -{ - u32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -} // namespace google_breakpad - diff --git a/toolkit/crashreporter/google-breakpad/src/common/md5.h b/toolkit/crashreporter/google-breakpad/src/common/md5.h deleted file mode 100644 index 2ab0ab95a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/md5.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2007 Google Inc. All Rights Reserved. -// Author: liuli@google.com (Liu Li) -#ifndef COMMON_MD5_H__ -#define COMMON_MD5_H__ - -#include - -namespace google_breakpad { - -typedef uint32_t u32; -typedef uint8_t u8; - -struct MD5Context { - u32 buf[4]; - u32 bits[2]; - u8 in[64]; -}; - -void MD5Init(struct MD5Context *ctx); - -void MD5Update(struct MD5Context *ctx, unsigned char const *buf, size_t len); - -void MD5Final(unsigned char digest[16], struct MD5Context *ctx); - -} // namespace google_breakpad - -#endif // COMMON_MD5_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/memory.h b/toolkit/crashreporter/google-breakpad/src/common/memory.h deleted file mode 100644 index 9158b50c8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/memory.h +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_MEMORY_H_ -#define GOOGLE_BREAKPAD_COMMON_MEMORY_H_ - -#include -#include -#include -#include - -#include -#include - -#if defined(MEMORY_SANITIZER) -#include -#endif - -#ifdef __APPLE__ -#define sys_mmap mmap -#define sys_munmap munmap -#define MAP_ANONYMOUS MAP_ANON -#else -#include "third_party/lss/linux_syscall_support.h" -#endif - -namespace google_breakpad { - -// This is very simple allocator which fetches pages from the kernel directly. -// Thus, it can be used even when the heap may be corrupted. -// -// There is no free operation. The pages are only freed when the object is -// destroyed. -class PageAllocator { - public: - PageAllocator() - : page_size_(getpagesize()), - last_(NULL), - current_page_(NULL), - page_offset_(0), - pages_allocated_(0) { - } - - ~PageAllocator() { - FreeAll(); - } - - void *Alloc(size_t bytes) { - if (!bytes) - return NULL; - - if (current_page_ && page_size_ - page_offset_ >= bytes) { - uint8_t *const ret = current_page_ + page_offset_; - page_offset_ += bytes; - if (page_offset_ == page_size_) { - page_offset_ = 0; - current_page_ = NULL; - } - - return ret; - } - - const size_t pages = - (bytes + sizeof(PageHeader) + page_size_ - 1) / page_size_; - uint8_t *const ret = GetNPages(pages); - if (!ret) - return NULL; - - page_offset_ = - (page_size_ - (page_size_ * pages - (bytes + sizeof(PageHeader)))) % - page_size_; - current_page_ = page_offset_ ? ret + page_size_ * (pages - 1) : NULL; - - return ret + sizeof(PageHeader); - } - - // Checks whether the page allocator owns the passed-in pointer. - // This method exists for testing pursposes only. - bool OwnsPointer(const void* p) { - for (PageHeader* header = last_; header; header = header->next) { - const char* current = reinterpret_cast(header); - if ((p >= current) && (p < current + header->num_pages * page_size_)) - return true; - } - - return false; - } - - unsigned long pages_allocated() { return pages_allocated_; } - - private: - uint8_t *GetNPages(size_t num_pages) { - void *a = sys_mmap(NULL, page_size_ * num_pages, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (a == MAP_FAILED) - return NULL; - -#if defined(MEMORY_SANITIZER) - // We need to indicate to MSan that memory allocated through sys_mmap is - // initialized, since linux_syscall_support.h doesn't have MSan hooks. - __msan_unpoison(a, page_size_ * num_pages); -#endif - - struct PageHeader *header = reinterpret_cast(a); - header->next = last_; - header->num_pages = num_pages; - last_ = header; - - pages_allocated_ += num_pages; - - return reinterpret_cast(a); - } - - void FreeAll() { - PageHeader *next; - - for (PageHeader *cur = last_; cur; cur = next) { - next = cur->next; - sys_munmap(cur, cur->num_pages * page_size_); - } - } - - struct PageHeader { - PageHeader *next; // pointer to the start of the next set of pages. - size_t num_pages; // the number of pages in this set. - }; - - const size_t page_size_; - PageHeader *last_; - uint8_t *current_page_; - size_t page_offset_; - unsigned long pages_allocated_; -}; - -// Wrapper to use with STL containers -template -struct PageStdAllocator : public std::allocator { - typedef typename std::allocator::pointer pointer; - typedef typename std::allocator::size_type size_type; - - explicit PageStdAllocator(PageAllocator& allocator) : allocator_(allocator), - stackdata_(NULL), - stackdata_size_(0) - {} - - template PageStdAllocator(const PageStdAllocator& other) - : allocator_(other.allocator_), - stackdata_(nullptr), - stackdata_size_(0) - {} - - explicit PageStdAllocator(PageAllocator& allocator, - pointer stackdata, - size_type stackdata_size) : allocator_(allocator), - stackdata_(stackdata), - stackdata_size_(stackdata_size) - {} - - inline pointer allocate(size_type n, const void* = 0) { - const size_type size = sizeof(T) * n; - if (size <= stackdata_size_) { - return stackdata_; - } - return static_cast(allocator_.Alloc(size)); - } - - inline void deallocate(pointer, size_type) { - // The PageAllocator doesn't free. - } - - template struct rebind { - typedef PageStdAllocator other; - }; - - private: - // Silly workaround for the gcc from Android's ndk (gcc 4.6), which will - // otherwise complain that `other.allocator_` is private in the constructor - // code. - template friend struct PageStdAllocator; - - PageAllocator& allocator_; - pointer stackdata_; - size_type stackdata_size_; -}; - -// A wasteful vector is a std::vector, except that it allocates memory from a -// PageAllocator. It's wasteful because, when resizing, it always allocates a -// whole new array since the PageAllocator doesn't support realloc. -template -class wasteful_vector : public std::vector > { - public: - wasteful_vector(PageAllocator* allocator, unsigned size_hint = 16) - : std::vector >(PageStdAllocator(*allocator)) { - std::vector >::reserve(size_hint); - } - protected: - wasteful_vector(PageStdAllocator allocator) - : std::vector >(allocator) {} -}; - -// auto_wasteful_vector allocates space on the stack for N entries to avoid -// using the PageAllocator for small data, while still allowing for larger data. -template -class auto_wasteful_vector : public wasteful_vector { - T stackdata_[N]; - public: - auto_wasteful_vector(PageAllocator* allocator) - : wasteful_vector( - PageStdAllocator(*allocator, - &stackdata_[0], - sizeof(stackdata_))) { - std::vector >::reserve(N); - } -}; - -} // namespace google_breakpad - -inline void* operator new(size_t nbytes, - google_breakpad::PageAllocator& allocator) { - return allocator.Alloc(nbytes); -} - -#endif // GOOGLE_BREAKPAD_COMMON_MEMORY_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/memory_range.h b/toolkit/crashreporter/google-breakpad/src/common/memory_range.h deleted file mode 100644 index 41dd2da62..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/memory_range.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_range.h: Define the google_breakpad::MemoryRange class, which -// is a lightweight wrapper with a pointer and a length to encapsulate -// a contiguous range of memory. - -#ifndef COMMON_MEMORY_RANGE_H_ -#define COMMON_MEMORY_RANGE_H_ - -#include - -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -// A lightweight wrapper with a pointer and a length to encapsulate a -// contiguous range of memory. It provides helper methods for checked -// access of a subrange of the memory. Its implemementation does not -// allocate memory or call into libc functions, and is thus safer to use -// in a crashed environment. -class MemoryRange { - public: - MemoryRange() : data_(NULL), length_(0) {} - - MemoryRange(const void* data, size_t length) { - Set(data, length); - } - - // Returns true if this memory range contains no data. - bool IsEmpty() const { - // Set() guarantees that |length_| is zero if |data_| is NULL. - return length_ == 0; - } - - // Resets to an empty range. - void Reset() { - data_ = NULL; - length_ = 0; - } - - // Sets this memory range to point to |data| and its length to |length|. - void Set(const void* data, size_t length) { - data_ = reinterpret_cast(data); - // Always set |length_| to zero if |data_| is NULL. - length_ = data ? length : 0; - } - - // Returns true if this range covers a subrange of |sub_length| bytes - // at |sub_offset| bytes of this memory range, or false otherwise. - bool Covers(size_t sub_offset, size_t sub_length) const { - // The following checks verify that: - // 1. sub_offset is within [ 0 .. length_ - 1 ] - // 2. sub_offset + sub_length is within - // [ sub_offset .. length_ ] - return sub_offset < length_ && - sub_offset + sub_length >= sub_offset && - sub_offset + sub_length <= length_; - } - - // Returns a raw data pointer to a subrange of |sub_length| bytes at - // |sub_offset| bytes of this memory range, or NULL if the subrange - // is out of bounds. - const void* GetData(size_t sub_offset, size_t sub_length) const { - return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : NULL; - } - - // Same as the two-argument version of GetData() but uses sizeof(DataType) - // as the subrange length and returns an |DataType| pointer for convenience. - template - const DataType* GetData(size_t sub_offset) const { - return reinterpret_cast( - GetData(sub_offset, sizeof(DataType))); - } - - // Returns a raw pointer to the |element_index|-th element of an array - // of elements of length |element_size| starting at |sub_offset| bytes - // of this memory range, or NULL if the element is out of bounds. - const void* GetArrayElement(size_t element_offset, - size_t element_size, - unsigned element_index) const { - size_t sub_offset = element_offset + element_index * element_size; - return GetData(sub_offset, element_size); - } - - // Same as the three-argument version of GetArrayElement() but deduces - // the element size using sizeof(ElementType) and returns an |ElementType| - // pointer for convenience. - template - const ElementType* GetArrayElement(size_t element_offset, - unsigned element_index) const { - return reinterpret_cast( - GetArrayElement(element_offset, sizeof(ElementType), element_index)); - } - - // Returns a subrange of |sub_length| bytes at |sub_offset| bytes of - // this memory range, or an empty range if the subrange is out of bounds. - MemoryRange Subrange(size_t sub_offset, size_t sub_length) const { - return Covers(sub_offset, sub_length) ? - MemoryRange(data_ + sub_offset, sub_length) : MemoryRange(); - } - - // Returns a pointer to the beginning of this memory range. - const uint8_t* data() const { return data_; } - - // Returns the length, in bytes, of this memory range. - size_t length() const { return length_; } - - private: - // Pointer to the beginning of this memory range. - const uint8_t* data_; - - // Length, in bytes, of this memory range. - size_t length_; -}; - -} // namespace google_breakpad - -#endif // COMMON_MEMORY_RANGE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/memory_range_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/memory_range_unittest.cc deleted file mode 100644 index f6cf8c8b2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/memory_range_unittest.cc +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_range_unittest.cc: Unit tests for google_breakpad::MemoryRange. - -#include "breakpad_googletest_includes.h" -#include "common/memory_range.h" - -using google_breakpad::MemoryRange; -using testing::Message; - -namespace { - -const uint32_t kBuffer[10] = { 0 }; -const size_t kBufferSize = sizeof(kBuffer); -const uint8_t* kBufferPointer = reinterpret_cast(kBuffer); - -// Test vectors for verifying Covers, GetData, and Subrange. -const struct { - bool valid; - size_t offset; - size_t length; -} kSubranges[] = { - { true, 0, 0 }, - { true, 0, 2 }, - { true, 0, kBufferSize }, - { true, 2, 0 }, - { true, 2, 4 }, - { true, 2, kBufferSize - 2 }, - { true, kBufferSize - 1, 1 }, - { false, kBufferSize, 0 }, - { false, kBufferSize, static_cast(-1) }, - { false, kBufferSize + 1, 0 }, - { false, static_cast(-1), 2 }, - { false, 1, kBufferSize }, - { false, kBufferSize - 1, 2 }, - { false, 0, static_cast(-1) }, - { false, 1, static_cast(-1) }, -}; -const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]); - -// Test vectors for verifying GetArrayElement. -const struct { - size_t offset; - size_t size; - size_t index; - const void* const pointer; -} kElements[] = { - // Valid array elemenets - { 0, 1, 0, kBufferPointer }, - { 0, 1, 1, kBufferPointer + 1 }, - { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 }, - { 0, 2, 1, kBufferPointer + 2 }, - { 0, 4, 2, kBufferPointer + 8 }, - { 0, 4, 9, kBufferPointer + 36 }, - { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, - // Invalid array elemenets - { 0, 1, kBufferSize, NULL }, - { 0, 4, 10, NULL }, - { kBufferSize - 1, 1, 1, NULL }, - { kBufferSize - 1, 2, 0, NULL }, - { kBufferSize, 1, 0, NULL }, -}; -const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); - -} // namespace - -TEST(MemoryRangeTest, DefaultConstructor) { - MemoryRange range; - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MemoryRangeTest, ConstructorWithDataAndLength) { - MemoryRange range(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); -} - -TEST(MemoryRangeTest, Reset) { - MemoryRange range; - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); - - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MemoryRangeTest, Set) { - MemoryRange range; - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Set(NULL, 0); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) { - MemoryRange range; - MemoryRange subrange = range.Subrange(0, 10); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); -} - -TEST(MemoryRangeTest, SubrangeAndGetData) { - MemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumSubranges; ++i) { - bool valid = kSubranges[i].valid; - size_t sub_offset = kSubranges[i].offset; - size_t sub_length = kSubranges[i].length; - SCOPED_TRACE(Message() << "offset=" << sub_offset - << ", length=" << sub_length); - - MemoryRange subrange = range.Subrange(sub_offset, sub_length); - if (valid) { - EXPECT_TRUE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, - range.GetData(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); - EXPECT_EQ(sub_length, subrange.length()); - } else { - EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); - } - } -} - -TEST(MemoryRangeTest, GetDataWithTemplateType) { - MemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetData(0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); - const int* int_pointer = range.GetData(0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); -} - -TEST(MemoryRangeTest, GetArrayElement) { - MemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumElements; ++i) { - size_t element_offset = kElements[i].offset; - size_t element_size = kElements[i].size; - unsigned element_index = kElements[i].index; - const void* const element_pointer = kElements[i].pointer; - SCOPED_TRACE(Message() << "offset=" << element_offset - << ", size=" << element_size - << ", index=" << element_index); - EXPECT_EQ(element_pointer, range.GetArrayElement( - element_offset, element_size, element_index)); - } -} - -TEST(MemoryRangeTest, GetArrayElmentWithTemplateType) { - MemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetArrayElement(0, 0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); - const int* int_pointer = range.GetArrayElement(0, 0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/memory_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/memory_unittest.cc deleted file mode 100644 index 8d2494c23..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/memory_unittest.cc +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "breakpad_googletest_includes.h" -#include "common/memory.h" - -using namespace google_breakpad; - -namespace { -typedef testing::Test PageAllocatorTest; -} - -TEST(PageAllocatorTest, Setup) { - PageAllocator allocator; - EXPECT_EQ(0U, allocator.pages_allocated()); -} - -TEST(PageAllocatorTest, SmallObjects) { - PageAllocator allocator; - - EXPECT_EQ(0U, allocator.pages_allocated()); - for (unsigned i = 1; i < 1024; ++i) { - uint8_t *p = reinterpret_cast(allocator.Alloc(i)); - ASSERT_FALSE(p == NULL); - memset(p, 0, i); - } -} - -TEST(PageAllocatorTest, LargeObject) { - PageAllocator allocator; - - EXPECT_EQ(0U, allocator.pages_allocated()); - uint8_t *p = reinterpret_cast(allocator.Alloc(10000)); - ASSERT_FALSE(p == NULL); - EXPECT_EQ(3U, allocator.pages_allocated()); - for (unsigned i = 1; i < 10; ++i) { - uint8_t *p = reinterpret_cast(allocator.Alloc(i)); - ASSERT_FALSE(p == NULL); - memset(p, 0, i); - } -} - -namespace { -typedef testing::Test WastefulVectorTest; -} - -TEST(WastefulVectorTest, Setup) { - PageAllocator allocator_; - wasteful_vector v(&allocator_); - ASSERT_TRUE(v.empty()); - ASSERT_EQ(v.size(), 0u); -} - -TEST(WastefulVectorTest, Simple) { - PageAllocator allocator_; - EXPECT_EQ(0U, allocator_.pages_allocated()); - wasteful_vector v(&allocator_); - - for (unsigned i = 0; i < 256; ++i) { - v.push_back(i); - ASSERT_EQ(i, v.back()); - ASSERT_EQ(&v.back(), &v[i]); - } - ASSERT_FALSE(v.empty()); - ASSERT_EQ(v.size(), 256u); - EXPECT_EQ(1U, allocator_.pages_allocated()); - for (unsigned i = 0; i < 256; ++i) - ASSERT_EQ(v[i], i); -} - -TEST(WastefulVectorTest, UsesPageAllocator) { - PageAllocator allocator_; - wasteful_vector v(&allocator_); - EXPECT_EQ(1U, allocator_.pages_allocated()); - - v.push_back(1); - ASSERT_TRUE(allocator_.OwnsPointer(&v[0])); -} - -TEST(WastefulVectorTest, AutoWastefulVector) { - PageAllocator allocator_; - EXPECT_EQ(0U, allocator_.pages_allocated()); - - auto_wasteful_vector v(&allocator_); - EXPECT_EQ(0U, allocator_.pages_allocated()); - - v.push_back(1); - EXPECT_EQ(0U, allocator_.pages_allocated()); - EXPECT_FALSE(allocator_.OwnsPointer(&v[0])); - - v.resize(4); - EXPECT_EQ(0U, allocator_.pages_allocated()); - EXPECT_FALSE(allocator_.OwnsPointer(&v[0])); - - v.resize(10); - EXPECT_EQ(1U, allocator_.pages_allocated()); - EXPECT_TRUE(allocator_.OwnsPointer(&v[0])); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/minidump_type_helper.h b/toolkit/crashreporter/google-breakpad/src/common/minidump_type_helper.h deleted file mode 100644 index 5a7d5a6a8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/minidump_type_helper.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ - -#include - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -template -struct MDTypeHelper; - -template <> -struct MDTypeHelper { - typedef MDRawDebug32 MDRawDebug; - typedef MDRawLinkMap32 MDRawLinkMap; -}; - -template <> -struct MDTypeHelper { - typedef MDRawDebug64 MDRawDebug; - typedef MDRawLinkMap64 MDRawLinkMap; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/module.cc b/toolkit/crashreporter/google-breakpad/src/common/module.cc deleted file mode 100644 index e701f1b59..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/module.cc +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright (c) 2011 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// module.cc: Implement google_breakpad::Module. See module.h. - -#include "common/module.h" - -#include -#include -#include -#include - -#include -#include - -namespace google_breakpad { - -using std::dec; -using std::endl; -using std::hex; - - -Module::Module(const string &name, const string &os, - const string &architecture, const string &id, - const string &code_id /* = "" */) : - name_(name), - os_(os), - architecture_(architecture), - id_(id), - code_id_(code_id), - load_address_(0) { } - -Module::~Module() { - for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it) - delete it->second; - for (FunctionSet::iterator it = functions_.begin(); - it != functions_.end(); ++it) { - delete *it; - } - for (StackFrameEntrySet::iterator it = stack_frame_entries_.begin(); - it != stack_frame_entries_.end(); ++it) { - delete *it; - } - for (ExternSet::iterator it = externs_.begin(); it != externs_.end(); ++it) - delete *it; -} - -void Module::SetLoadAddress(Address address) { - load_address_ = address; -} - -void Module::AddFunction(Function *function) { - // FUNC lines must not hold an empty name, so catch the problem early if - // callers try to add one. - assert(!function->name.empty()); - - // FUNCs are better than PUBLICs as they come with sizes, so remove an extern - // with the same address if present. - Extern ext(function->address); - ExternSet::iterator it_ext = externs_.find(&ext); - if (it_ext == externs_.end() && - architecture_ == "arm" && - (function->address & 0x1) == 0) { - // ARM THUMB functions have bit 0 set. ARM64 does not have THUMB. - Extern arm_thumb_ext(function->address | 0x1); - it_ext = externs_.find(&arm_thumb_ext); - } - if (it_ext != externs_.end()) { - delete *it_ext; - externs_.erase(it_ext); - } -#if _DEBUG - { - // There should be no other PUBLIC symbols that overlap with the function. - Extern debug_ext(function->address); - ExternSet::iterator it_debug = externs_.lower_bound(&ext); - assert(it_debug == externs_.end() || - (*it_debug)->address >= function->address + function->size); - } -#endif - - std::pair ret = functions_.insert(function); - if (!ret.second && (*ret.first != function)) { - // Free the duplicate that was not inserted because this Module - // now owns it. - delete function; - } -} - -void Module::AddFunctions(vector::iterator begin, - vector::iterator end) { - for (vector::iterator it = begin; it != end; ++it) - AddFunction(*it); -} - -void Module::AddStackFrameEntry(StackFrameEntry* stack_frame_entry) { - std::pair ret = - stack_frame_entries_.insert(stack_frame_entry); - if (!ret.second) { - // Free the duplicate that was not inserted because this Module - // now owns it. - delete stack_frame_entry; - } -} - -void Module::AddExtern(Extern *ext) { - std::pair ret = externs_.insert(ext); - if (!ret.second) { - // Free the duplicate that was not inserted because this Module - // now owns it. - delete ext; - } -} - -void Module::GetFunctions(vector *vec, - vector::iterator i) { - vec->insert(i, functions_.begin(), functions_.end()); -} - -void Module::GetExterns(vector *vec, - vector::iterator i) { - vec->insert(i, externs_.begin(), externs_.end()); -} - -Module::File *Module::FindFile(const string &name) { - // A tricky bit here. The key of each map entry needs to be a - // pointer to the entry's File's name string. This means that we - // can't do the initial lookup with any operation that would create - // an empty entry for us if the name isn't found (like, say, - // operator[] or insert do), because such a created entry's key will - // be a pointer the string passed as our argument. Since the key of - // a map's value type is const, we can't fix it up once we've - // created our file. lower_bound does the lookup without doing an - // insertion, and returns a good hint iterator to pass to insert. - // Our "destiny" is where we belong, whether we're there or not now. - FileByNameMap::iterator destiny = files_.lower_bound(&name); - if (destiny == files_.end() - || *destiny->first != name) { // Repeated string comparison, boo hoo. - File *file = new File(name); - file->source_id = -1; - destiny = files_.insert(destiny, - FileByNameMap::value_type(&file->name, file)); - } - return destiny->second; -} - -Module::File *Module::FindFile(const char *name) { - string name_string = name; - return FindFile(name_string); -} - -Module::File *Module::FindExistingFile(const string &name) { - FileByNameMap::iterator it = files_.find(&name); - return (it == files_.end()) ? NULL : it->second; -} - -void Module::GetFiles(vector *vec) { - vec->clear(); - for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it) - vec->push_back(it->second); -} - -void Module::GetStackFrameEntries(vector* vec) const { - vec->clear(); - vec->insert(vec->begin(), stack_frame_entries_.begin(), - stack_frame_entries_.end()); -} - -Module::StackFrameEntry* Module::FindStackFrameEntryByAddress(Address address) { - StackFrameEntry search; - search.address = address; - StackFrameEntrySet::iterator it = stack_frame_entries_.upper_bound(&search); - - if (it == stack_frame_entries_.begin()) - return NULL; - - it--; - if ((*it)->address <= address && address < (*it)->address + (*it)->size) - return *it; - - return NULL; -} - -void Module::AssignSourceIds() { - // First, give every source file an id of -1. - for (FileByNameMap::iterator file_it = files_.begin(); - file_it != files_.end(); ++file_it) { - file_it->second->source_id = -1; - } - - // Next, mark all files actually cited by our functions' line number - // info, by setting each one's source id to zero. - for (FunctionSet::const_iterator func_it = functions_.begin(); - func_it != functions_.end(); ++func_it) { - Function *func = *func_it; - for (vector::iterator line_it = func->lines.begin(); - line_it != func->lines.end(); ++line_it) - line_it->file->source_id = 0; - } - - // Finally, assign source ids to those files that have been marked. - // We could have just assigned source id numbers while traversing - // the line numbers, but doing it this way numbers the files in - // lexicographical order by name, which is neat. - int next_source_id = 0; - for (FileByNameMap::iterator file_it = files_.begin(); - file_it != files_.end(); ++file_it) { - if (!file_it->second->source_id) - file_it->second->source_id = next_source_id++; - } -} - -bool Module::ReportError() { - fprintf(stderr, "error writing symbol file: %s\n", - strerror(errno)); - return false; -} - -bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) { - for (RuleMap::const_iterator it = rule_map.begin(); - it != rule_map.end(); ++it) { - if (it != rule_map.begin()) - stream << ' '; - stream << it->first << ": " << it->second; - } - return stream.good(); -} - -bool Module::Write(std::ostream &stream, SymbolData symbol_data) { - stream << "MODULE " << os_ << " " << architecture_ << " " - << id_ << " " << name_ << endl; - if (!stream.good()) - return ReportError(); - - if (!code_id_.empty()) { - stream << "INFO CODE_ID " << code_id_ << endl; - } - - if (symbol_data != ONLY_CFI) { - AssignSourceIds(); - - // Write out files. - for (FileByNameMap::iterator file_it = files_.begin(); - file_it != files_.end(); ++file_it) { - File *file = file_it->second; - if (file->source_id >= 0) { - stream << "FILE " << file->source_id << " " << file->name << endl; - if (!stream.good()) - return ReportError(); - } - } - - // Write out functions and their lines. - for (FunctionSet::const_iterator func_it = functions_.begin(); - func_it != functions_.end(); ++func_it) { - Function *func = *func_it; - stream << "FUNC " << hex - << (func->address - load_address_) << " " - << func->size << " " - << func->parameter_size << " " - << func->name << dec << endl; - if (!stream.good()) - return ReportError(); - - for (vector::iterator line_it = func->lines.begin(); - line_it != func->lines.end(); ++line_it) { - stream << hex - << (line_it->address - load_address_) << " " - << line_it->size << " " - << dec - << line_it->number << " " - << line_it->file->source_id << endl; - if (!stream.good()) - return ReportError(); - } - } - - // Write out 'PUBLIC' records. - for (ExternSet::const_iterator extern_it = externs_.begin(); - extern_it != externs_.end(); ++extern_it) { - Extern *ext = *extern_it; - stream << "PUBLIC " << hex - << (ext->address - load_address_) << " 0 " - << ext->name << dec << endl; - } - } - - if (symbol_data != NO_CFI) { - // Write out 'STACK CFI INIT' and 'STACK CFI' records. - StackFrameEntrySet::const_iterator frame_it; - for (frame_it = stack_frame_entries_.begin(); - frame_it != stack_frame_entries_.end(); ++frame_it) { - StackFrameEntry *entry = *frame_it; - stream << "STACK CFI INIT " << hex - << (entry->address - load_address_) << " " - << entry->size << " " << dec; - if (!stream.good() - || !WriteRuleMap(entry->initial_rules, stream)) - return ReportError(); - - stream << endl; - - // Write out this entry's delta rules as 'STACK CFI' records. - for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin(); - delta_it != entry->rule_changes.end(); ++delta_it) { - stream << "STACK CFI " << hex - << (delta_it->first - load_address_) << " " << dec; - if (!stream.good() - || !WriteRuleMap(delta_it->second, stream)) - return ReportError(); - - stream << endl; - } - } - } - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/module.h b/toolkit/crashreporter/google-breakpad/src/common/module.h deleted file mode 100644 index 305f94579..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/module.h +++ /dev/null @@ -1,351 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// module.h: Define google_breakpad::Module. A Module holds debugging -// information, and can write that information out as a Breakpad -// symbol file. - -#ifndef COMMON_LINUX_MODULE_H__ -#define COMMON_LINUX_MODULE_H__ - -#include -#include -#include -#include -#include - -#include "common/symbol_data.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -using std::set; -using std::vector; -using std::map; - -// A Module represents the contents of a module, and supports methods -// for adding information produced by parsing STABS or DWARF data -// --- possibly both from the same file --- and then writing out the -// unified contents as a Breakpad-format symbol file. -class Module { - public: - // The type of addresses and sizes in a symbol table. - typedef uint64_t Address; - struct File; - struct Function; - struct Line; - struct Extern; - - // Addresses appearing in File, Function, and Line structures are - // absolute, not relative to the the module's load address. That - // is, if the module were loaded at its nominal load address, the - // addresses would be correct. - - // A source file. - struct File { - explicit File(const string &name_input) : name(name_input), source_id(0) {} - - // The name of the source file. - const string name; - - // The file's source id. The Write member function clears this - // field and assigns source ids a fresh, so any value placed here - // before calling Write will be lost. - int source_id; - }; - - // A function. - struct Function { - Function(const string &name_input, const Address &address_input) : - name(name_input), address(address_input), size(0), parameter_size(0) {} - - // For sorting by address. (Not style-guide compliant, but it's - // stupid not to put this in the struct.) - static bool CompareByAddress(const Function *x, const Function *y) { - return x->address < y->address; - } - - // The function's name. - const string name; - - // The start address and length of the function's code. - const Address address; - Address size; - - // The function's parameter size. - Address parameter_size; - - // Source lines belonging to this function, sorted by increasing - // address. - vector lines; - }; - - // A source line. - struct Line { - // For sorting by address. (Not style-guide compliant, but it's - // stupid not to put this in the struct.) - static bool CompareByAddress(const Module::Line &x, const Module::Line &y) { - return x.address < y.address; - } - - Address address, size; // The address and size of the line's code. - File *file; // The source file. - int number; // The source line number. - }; - - // An exported symbol. - struct Extern { - explicit Extern(const Address &address_input) : address(address_input) {} - const Address address; - string name; - }; - - // A map from register names to postfix expressions that recover - // their their values. This can represent a complete set of rules to - // follow at some address, or a set of changes to be applied to an - // extant set of rules. - typedef map RuleMap; - - // A map from addresses to RuleMaps, representing changes that take - // effect at given addresses. - typedef map RuleChangeMap; - - // A range of 'STACK CFI' stack walking information. An instance of - // this structure corresponds to a 'STACK CFI INIT' record and the - // subsequent 'STACK CFI' records that fall within its range. - struct StackFrameEntry { - // The starting address and number of bytes of machine code this - // entry covers. - Address address, size; - - // The initial register recovery rules, in force at the starting - // address. - RuleMap initial_rules; - - // A map from addresses to rule changes. To find the rules in - // force at a given address, start with initial_rules, and then - // apply the changes given in this map for all addresses up to and - // including the address you're interested in. - RuleChangeMap rule_changes; - }; - - struct FunctionCompare { - bool operator() (const Function *lhs, - const Function *rhs) const { - if (lhs->address == rhs->address) - return lhs->name < rhs->name; - return lhs->address < rhs->address; - } - }; - - struct ExternCompare { - bool operator() (const Extern *lhs, - const Extern *rhs) const { - return lhs->address < rhs->address; - } - }; - - struct StackFrameEntryCompare { - bool operator() (const StackFrameEntry* lhs, - const StackFrameEntry* rhs) const { - return lhs->address < rhs->address; - } - }; - - // Create a new module with the given name, operating system, - // architecture, and ID string. - Module(const string &name, const string &os, const string &architecture, - const string &id, const string &code_id = ""); - ~Module(); - - // Set the module's load address to LOAD_ADDRESS; addresses given - // for functions and lines will be written to the Breakpad symbol - // file as offsets from this address. Construction initializes this - // module's load address to zero: addresses written to the symbol - // file will be the same as they appear in the Function, Line, and - // StackFrameEntry structures. - // - // Note that this member function has no effect on addresses stored - // in the data added to this module; the Write member function - // simply subtracts off the load address from addresses before it - // prints them. Only the last load address given before calling - // Write is used. - void SetLoadAddress(Address load_address); - - // Add FUNCTION to the module. FUNCTION's name must not be empty. - // This module owns all Function objects added with this function: - // destroying the module destroys them as well. - void AddFunction(Function *function); - - // Add all the functions in [BEGIN,END) to the module. - // This module owns all Function objects added with this function: - // destroying the module destroys them as well. - void AddFunctions(vector::iterator begin, - vector::iterator end); - - // Add STACK_FRAME_ENTRY to the module. - // This module owns all StackFrameEntry objects added with this - // function: destroying the module destroys them as well. - void AddStackFrameEntry(StackFrameEntry *stack_frame_entry); - - // Add PUBLIC to the module. - // This module owns all Extern objects added with this function: - // destroying the module destroys them as well. - void AddExtern(Extern *ext); - - // If this module has a file named NAME, return a pointer to it. If - // it has none, then create one and return a pointer to the new - // file. This module owns all File objects created using these - // functions; destroying the module destroys them as well. - File *FindFile(const string &name); - File *FindFile(const char *name); - - // If this module has a file named NAME, return a pointer to it. - // Otherwise, return NULL. - File *FindExistingFile(const string &name); - - // Insert pointers to the functions added to this module at I in - // VEC. The pointed-to Functions are still owned by this module. - // (Since this is effectively a copy of the function list, this is - // mostly useful for testing; other uses should probably get a more - // appropriate interface.) - void GetFunctions(vector *vec, vector::iterator i); - - // Insert pointers to the externs added to this module at I in - // VEC. The pointed-to Externs are still owned by this module. - // (Since this is effectively a copy of the extern list, this is - // mostly useful for testing; other uses should probably get a more - // appropriate interface.) - void GetExterns(vector *vec, vector::iterator i); - - // Clear VEC and fill it with pointers to the Files added to this - // module, sorted by name. The pointed-to Files are still owned by - // this module. (Since this is effectively a copy of the file list, - // this is mostly useful for testing; other uses should probably get - // a more appropriate interface.) - void GetFiles(vector *vec); - - // Clear VEC and fill it with pointers to the StackFrameEntry - // objects that have been added to this module. (Since this is - // effectively a copy of the stack frame entry list, this is mostly - // useful for testing; other uses should probably get - // a more appropriate interface.) - void GetStackFrameEntries(vector *vec) const; - - // If this module has a StackFrameEntry whose address range covers - // ADDRESS, return it. Otherwise return NULL. - StackFrameEntry* FindStackFrameEntryByAddress(Address address); - - // Find those files in this module that are actually referred to by - // functions' line number data, and assign them source id numbers. - // Set the source id numbers for all other files --- unused by the - // source line data --- to -1. We do this before writing out the - // symbol file, at which point we omit any unused files. - void AssignSourceIds(); - - // Call AssignSourceIds, and write this module to STREAM in the - // breakpad symbol format. Return true if all goes well, or false if - // an error occurs. This method writes out: - // - a header based on the values given to the constructor, - // If symbol_data is not ONLY_CFI then: - // - the source files added via FindFile, - // - the functions added via AddFunctions, each with its lines, - // - all public records, - // If symbol_data is not NO_CFI then: - // - all CFI records. - // Addresses in the output are all relative to the load address - // established by SetLoadAddress. - bool Write(std::ostream &stream, SymbolData symbol_data); - - string name() const { return name_; } - string os() const { return os_; } - string architecture() const { return architecture_; } - string identifier() const { return id_; } - string code_identifier() const { return code_id_; } - - private: - // Report an error that has occurred writing the symbol file, using - // errno to find the appropriate cause. Return false. - static bool ReportError(); - - // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI' - // records, without a final newline. Return true if all goes well; - // if an error occurs, return false, and leave errno set. - static bool WriteRuleMap(const RuleMap &rule_map, std::ostream &stream); - - // Module header entries. - string name_, os_, architecture_, id_, code_id_; - - // The module's nominal load address. Addresses for functions and - // lines are absolute, assuming the module is loaded at this - // address. - Address load_address_; - - // Relation for maps whose keys are strings shared with some other - // structure. - struct CompareStringPtrs { - bool operator()(const string *x, const string *y) const { return *x < *y; } - }; - - // A map from filenames to File structures. The map's keys are - // pointers to the Files' names. - typedef map FileByNameMap; - - // A set containing Function structures, sorted by address. - typedef set FunctionSet; - - // A set containing Extern structures, sorted by address. - typedef set ExternSet; - - // A set containing StackFrameEntry structures, sorted by address. - typedef set StackFrameEntrySet; - - // The module owns all the files and functions that have been added - // to it; destroying the module frees the Files and Functions these - // point to. - FileByNameMap files_; // This module's source files. - FunctionSet functions_; // This module's functions. - - // The module owns all the call frame info entries that have been - // added to it. - StackFrameEntrySet stack_frame_entries_; - - // The module owns all the externs that have been added to it; - // destroying the module frees the Externs these point to. - ExternSet externs_; -}; - -} // namespace google_breakpad - -#endif // COMMON_LINUX_MODULE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/module_unittest.cc deleted file mode 100644 index 3789f9ec5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/module_unittest.cc +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// module_unittest.cc: Unit tests for google_breakpad::Module. - -#include -#include -#include -#include - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/module.h" -#include "common/using_std_string.h" - -using google_breakpad::Module; -using std::stringstream; -using std::vector; -using testing::ContainerEq; - -static Module::Function *generate_duplicate_function(const string &name) { - const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cLL; - const Module::Address DUP_SIZE = 0x200b26e605f99071LL; - const Module::Address DUP_PARAMETER_SIZE = 0xf14ac4fed48c4a99LL; - - Module::Function *function = new Module::Function(name, DUP_ADDRESS); - function->size = DUP_SIZE; - function->parameter_size = DUP_PARAMETER_SIZE; - return function; -} - -#define MODULE_NAME "name with spaces" -#define MODULE_OS "os-name" -#define MODULE_ARCH "architecture" -#define MODULE_ID "id-string" -#define MODULE_CODE_ID "code-id-string" - -TEST(Write, Header) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n", - contents.c_str()); -} - -TEST(Write, HeaderCodeId) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID, MODULE_CODE_ID); - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "INFO CODE_ID code-id-string\n", - contents.c_str()); -} - -TEST(Write, OneLineFunc) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - Module::File *file = m.FindFile("file_name.cc"); - Module::Function *function = new Module::Function( - "function_name", 0xe165bf8023b9d9abLL); - function->size = 0x1e4bb0eb1cbf5b09LL; - function->parameter_size = 0x772beee89114358aLL; - Module::Line line = { 0xe165bf8023b9d9abLL, 0x1e4bb0eb1cbf5b09LL, - file, 67519080 }; - function->lines.push_back(line); - m.AddFunction(function); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FILE 0 file_name.cc\n" - "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a" - " function_name\n" - "e165bf8023b9d9ab 1e4bb0eb1cbf5b09 67519080 0\n", - contents.c_str()); -} - -TEST(Write, RelativeLoadAddress) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Some source files. We will expect to see them in lexicographic order. - Module::File *file1 = m.FindFile("filename-b.cc"); - Module::File *file2 = m.FindFile("filename-a.cc"); - - // A function. - Module::Function *function = new Module::Function( - "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)", 0xbec774ea5dd935f3LL); - function->size = 0x2922088f98d3f6fcLL; - function->parameter_size = 0xe5e9aa008bd5f0d0LL; - - // Some source lines. The module should not sort these. - Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL, - file1, 41676901 }; - Module::Line line2 = { 0xdaf35bc123885c04LL, 0xcf621b8d324d0ebLL, - file2, 67519080 }; - function->lines.push_back(line2); - function->lines.push_back(line1); - - m.AddFunction(function); - - // Some stack information. - Module::StackFrameEntry *entry = new Module::StackFrameEntry(); - entry->address = 0x30f9e5c83323973dULL; - entry->size = 0x49fc9ca7c7c13dc2ULL; - entry->initial_rules[".cfa"] = "he was a handsome man"; - entry->initial_rules["and"] = "what i want to know is"; - entry->rule_changes[0x30f9e5c83323973eULL]["how"] = - "do you like your blueeyed boy"; - entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death"; - m.AddStackFrameEntry(entry); - - // Set the load address. Doing this after adding all the data to - // the module must work fine. - m.SetLoadAddress(0x2ab698b0b6407073LL); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FILE 0 filename-a.cc\n" - "FILE 1 filename-b.cc\n" - "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0" - " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n" - "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n" - "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n" - "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2" - " .cfa: he was a handsome man" - " and: what i want to know is\n" - "STACK CFI 6434d177ce326cb" - " Mister: Death" - " how: do you like your blueeyed boy\n", - contents.c_str()); -} - -TEST(Write, OmitUnusedFiles) { - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Create some source files. - Module::File *file1 = m.FindFile("filename1"); - m.FindFile("filename2"); // not used by any line - Module::File *file3 = m.FindFile("filename3"); - - // Create a function. - Module::Function *function = new Module::Function( - "function_name", 0x9b926d464f0b9384LL); - function->size = 0x4f524a4ba795e6a6LL; - function->parameter_size = 0xbbe8133a6641c9b7LL; - - // Source files that refer to some files, but not others. - Module::Line line1 = { 0x595fa44ebacc1086LL, 0x1e1e0191b066c5b3LL, - file1, 137850127 }; - Module::Line line2 = { 0x401ce8c8a12d25e3LL, 0x895751c41b8d2ce2LL, - file3, 28113549 }; - function->lines.push_back(line1); - function->lines.push_back(line2); - m.AddFunction(function); - - m.AssignSourceIds(); - - vector vec; - m.GetFiles(&vec); - EXPECT_EQ((size_t) 3, vec.size()); - EXPECT_STREQ("filename1", vec[0]->name.c_str()); - EXPECT_NE(-1, vec[0]->source_id); - // Expect filename2 not to be used. - EXPECT_STREQ("filename2", vec[1]->name.c_str()); - EXPECT_EQ(-1, vec[1]->source_id); - EXPECT_STREQ("filename3", vec[2]->name.c_str()); - EXPECT_NE(-1, vec[2]->source_id); - - stringstream s; - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FILE 0 filename1\n" - "FILE 1 filename3\n" - "FUNC 9b926d464f0b9384 4f524a4ba795e6a6 bbe8133a6641c9b7" - " function_name\n" - "595fa44ebacc1086 1e1e0191b066c5b3 137850127 0\n" - "401ce8c8a12d25e3 895751c41b8d2ce2 28113549 1\n", - contents.c_str()); -} - -TEST(Write, NoCFI) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Some source files. We will expect to see them in lexicographic order. - Module::File *file1 = m.FindFile("filename.cc"); - - // A function. - Module::Function *function = new Module::Function( - "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)", 0xbec774ea5dd935f3LL); - function->size = 0x2922088f98d3f6fcLL; - function->parameter_size = 0xe5e9aa008bd5f0d0LL; - - // Some source lines. The module should not sort these. - Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL, - file1, 41676901 }; - function->lines.push_back(line1); - - m.AddFunction(function); - - // Some stack information. - Module::StackFrameEntry *entry = new Module::StackFrameEntry(); - entry->address = 0x30f9e5c83323973dULL; - entry->size = 0x49fc9ca7c7c13dc2ULL; - entry->initial_rules[".cfa"] = "he was a handsome man"; - entry->initial_rules["and"] = "what i want to know is"; - entry->rule_changes[0x30f9e5c83323973eULL]["how"] = - "do you like your blueeyed boy"; - entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death"; - m.AddStackFrameEntry(entry); - - // Set the load address. Doing this after adding all the data to - // the module must work fine. - m.SetLoadAddress(0x2ab698b0b6407073LL); - - m.Write(s, NO_CFI); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FILE 0 filename.cc\n" - "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0" - " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n" - "9410dc39a798c580 1c2be6d6c5af2611 41676901 0\n", - contents.c_str()); -} - -TEST(Construct, AddFunctions) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two functions. - Module::Function *function1 = new Module::Function( - "_without_form", 0xd35024aa7ca7da5cLL); - function1->size = 0x200b26e605f99071LL; - function1->parameter_size = 0xf14ac4fed48c4a99LL; - - Module::Function *function2 = new Module::Function( - "_and_void", 0x2987743d0b35b13fLL); - function2->size = 0xb369db048deb3010LL; - function2->parameter_size = 0x938e556cb5a79988LL; - - // Put them in a vector. - vector vec; - vec.push_back(function1); - vec.push_back(function2); - - m.AddFunctions(vec.begin(), vec.end()); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988" - " _and_void\n" - "FUNC d35024aa7ca7da5c 200b26e605f99071 f14ac4fed48c4a99" - " _without_form\n", - contents.c_str()); - - // Check that m.GetFunctions returns the functions we expect. - vec.clear(); - m.GetFunctions(&vec, vec.end()); - EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function1)); - EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function2)); - EXPECT_EQ((size_t) 2, vec.size()); -} - -TEST(Construct, AddFrames) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // First STACK CFI entry, with no initial rules or deltas. - Module::StackFrameEntry *entry1 = new Module::StackFrameEntry(); - entry1->address = 0xddb5f41285aa7757ULL; - entry1->size = 0x1486493370dc5073ULL; - m.AddStackFrameEntry(entry1); - - // Second STACK CFI entry, with initial rules but no deltas. - Module::StackFrameEntry *entry2 = new Module::StackFrameEntry(); - entry2->address = 0x8064f3af5e067e38ULL; - entry2->size = 0x0de2a5ee55509407ULL; - entry2->initial_rules[".cfa"] = "I think that I shall never see"; - entry2->initial_rules["stromboli"] = "a poem lovely as a tree"; - entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest"; - m.AddStackFrameEntry(entry2); - - // Third STACK CFI entry, with initial rules and deltas. - Module::StackFrameEntry *entry3 = new Module::StackFrameEntry(); - entry3->address = 0x5e8d0db0a7075c6cULL; - entry3->size = 0x1c7edb12a7aea229ULL; - entry3->initial_rules[".cfa"] = "Whose woods are these"; - entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] = - "the village though"; - entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] = - "he will not see me stopping here"; - entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] = - "his house is in"; - entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] = - "I think I know"; - m.AddStackFrameEntry(entry3); - - // Check that Write writes STACK CFI records properly. - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229" - " .cfa: Whose woods are these\n" - "STACK CFI 36682fad3763ffff" - " .cfa: I think I know" - " stromboli: his house is in\n" - "STACK CFI 47ceb0f63c269d7f" - " calzone: the village though" - " cannoli: he will not see me stopping here\n" - "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407" - " .cfa: I think that I shall never see" - " cannoli: a tree whose hungry mouth is prest" - " stromboli: a poem lovely as a tree\n" - "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n", - contents.c_str()); - - // Check that GetStackFrameEntries works. - vector entries; - m.GetStackFrameEntries(&entries); - ASSERT_EQ(3U, entries.size()); - // Check first entry. - EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[0]->address); - EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[0]->size); - Module::RuleMap entry1_initial; - entry1_initial[".cfa"] = "Whose woods are these"; - EXPECT_THAT(entries[0]->initial_rules, ContainerEq(entry1_initial)); - Module::RuleChangeMap entry1_changes; - entry1_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know"; - entry1_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in"; - entry1_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though"; - entry1_changes[0x47ceb0f63c269d7fULL]["cannoli"] = - "he will not see me stopping here"; - EXPECT_THAT(entries[0]->rule_changes, ContainerEq(entry1_changes)); - // Check second entry. - EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address); - EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size); - ASSERT_EQ(3U, entries[1]->initial_rules.size()); - Module::RuleMap entry2_initial; - entry2_initial[".cfa"] = "I think that I shall never see"; - entry2_initial["stromboli"] = "a poem lovely as a tree"; - entry2_initial["cannoli"] = "a tree whose hungry mouth is prest"; - EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial)); - ASSERT_EQ(0U, entries[1]->rule_changes.size()); - // Check third entry. - EXPECT_EQ(0xddb5f41285aa7757ULL, entries[2]->address); - EXPECT_EQ(0x1486493370dc5073ULL, entries[2]->size); - ASSERT_EQ(0U, entries[2]->initial_rules.size()); - ASSERT_EQ(0U, entries[2]->rule_changes.size()); -} - -TEST(Construct, UniqueFiles) { - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - Module::File *file1 = m.FindFile("foo"); - Module::File *file2 = m.FindFile(string("bar")); - Module::File *file3 = m.FindFile(string("foo")); - Module::File *file4 = m.FindFile("bar"); - EXPECT_NE(file1, file2); - EXPECT_EQ(file1, file3); - EXPECT_EQ(file2, file4); - EXPECT_EQ(file1, m.FindExistingFile("foo")); - EXPECT_TRUE(m.FindExistingFile("baz") == NULL); -} - -TEST(Construct, DuplicateFunctions) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two functions. - Module::Function *function1 = generate_duplicate_function("_without_form"); - Module::Function *function2 = generate_duplicate_function("_without_form"); - - m.AddFunction(function1); - m.AddFunction(function2); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99" - " _without_form\n", - contents.c_str()); -} - -TEST(Construct, FunctionsWithSameAddress) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two functions. - Module::Function *function1 = generate_duplicate_function("_without_form"); - Module::Function *function2 = generate_duplicate_function("_and_void"); - - m.AddFunction(function1); - m.AddFunction(function2); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" - "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99" - " _and_void\n" - "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99" - " _without_form\n", - contents.c_str()); -} - -// Externs should be written out as PUBLIC records, sorted by -// address. -TEST(Construct, Externs) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two externs. - Module::Extern *extern1 = new Module::Extern(0xffff); - extern1->name = "_abc"; - Module::Extern *extern2 = new Module::Extern(0xaaaa); - extern2->name = "_xyz"; - - m.AddExtern(extern1); - m.AddExtern(extern2); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - - EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " " - MODULE_ID " " MODULE_NAME "\n" - "PUBLIC aaaa 0 _xyz\n" - "PUBLIC ffff 0 _abc\n", - contents.c_str()); -} - -// Externs with the same address should only keep the first entry -// added. -TEST(Construct, DuplicateExterns) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two externs. - Module::Extern *extern1 = new Module::Extern(0xffff); - extern1->name = "_xyz"; - Module::Extern *extern2 = new Module::Extern(0xffff); - extern2->name = "_abc"; - - m.AddExtern(extern1); - m.AddExtern(extern2); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - - EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " " - MODULE_ID " " MODULE_NAME "\n" - "PUBLIC ffff 0 _xyz\n", - contents.c_str()); -} - -// If there exists an extern and a function at the same address, only write -// out the FUNC entry. -TEST(Construct, FunctionsAndExternsWithSameAddress) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // Two externs. - Module::Extern* extern1 = new Module::Extern(0xabc0); - extern1->name = "abc"; - Module::Extern* extern2 = new Module::Extern(0xfff0); - extern2->name = "xyz"; - - m.AddExtern(extern1); - m.AddExtern(extern2); - - Module::Function* function = new Module::Function("_xyz", 0xfff0); - function->size = 0x10; - function->parameter_size = 0; - m.AddFunction(function); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - - EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " " - MODULE_ID " " MODULE_NAME "\n" - "FUNC fff0 10 0 _xyz\n" - "PUBLIC abc0 0 abc\n", - contents.c_str()); -} - -// If there exists an extern and a function at the same address, only write -// out the FUNC entry. For ARM THUMB, the extern that comes from the ELF -// symbol section has bit 0 set. -TEST(Construct, FunctionsAndThumbExternsWithSameAddress) { - stringstream s; - Module m(MODULE_NAME, MODULE_OS, "arm", MODULE_ID); - - // Two THUMB externs. - Module::Extern* thumb_extern1 = new Module::Extern(0xabc1); - thumb_extern1->name = "thumb_abc"; - Module::Extern* thumb_extern2 = new Module::Extern(0xfff1); - thumb_extern2->name = "thumb_xyz"; - - Module::Extern* arm_extern1 = new Module::Extern(0xcc00); - arm_extern1->name = "arm_func"; - - m.AddExtern(thumb_extern1); - m.AddExtern(thumb_extern2); - m.AddExtern(arm_extern1); - - // The corresponding function from the DWARF debug data have the actual - // address. - Module::Function* function = new Module::Function("_thumb_xyz", 0xfff0); - function->size = 0x10; - function->parameter_size = 0; - m.AddFunction(function); - - m.Write(s, ALL_SYMBOL_DATA); - string contents = s.str(); - - EXPECT_STREQ("MODULE " MODULE_OS " arm " - MODULE_ID " " MODULE_NAME "\n" - "FUNC fff0 10 0 _thumb_xyz\n" - "PUBLIC abc1 0 thumb_abc\n" - "PUBLIC cc00 0 arm_func\n", - contents.c_str()); -} - -TEST(Lookup, StackFrameEntries) { - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); - - // First STACK CFI entry, with no initial rules or deltas. - Module::StackFrameEntry *entry1 = new Module::StackFrameEntry(); - entry1->address = 0x2000; - entry1->size = 0x900; - m.AddStackFrameEntry(entry1); - - // Second STACK CFI entry, with initial rules but no deltas. - Module::StackFrameEntry *entry2 = new Module::StackFrameEntry(); - entry2->address = 0x3000; - entry2->size = 0x900; - entry2->initial_rules[".cfa"] = "I think that I shall never see"; - entry2->initial_rules["stromboli"] = "a poem lovely as a tree"; - entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest"; - m.AddStackFrameEntry(entry2); - - // Third STACK CFI entry, with initial rules and deltas. - Module::StackFrameEntry *entry3 = new Module::StackFrameEntry(); - entry3->address = 0x1000; - entry3->size = 0x900; - entry3->initial_rules[".cfa"] = "Whose woods are these"; - entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] = - "the village though"; - entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] = - "he will not see me stopping here"; - entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] = - "his house is in"; - entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] = - "I think I know"; - m.AddStackFrameEntry(entry3); - - Module::StackFrameEntry* s = m.FindStackFrameEntryByAddress(0x1000); - EXPECT_EQ(entry3, s); - s = m.FindStackFrameEntryByAddress(0x18FF); - EXPECT_EQ(entry3, s); - - s = m.FindStackFrameEntryByAddress(0x1900); - EXPECT_EQ((Module::StackFrameEntry*)NULL, s); - s = m.FindStackFrameEntryByAddress(0x1A00); - EXPECT_EQ((Module::StackFrameEntry*)NULL, s); - - s = m.FindStackFrameEntryByAddress(0x2000); - EXPECT_EQ(entry1, s); - s = m.FindStackFrameEntryByAddress(0x28FF); - EXPECT_EQ(entry1, s); - - s = m.FindStackFrameEntryByAddress(0x3000); - EXPECT_EQ(entry2, s); - s = m.FindStackFrameEntryByAddress(0x38FF); - EXPECT_EQ(entry2, s); - - s = m.FindStackFrameEntryByAddress(0x3900); - EXPECT_EQ((Module::StackFrameEntry*)NULL, s); - s = m.FindStackFrameEntryByAddress(0x3A00); - EXPECT_EQ((Module::StackFrameEntry*)NULL, s); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/moz.build b/toolkit/crashreporter/google-breakpad/src/common/moz.build deleted file mode 100644 index 7bb6e9b6d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/moz.build +++ /dev/null @@ -1,72 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -if CONFIG['OS_ARCH'] in ('Darwin', 'Linux'): - DIRS += ['dwarf'] - -UNIFIED_SOURCES += [ - 'convert_UTF.c', - 'string_conversion.cc', -] - -if CONFIG['OS_ARCH'] != 'WINNT': - UNIFIED_SOURCES += [ - 'md5.cc', - ] - -if CONFIG['OS_ARCH'] == 'Linux': - HOST_DEFINES['HAVE_A_OUT_H'] = True -elif CONFIG['OS_ARCH'] == 'Darwin': - HOST_DEFINES['HAVE_MACH_O_NLIST_H'] = True - HOST_SOURCES += [ - 'stabs_reader.cc', - 'stabs_to_module.cc', - ] - if CONFIG['HOST_OS_ARCH'] != 'Darwin': - HOST_CXXFLAGS += [ - '-I%s/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/' % TOPSRCDIR, - ] - -if CONFIG['OS_ARCH'] != 'WINNT': - HOST_SOURCES += [ - 'arm_ex_reader.cc', - 'arm_ex_to_module.cc', - 'convert_UTF.c', - 'dwarf_cfi_to_module.cc', - 'dwarf_cu_to_module.cc', - 'dwarf_line_to_module.cc', - 'language.cc', - 'md5.cc', - 'module.cc', - 'string_conversion.cc', - ] - if CONFIG['OS_ARCH'] == 'Darwin': - HOST_CXXFLAGS += [ - '-stdlib=libc++', - ] - HOST_CXXFLAGS += [ - '-O2', - '-g', - ] - HostLibrary('host_breakpad_common_s') - -if CONFIG['OS_TARGET'] == 'Android': - # We don't support unifying assembly files. - SOURCES += [ - 'android/breakpad_getcontext.S', - ] - LOCAL_INCLUDES += [ - '/toolkit/crashreporter/google-breakpad/src/common/android/include', - ] - -Library('breakpad_common_s') - -# We allow warnings for third-party code that can be updated from upstream. -ALLOW_COMPILER_WARNINGS = True - -FINAL_LIBRARY = 'xul' - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/common/scoped_ptr.h b/toolkit/crashreporter/google-breakpad/src/common/scoped_ptr.h deleted file mode 100644 index d137c1868..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/scoped_ptr.h +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Scopers help you manage ownership of a pointer, helping you easily manage the -// a pointer within a scope, and automatically destroying the pointer at the -// end of a scope. There are two main classes you will use, which correspond -// to the operators new/delete and new[]/delete[]. -// -// Example usage (scoped_ptr): -// { -// scoped_ptr foo(new Foo("wee")); -// } // foo goes out of scope, releasing the pointer with it. -// -// { -// scoped_ptr foo; // No pointer managed. -// foo.reset(new Foo("wee")); // Now a pointer is managed. -// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. -// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. -// foo->Method(); // Foo::Method() called. -// foo.get()->Method(); // Foo::Method() called. -// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer -// // manages a pointer. -// foo.reset(new Foo("wee4")); // foo manages a pointer again. -// foo.reset(); // Foo("wee4") destroyed, foo no longer -// // manages a pointer. -// } // foo wasn't managing a pointer, so nothing was destroyed. -// -// Example usage (scoped_array): -// { -// scoped_array foo(new Foo[100]); -// foo.get()->Method(); // Foo::Method on the 0th element. -// foo[10].Method(); // Foo::Method on the 10th element. -// } - -#ifndef COMMON_SCOPED_PTR_H_ -#define COMMON_SCOPED_PTR_H_ - -// This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array, scoped_ptr_malloc. - -#include -#include -#include - -namespace google_breakpad { - -// A scoped_ptr is like a T*, except that the destructor of scoped_ptr -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr owns the T object that it points to. -// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. -// Also like T*, scoped_ptr is thread-compatible, and once you -// dereference it, you get the threadsafety guarantees of T. -// -// The size of a scoped_ptr is small: -// sizeof(scoped_ptr) == sizeof(C*) -template -class scoped_ptr { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = NULL) : ptr_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_ptr() { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != ptr_) { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - ptr_ = p; - } - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - C* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - C* get() const { return ptr_; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return ptr_ == p; } - bool operator!=(C* p) const { return ptr_ != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - C* tmp = ptr_; - ptr_ = p2.ptr_; - p2.ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = ptr_; - ptr_ = NULL; - return retVal; - } - - private: - C* ptr_; - - // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't - // make sense, and if C2 == C, it still doesn't make sense because you should - // never have the same object owned by two different scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; - - // Disallow evil constructors - scoped_ptr(const scoped_ptr&); - void operator=(const scoped_ptr&); -}; - -// Free functions -template -void swap(scoped_ptr& p1, scoped_ptr& p2) { - p1.swap(p2); -} - -template -bool operator==(C* p1, const scoped_ptr& p2) { - return p1 == p2.get(); -} - -template -bool operator!=(C* p1, const scoped_ptr& p2) { - return p1 != p2.get(); -} - -// scoped_array is like scoped_ptr, except that the caller must allocate -// with new [] and the destructor deletes objects with delete []. -// -// As with scoped_ptr, a scoped_array either points to an object -// or is NULL. A scoped_array owns the object that it points to. -// scoped_array is thread-compatible, and once you index into it, -// the returned objects have only the threadsafety guarantees of T. -// -// Size: sizeof(scoped_array) == sizeof(C*) -template -class scoped_array { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to intializing with NULL. - // There is no way to create an uninitialized scoped_array. - // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_array() { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != array_) { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - array_ = p; - } - } - - // Get one element of the current object. - // Will assert() if there is no current object, or index i is negative. - C& operator[](ptrdiff_t i) const { - assert(i >= 0); - assert(array_ != NULL); - return array_[i]; - } - - // Get a pointer to the zeroth element of the current object. - // If there is no current object, return NULL. - C* get() const { - return array_; - } - - // Comparison operators. - // These return whether two scoped_array refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return array_ == p; } - bool operator!=(C* p) const { return array_ != p; } - - // Swap two scoped arrays. - void swap(scoped_array& p2) { - C* tmp = array_; - array_ = p2.array_; - p2.array_ = tmp; - } - - // Release an array. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = array_; - array_ = NULL; - return retVal; - } - - private: - C* array_; - - // Forbid comparison of different scoped_array types. - template bool operator==(scoped_array const& p2) const; - template bool operator!=(scoped_array const& p2) const; - - // Disallow evil constructors - scoped_array(const scoped_array&); - void operator=(const scoped_array&); -}; - -// Free functions -template -void swap(scoped_array& p1, scoped_array& p2) { - p1.swap(p2); -} - -template -bool operator==(C* p1, const scoped_array& p2) { - return p1 == p2.get(); -} - -template -bool operator!=(C* p1, const scoped_array& p2) { - return p1 != p2.get(); -} - -// This class wraps the c library function free() in a class that can be -// passed as a template argument to scoped_ptr_malloc below. -class ScopedPtrMallocFree { - public: - inline void operator()(void* x) const { - free(x); - } -}; - -// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a -// second template argument, the functor used to free the object. - -template -class scoped_ptr_malloc { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with an allocator that matches the - // Free functor. For the default Free functor, this is malloc, calloc, or - // realloc. - explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} - - // Destructor. If there is a C object, call the Free functor. - ~scoped_ptr_malloc() { - reset(); - } - - // Reset. Calls the Free functor on the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (ptr_ != p) { - FreeProc free_proc; - free_proc(ptr_); - ptr_ = p; - } - } - - // Get the current object. - // operator* and operator-> will cause an assert() failure if there is - // no current object. - C& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - - C* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - - C* get() const { - return ptr_; - } - - // Comparison operators. - // These return whether a scoped_ptr_malloc and a plain pointer refer - // to the same object, not just to two different but equal objects. - // For compatibility with the boost-derived implementation, these - // take non-const arguments. - bool operator==(C* p) const { - return ptr_ == p; - } - - bool operator!=(C* p) const { - return ptr_ != p; - } - - // Swap two scoped pointers. - void swap(scoped_ptr_malloc & b) { - C* tmp = b.ptr_; - b.ptr_ = ptr_; - ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* tmp = ptr_; - ptr_ = NULL; - return tmp; - } - - private: - C* ptr_; - - // no reason to use these: each scoped_ptr_malloc should have its own object - template - bool operator==(scoped_ptr_malloc const& p) const; - template - bool operator!=(scoped_ptr_malloc const& p) const; - - // Disallow evil constructors - scoped_ptr_malloc(const scoped_ptr_malloc&); - void operator=(const scoped_ptr_malloc&); -}; - -template inline -void swap(scoped_ptr_malloc& a, scoped_ptr_malloc& b) { - a.swap(b); -} - -template inline -bool operator==(C* p, const scoped_ptr_malloc& b) { - return p == b.get(); -} - -template inline -bool operator!=(C* p, const scoped_ptr_malloc& b) { - return p != b.get(); -} - -} // namespace google_breakpad - -#endif // COMMON_SCOPED_PTR_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.cc b/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.cc deleted file mode 100644 index e0a74ceeb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/simple_string_dictionary.h" - -namespace google_breakpad { - -namespace { - -// In C++98 (ISO 14882), section 9.5.1 says that a union cannot have a member -// with a non-trivial ctor, copy ctor, dtor, or assignment operator. Use this -// property to ensure that Entry remains POD. -union Compile_Assert { - NonAllocatingMap<1, 1, 1>::Entry Compile_Assert__entry_must_be_pod; -}; - -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.h b/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.h deleted file mode 100644 index d2ab17fda..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary.h +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_SIMPLE_STRING_DICTIONARY_H_ -#define COMMON_SIMPLE_STRING_DICTIONARY_H_ - -#include -#include - -#include "common/basictypes.h" - -namespace google_breakpad { - -// Opaque type for the serialized representation of a NonAllocatingMap. One is -// created in NonAllocatingMap::Serialize and can be deserialized using one of -// the constructors. -struct SerializedNonAllocatingMap; - -// NonAllocatingMap is an implementation of a map/dictionary collection that -// uses a fixed amount of storage, so that it does not perform any dynamic -// allocations for its operations. -// -// The actual map storage (the Entry) is guaranteed to be POD, so that it can -// be transmitted over various IPC mechanisms. -// -// The template parameters control the amount of storage used for the key, -// value, and map. The KeySize and ValueSize are measured in bytes, not glyphs, -// and includes space for a \0 byte. This gives space for KeySize-1 and -// ValueSize-1 characters in an entry. NumEntries is the total number of -// entries that will fit in the map. -template -class NonAllocatingMap { - public: - // Constant and publicly accessible versions of the template parameters. - static const size_t key_size = KeySize; - static const size_t value_size = ValueSize; - static const size_t num_entries = NumEntries; - - // An Entry object is a single entry in the map. If the key is a 0-length - // NUL-terminated string, the entry is empty. - struct Entry { - char key[KeySize]; - char value[ValueSize]; - - bool is_active() const { - return key[0] != '\0'; - } - }; - - // An Iterator can be used to iterate over all the active entries in a - // NonAllocatingMap. - class Iterator { - public: - explicit Iterator(const NonAllocatingMap& map) - : map_(map), - current_(0) { - } - - // Returns the next entry in the map, or NULL if at the end of the - // collection. - const Entry* Next() { - while (current_ < map_.num_entries) { - const Entry* entry = &map_.entries_[current_++]; - if (entry->is_active()) { - return entry; - } - } - return NULL; - } - - private: - const NonAllocatingMap& map_; - size_t current_; - - DISALLOW_COPY_AND_ASSIGN(Iterator); - }; - - NonAllocatingMap() : entries_() { - } - - NonAllocatingMap(const NonAllocatingMap& other) { - *this = other; - } - - NonAllocatingMap& operator=(const NonAllocatingMap& other) { - assert(other.key_size == key_size); - assert(other.value_size == value_size); - assert(other.num_entries == num_entries); - if (other.key_size == key_size && other.value_size == value_size && - other.num_entries == num_entries) { - memcpy(entries_, other.entries_, sizeof(entries_)); - } - return *this; - } - - // Constructs a map from its serialized form. |map| should be the out - // parameter from Serialize() and |size| should be its return value. - NonAllocatingMap(const SerializedNonAllocatingMap* map, size_t size) { - assert(size == sizeof(entries_)); - if (size == sizeof(entries_)) { - memcpy(entries_, map, size); - } - } - - // Returns the number of active key/value pairs. The upper limit for this - // is NumEntries. - size_t GetCount() const { - size_t count = 0; - for (size_t i = 0; i < num_entries; ++i) { - if (entries_[i].is_active()) { - ++count; - } - } - return count; - } - - // Given |key|, returns its corresponding |value|. |key| must not be NULL. If - // the key is not found, NULL is returned. - const char* GetValueForKey(const char* key) const { - assert(key); - if (!key) - return NULL; - - const Entry* entry = GetConstEntryForKey(key); - if (!entry) - return NULL; - - return entry->value; - } - - // Stores |value| into |key|, replacing the existing value if |key| is - // already present. |key| must not be NULL. If |value| is NULL, the key is - // removed from the map. If there is no more space in the map, then the - // operation silently fails. - void SetKeyValue(const char* key, const char* value) { - if (!value) { - RemoveKey(key); - return; - } - - assert(key); - if (!key) - return; - - // Key must not be an empty string. - assert(key[0] != '\0'); - if (key[0] == '\0') - return; - - Entry* entry = GetEntryForKey(key); - - // If it does not yet exist, attempt to insert it. - if (!entry) { - for (size_t i = 0; i < num_entries; ++i) { - if (!entries_[i].is_active()) { - entry = &entries_[i]; - - strncpy(entry->key, key, key_size); - entry->key[key_size - 1] = '\0'; - - break; - } - } - } - - // If the map is out of space, entry will be NULL. - if (!entry) - return; - -#ifndef NDEBUG - // Sanity check that the key only appears once. - int count = 0; - for (size_t i = 0; i < num_entries; ++i) { - if (strncmp(entries_[i].key, key, key_size) == 0) - ++count; - } - assert(count == 1); -#endif - - strncpy(entry->value, value, value_size); - entry->value[value_size - 1] = '\0'; - } - - // Given |key|, removes any associated value. |key| must not be NULL. If - // the key is not found, this is a noop. - void RemoveKey(const char* key) { - assert(key); - if (!key) - return; - - Entry* entry = GetEntryForKey(key); - if (entry) { - entry->key[0] = '\0'; - entry->value[0] = '\0'; - } - -#ifndef NDEBUG - assert(GetEntryForKey(key) == NULL); -#endif - } - - // Places a serialized version of the map into |map| and returns the size. - // Both of these should be passed to the deserializing constructor. Note that - // the serialized |map| is scoped to the lifetime of the non-serialized - // instance of this class. The |map| can be copied across IPC boundaries. - size_t Serialize(const SerializedNonAllocatingMap** map) const { - *map = reinterpret_cast(entries_); - return sizeof(entries_); - } - - private: - const Entry* GetConstEntryForKey(const char* key) const { - for (size_t i = 0; i < num_entries; ++i) { - if (strncmp(key, entries_[i].key, key_size) == 0) { - return &entries_[i]; - } - } - return NULL; - } - - Entry* GetEntryForKey(const char* key) { - return const_cast(GetConstEntryForKey(key)); - } - - Entry entries_[NumEntries]; -}; - -// For historical reasons this specialized version is available with the same -// size factors as a previous implementation. -typedef NonAllocatingMap<256, 256, 64> SimpleStringDictionary; - -} // namespace google_breakpad - -#endif // COMMON_SIMPLE_STRING_DICTIONARY_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary_unittest.cc deleted file mode 100644 index 34f4b9ef5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/simple_string_dictionary_unittest.cc +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "breakpad_googletest_includes.h" -#include "common/simple_string_dictionary.h" - -namespace google_breakpad { - -TEST(NonAllocatingMapTest, Entry) { - typedef NonAllocatingMap<5, 9, 15> TestMap; - TestMap map; - - const TestMap::Entry* entry = TestMap::Iterator(map).Next(); - EXPECT_FALSE(entry); - - // Try setting a key/value and then verify. - map.SetKeyValue("key1", "value1"); - entry = TestMap::Iterator(map).Next(); - ASSERT_TRUE(entry); - EXPECT_STREQ(entry->key, "key1"); - EXPECT_STREQ(entry->value, "value1"); - - // Try setting a new value. - map.SetKeyValue("key1", "value3"); - EXPECT_STREQ(entry->value, "value3"); - - // Make sure the key didn't change. - EXPECT_STREQ(entry->key, "key1"); - - // Clear the entry and verify the key and value are empty strings. - map.RemoveKey("key1"); - EXPECT_FALSE(entry->is_active()); - EXPECT_EQ(strlen(entry->key), 0u); - EXPECT_EQ(strlen(entry->value), 0u); -} - -TEST(NonAllocatingMapTest, SimpleStringDictionary) { - // Make a new dictionary - SimpleStringDictionary dict; - - // Set three distinct values on three keys - dict.SetKeyValue("key1", "value1"); - dict.SetKeyValue("key2", "value2"); - dict.SetKeyValue("key3", "value3"); - - EXPECT_NE(dict.GetValueForKey("key1"), "value1"); - EXPECT_NE(dict.GetValueForKey("key2"), "value2"); - EXPECT_NE(dict.GetValueForKey("key3"), "value3"); - EXPECT_EQ(dict.GetCount(), 3u); - // try an unknown key - EXPECT_FALSE(dict.GetValueForKey("key4")); - - // Remove a key - dict.RemoveKey("key3"); - - // Now make sure it's not there anymore - EXPECT_FALSE(dict.GetValueForKey("key3")); - - // Remove by setting value to NULL - dict.SetKeyValue("key2", NULL); - - // Now make sure it's not there anymore - EXPECT_FALSE(dict.GetValueForKey("key2")); -} - -TEST(NonAllocatingMapTest, CopyAndAssign) { - NonAllocatingMap<10, 10, 10> map; - map.SetKeyValue("one", "a"); - map.SetKeyValue("two", "b"); - map.SetKeyValue("three", "c"); - map.RemoveKey("two"); - EXPECT_EQ(2u, map.GetCount()); - - // Test copy. - NonAllocatingMap<10, 10, 10> map_copy(map); - EXPECT_EQ(2u, map_copy.GetCount()); - EXPECT_STREQ("a", map_copy.GetValueForKey("one")); - EXPECT_STREQ("c", map_copy.GetValueForKey("three")); - map_copy.SetKeyValue("four", "d"); - EXPECT_STREQ("d", map_copy.GetValueForKey("four")); - EXPECT_FALSE(map.GetValueForKey("four")); - - // Test assign. - NonAllocatingMap<10, 10, 10> map_assign; - map_assign = map; - EXPECT_EQ(2u, map_assign.GetCount()); - EXPECT_STREQ("a", map_assign.GetValueForKey("one")); - EXPECT_STREQ("c", map_assign.GetValueForKey("three")); - map_assign.SetKeyValue("four", "d"); - EXPECT_STREQ("d", map_assign.GetValueForKey("four")); - EXPECT_FALSE(map.GetValueForKey("four")); - - map.RemoveKey("one"); - EXPECT_FALSE(map.GetValueForKey("one")); - EXPECT_STREQ("a", map_copy.GetValueForKey("one")); - EXPECT_STREQ("a", map_assign.GetValueForKey("one")); -} - -// Add a bunch of values to the dictionary, remove some entries in the middle, -// and then add more. -TEST(NonAllocatingMapTest, Iterator) { - SimpleStringDictionary* dict = new SimpleStringDictionary(); - ASSERT_TRUE(dict); - - char key[SimpleStringDictionary::key_size]; - char value[SimpleStringDictionary::value_size]; - - const int kDictionaryCapacity = SimpleStringDictionary::num_entries; - const int kPartitionIndex = kDictionaryCapacity - 5; - - // We assume at least this size in the tests below - ASSERT_GE(kDictionaryCapacity, 64); - - // We'll keep track of the number of key/value pairs we think should - // be in the dictionary - int expectedDictionarySize = 0; - - // Set a bunch of key/value pairs like key0/value0, key1/value1, ... - for (int i = 0; i < kPartitionIndex; ++i) { - sprintf(key, "key%d", i); - sprintf(value, "value%d", i); - dict->SetKeyValue(key, value); - } - expectedDictionarySize = kPartitionIndex; - - // set a couple of the keys twice (with the same value) - should be nop - dict->SetKeyValue("key2", "value2"); - dict->SetKeyValue("key4", "value4"); - dict->SetKeyValue("key15", "value15"); - - // Remove some random elements in the middle - dict->RemoveKey("key7"); - dict->RemoveKey("key18"); - dict->RemoveKey("key23"); - dict->RemoveKey("key31"); - expectedDictionarySize -= 4; // we just removed four key/value pairs - - // Set some more key/value pairs like key59/value59, key60/value60, ... - for (int i = kPartitionIndex; i < kDictionaryCapacity; ++i) { - sprintf(key, "key%d", i); - sprintf(value, "value%d", i); - dict->SetKeyValue(key, value); - } - expectedDictionarySize += kDictionaryCapacity - kPartitionIndex; - - // Now create an iterator on the dictionary - SimpleStringDictionary::Iterator iter(*dict); - - // We then verify that it iterates through exactly the number of - // key/value pairs we expect, and that they match one-for-one with what we - // would expect. The ordering of the iteration does not matter... - - // used to keep track of number of occurrences found for key/value pairs - int count[kDictionaryCapacity]; - memset(count, 0, sizeof(count)); - - int totalCount = 0; - - const SimpleStringDictionary::Entry* entry; - while ((entry = iter.Next())) { - totalCount++; - - // Extract keyNumber from a string of the form key - int keyNumber; - sscanf(entry->key, "key%d", &keyNumber); - - // Extract valueNumber from a string of the form value - int valueNumber; - sscanf(entry->value, "value%d", &valueNumber); - - // The value number should equal the key number since that's how we set them - EXPECT_EQ(keyNumber, valueNumber); - - // Key and value numbers should be in proper range: - // 0 <= keyNumber < kDictionaryCapacity - bool isKeyInGoodRange = - (keyNumber >= 0 && keyNumber < kDictionaryCapacity); - bool isValueInGoodRange = - (valueNumber >= 0 && valueNumber < kDictionaryCapacity); - EXPECT_TRUE(isKeyInGoodRange); - EXPECT_TRUE(isValueInGoodRange); - - if (isKeyInGoodRange && isValueInGoodRange) { - ++count[keyNumber]; - } - } - - // Make sure each of the key/value pairs showed up exactly one time, except - // for the ones which we removed. - for (size_t i = 0; i < kDictionaryCapacity; ++i) { - // Skip over key7, key18, key23, and key31, since we removed them - if (!(i == 7 || i == 18 || i == 23 || i == 31)) { - EXPECT_EQ(count[i], 1); - } - } - - // Make sure the number of iterations matches the expected dictionary size. - EXPECT_EQ(totalCount, expectedDictionarySize); -} - - -TEST(NonAllocatingMapTest, AddRemove) { - NonAllocatingMap<5, 7, 6> map; - map.SetKeyValue("rob", "ert"); - map.SetKeyValue("mike", "pink"); - map.SetKeyValue("mark", "allays"); - - EXPECT_EQ(3u, map.GetCount()); - EXPECT_STREQ("ert", map.GetValueForKey("rob")); - EXPECT_STREQ("pink", map.GetValueForKey("mike")); - EXPECT_STREQ("allays", map.GetValueForKey("mark")); - - map.RemoveKey("mike"); - - EXPECT_EQ(2u, map.GetCount()); - EXPECT_FALSE(map.GetValueForKey("mike")); - - map.SetKeyValue("mark", "mal"); - EXPECT_EQ(2u, map.GetCount()); - EXPECT_STREQ("mal", map.GetValueForKey("mark")); - - map.RemoveKey("mark"); - EXPECT_EQ(1u, map.GetCount()); - EXPECT_FALSE(map.GetValueForKey("mark")); -} - -TEST(NonAllocatingMapTest, Serialize) { - typedef NonAllocatingMap<4, 5, 7> TestMap; - TestMap map; - map.SetKeyValue("one", "abc"); - map.SetKeyValue("two", "def"); - map.SetKeyValue("tre", "hig"); - - EXPECT_STREQ("abc", map.GetValueForKey("one")); - EXPECT_STREQ("def", map.GetValueForKey("two")); - EXPECT_STREQ("hig", map.GetValueForKey("tre")); - - const SerializedNonAllocatingMap* serialized; - size_t size = map.Serialize(&serialized); - - SerializedNonAllocatingMap* serialized_copy = - reinterpret_cast(malloc(size)); - ASSERT_TRUE(serialized_copy); - memcpy(serialized_copy, serialized, size); - - TestMap deserialized(serialized_copy, size); - free(serialized_copy); - - EXPECT_EQ(3u, deserialized.GetCount()); - EXPECT_STREQ("abc", deserialized.GetValueForKey("one")); - EXPECT_STREQ("def", deserialized.GetValueForKey("two")); - EXPECT_STREQ("hig", deserialized.GetValueForKey("tre")); -} - -// Running out of space shouldn't crash. -TEST(NonAllocatingMapTest, OutOfSpace) { - NonAllocatingMap<3, 2, 2> map; - map.SetKeyValue("a", "1"); - map.SetKeyValue("b", "2"); - map.SetKeyValue("c", "3"); - EXPECT_EQ(2u, map.GetCount()); - EXPECT_FALSE(map.GetValueForKey("c")); -} - -#ifndef NDEBUG - -TEST(NonAllocatingMapTest, NullKey) { - NonAllocatingMap<4, 6, 6> map; - ASSERT_DEATH(map.SetKeyValue(NULL, "hello"), ""); - - map.SetKeyValue("hi", "there"); - ASSERT_DEATH(map.GetValueForKey(NULL), ""); - EXPECT_STREQ("there", map.GetValueForKey("hi")); - - ASSERT_DEATH(map.GetValueForKey(NULL), ""); - map.RemoveKey("hi"); - EXPECT_EQ(0u, map.GetCount()); -} - -#endif // !NDEBUG - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.cc b/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.cc deleted file mode 100644 index 168d0b287..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.cc +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/scoped_ptr.h" -#include "common/solaris/dump_symbols.h" -#include "common/solaris/file_id.h" -#include "common/solaris/guid_creator.h" - -// This namespace contains helper functions. -namespace { - -using std::make_pair; - -#if defined(_LP64) -typedef Elf64_Sym Elf_Sym; -#else -typedef Elf32_Sym Elf_Sym; -#endif - -// Symbol table entry from stabs. Sun CC specific. -struct slist { - // String table index. - unsigned int n_strx; - // Stab type. - unsigned char n_type; - char n_other; - short n_desc; - unsigned long n_value; -}; - -// Symbol table entry -struct SymbolEntry { - // Offset from the start of the file. - GElf_Addr offset; - // Function size. - GElf_Word size; -}; - -// Infomation of a line. -struct LineInfo { - // Offset from start of the function. - // Load from stab symbol. - GElf_Off rva_to_func; - // Offset from base of the loading binary. - GElf_Off rva_to_base; - // Size of the line. - // The first line: equals to rva_to_func. - // The other lines: the difference of rva_to_func of the line and - // rva_to_func of the previous N_SLINE. - uint32_t size; - // Line number. - uint32_t line_num; -}; - -// Information of a function. -struct FuncInfo { - // Name of the function. - const char *name; - // Offset from the base of the loading address. - GElf_Off rva_to_base; - // Virtual address of the function. - // Load from stab symbol. - GElf_Addr addr; - // Size of the function. - // Equal to rva_to_func of the last function line. - uint32_t size; - // Total size of stack parameters. - uint32_t stack_param_size; - // Line information array. - std::vector line_info; -}; - -// Information of a source file. -struct SourceFileInfo { - // Name of the source file. - const char *name; - // Starting address of the source file. - GElf_Addr addr; - // Id of the source file. - int source_id; - // Functions information. - std::vector func_info; -}; - -struct CompareString { - bool operator()(const char *s1, const char *s2) const { - return strcmp(s1, s2) < 0; - } -}; - -typedef std::map SymbolMap; - -// Information of a symbol table. -// This is the root of all types of symbol. -struct SymbolInfo { - std::vector source_file_info; - // Symbols information. - SymbolMap symbol_entries; -}; - -// Stab section name. -const char *kStabName = ".stab"; - -// Stab str section name. -const char *kStabStrName = ".stabstr"; - -// Symtab section name. -const char *kSymtabName = ".symtab"; - -// Strtab section name. -const char *kStrtabName = ".strtab"; - -// Default buffer lenght for demangle. -const int demangleLen = 20000; - -// Offset to the string table. -uint64_t stringOffset = 0; - -// Update the offset to the start of the string index of the next -// object module for every N_ENDM stabs. -inline void RecalculateOffset(struct slist* cur_list, char *stabstr) { - while ((--cur_list)->n_strx == 0) ; - stringOffset += cur_list->n_strx; - - char *temp = stabstr + stringOffset; - while (*temp != '\0') { - ++stringOffset; - ++temp; - } - // Skip the extra '\0' - ++stringOffset; -} - -// Demangle using demangle library on Solaris. -std::string Demangle(const char *mangled) { - int status = 0; - std::string str(mangled); - char *demangled = (char *)malloc(demangleLen); - - if (!demangled) { - fprintf(stderr, "no enough memory.\n"); - goto out; - } - - if ((status = cplus_demangle(mangled, demangled, demangleLen)) == - DEMANGLE_ESPACE) { - fprintf(stderr, "incorrect demangle.\n"); - goto out; - } - - str = demangled; - free(demangled); - -out: - return str; -} - -bool WriteFormat(int fd, const char *fmt, ...) { - va_list list; - char buffer[4096]; - ssize_t expected, written; - va_start(list, fmt); - vsnprintf(buffer, sizeof(buffer), fmt, list); - expected = strlen(buffer); - written = write(fd, buffer, strlen(buffer)); - va_end(list); - return expected == written; -} - -bool IsValidElf(const GElf_Ehdr *elf_header) { - return memcmp(elf_header, ELFMAG, SELFMAG) == 0; -} - -static bool FindSectionByName(Elf *elf, const char *name, - int shstrndx, - GElf_Shdr *shdr) { - assert(name != NULL); - - if (strlen(name) == 0) - return false; - - Elf_Scn *scn = NULL; - - while ((scn = elf_nextscn(elf, scn)) != NULL) { - if (gelf_getshdr(scn, shdr) == (GElf_Shdr *)0) { - fprintf(stderr, "failed to read section header: %s\n", elf_errmsg(0)); - return false; - } - - const char *section_name = elf_strptr(elf, shstrndx, shdr->sh_name); - if (!section_name) { - fprintf(stderr, "Section name error: %s\n", elf_errmsg(-1)); - continue; - } - - if (strcmp(section_name, name) == 0) - return true; - } - - return false; -} - -// The parameter size is used for FPO-optimized code, and -// this is all tied up with the debugging data for Windows x86. -// Set it to 0 on Solaris. -int LoadStackParamSize(struct slist *list, - struct slist *list_end, - struct FuncInfo *func_info) { - struct slist *cur_list = list; - int step = 1; - while (cur_list < list_end && cur_list->n_type == N_PSYM) { - ++cur_list; - ++step; - } - - func_info->stack_param_size = 0; - return step; -} - -int LoadLineInfo(struct slist *list, - struct slist *list_end, - struct FuncInfo *func_info) { - struct slist *cur_list = list; - do { - // Skip non line information. - while (cur_list < list_end && cur_list->n_type != N_SLINE) { - // Only exit when got another function, or source file, or end stab. - if (cur_list->n_type == N_FUN || cur_list->n_type == N_SO || - cur_list->n_type == N_ENDM) { - return cur_list - list; - } - ++cur_list; - } - struct LineInfo line; - while (cur_list < list_end && cur_list->n_type == N_SLINE) { - line.rva_to_func = cur_list->n_value; - // n_desc is a signed short - line.line_num = (unsigned short)cur_list->n_desc; - func_info->line_info.push_back(line); - ++cur_list; - } - if (cur_list == list_end && cur_list->n_type == N_ENDM) - break; - } while (list < list_end); - - return cur_list - list; -} - -int LoadFuncSymbols(struct slist *list, - struct slist *list_end, - char *stabstr, - GElf_Word base, - struct SourceFileInfo *source_file_info) { - struct slist *cur_list = list; - assert(cur_list->n_type == N_SO); - ++cur_list; - - source_file_info->func_info.clear(); - while (cur_list < list_end) { - // Go until the function symbol. - while (cur_list < list_end && cur_list->n_type != N_FUN) { - if (cur_list->n_type == N_SO) { - return cur_list - list; - } - ++cur_list; - if (cur_list->n_type == N_ENDM) - RecalculateOffset(cur_list, stabstr); - continue; - } - while (cur_list->n_type == N_FUN) { - struct FuncInfo func_info; - memset(&func_info, 0, sizeof(func_info)); - func_info.name = stabstr + cur_list->n_strx + stringOffset; - // The n_value field is always 0 from stab generated by Sun CC. - // TODO(Alfred): Find the correct value. - func_info.addr = cur_list->n_value; - ++cur_list; - if (cur_list->n_type == N_ENDM) - RecalculateOffset(cur_list, stabstr); - if (cur_list->n_type != N_ESYM && cur_list->n_type != N_ISYM && - cur_list->n_type != N_FUN) { - // Stack parameter size. - cur_list += LoadStackParamSize(cur_list, list_end, &func_info); - // Line info. - cur_list += LoadLineInfo(cur_list, list_end, &func_info); - } - if (cur_list < list_end && cur_list->n_type == N_ENDM) - RecalculateOffset(cur_list, stabstr); - // Functions in this module should have address bigger than the module - // starting address. - // - // These two values are always 0 with Sun CC. - // TODO(Alfred): Get the correct value or remove the condition statement. - if (func_info.addr >= source_file_info->addr) { - source_file_info->func_info.push_back(func_info); - } - } - } - return cur_list - list; -} - -// Compute size and rva information based on symbols loaded from stab section. -bool ComputeSizeAndRVA(struct SymbolInfo *symbols) { - std::vector *sorted_files = - &(symbols->source_file_info); - SymbolMap *symbol_entries = &(symbols->symbol_entries); - for (size_t i = 0; i < sorted_files->size(); ++i) { - struct SourceFileInfo &source_file = (*sorted_files)[i]; - std::vector *sorted_functions = &(source_file.func_info); - int func_size = sorted_functions->size(); - - for (size_t j = 0; j < func_size; ++j) { - struct FuncInfo &func_info = (*sorted_functions)[j]; - int line_count = func_info.line_info.size(); - - // Discard the ending part of the name. - std::string func_name(func_info.name); - std::string::size_type last_colon = func_name.find_first_of(':'); - if (last_colon != std::string::npos) - func_name = func_name.substr(0, last_colon); - - // Fine the symbol offset from the loading address and size by name. - SymbolMap::const_iterator it = symbol_entries->find(func_name.c_str()); - if (it->second) { - func_info.rva_to_base = it->second->offset; - func_info.size = (line_count == 0) ? 0 : it->second->size; - } else { - func_info.rva_to_base = 0; - func_info.size = 0; - } - - // Compute function and line size. - for (size_t k = 0; k < line_count; ++k) { - struct LineInfo &line_info = func_info.line_info[k]; - - line_info.rva_to_base = line_info.rva_to_func + func_info.rva_to_base; - if (k == line_count - 1) { - line_info.size = func_info.size - line_info.rva_to_func; - } else { - struct LineInfo &next_line = func_info.line_info[k + 1]; - line_info.size = next_line.rva_to_func - line_info.rva_to_func; - } - } // for each line. - } // for each function. - } // for each source file. - for (SymbolMap::iterator it = symbol_entries->begin(); - it != symbol_entries->end(); ++it) { - free(it->second); - } - return true; -} - -bool LoadAllSymbols(const GElf_Shdr *stab_section, - const GElf_Shdr *stabstr_section, - GElf_Word base, - struct SymbolInfo *symbols) { - if (stab_section == NULL || stabstr_section == NULL) - return false; - - char *stabstr = - reinterpret_cast(stabstr_section->sh_offset + base); - struct slist *lists = - reinterpret_cast(stab_section->sh_offset + base); - int nstab = stab_section->sh_size / sizeof(struct slist); - int source_id = 0; - - // First pass, load all symbols from the object file. - for (int i = 0; i < nstab; ) { - int step = 1; - struct slist *cur_list = lists + i; - if (cur_list->n_type == N_SO) { - // FUNC
- struct SourceFileInfo source_file_info; - source_file_info.name = stabstr + cur_list->n_strx + stringOffset; - // The n_value field is always 0 from stab generated by Sun CC. - // TODO(Alfred): Find the correct value. - source_file_info.addr = cur_list->n_value; - if (strchr(source_file_info.name, '.')) - source_file_info.source_id = source_id++; - else - source_file_info.source_id = -1; - step = LoadFuncSymbols(cur_list, lists + nstab - 1, stabstr, - base, &source_file_info); - symbols->source_file_info.push_back(source_file_info); - } - i += step; - } - // Second pass, compute the size of functions and lines. - return ComputeSizeAndRVA(symbols); -} - -bool LoadSymbols(Elf *elf, GElf_Ehdr *elf_header, struct SymbolInfo *symbols, - void *obj_base) { - GElf_Word base = reinterpret_cast(obj_base); - - const GElf_Shdr *sections = - reinterpret_cast(elf_header->e_shoff + base); - GElf_Shdr stab_section; - if (!FindSectionByName(elf, kStabName, elf_header->e_shstrndx, - &stab_section)) { - fprintf(stderr, "Stab section not found.\n"); - return false; - } - GElf_Shdr stabstr_section; - if (!FindSectionByName(elf, kStabStrName, elf_header->e_shstrndx, - &stabstr_section)) { - fprintf(stderr, "Stabstr section not found.\n"); - return false; - } - GElf_Shdr symtab_section; - if (!FindSectionByName(elf, kSymtabName, elf_header->e_shstrndx, - &symtab_section)) { - fprintf(stderr, "Symtab section not found.\n"); - return false; - } - GElf_Shdr strtab_section; - if (!FindSectionByName(elf, kStrtabName, elf_header->e_shstrndx, - &strtab_section)) { - fprintf(stderr, "Strtab section not found.\n"); - return false; - } - - Elf_Sym *symbol = (Elf_Sym *)((char *)base + symtab_section.sh_offset); - for (int i = 0; i < symtab_section.sh_size/symtab_section.sh_entsize; ++i) { - struct SymbolEntry *symbol_entry = - (struct SymbolEntry *)malloc(sizeof(struct SymbolEntry)); - const char *name = reinterpret_cast( - strtab_section.sh_offset + (GElf_Word)base + symbol->st_name); - symbol_entry->offset = symbol->st_value; - symbol_entry->size = symbol->st_size; - symbols->symbol_entries.insert(make_pair(name, symbol_entry)); - ++symbol; - } - - - // Load symbols. - return LoadAllSymbols(&stab_section, &stabstr_section, base, symbols); -} - -bool WriteModuleInfo(int fd, GElf_Half arch, const std::string &obj_file) { - const char *arch_name = NULL; - if (arch == EM_386) - arch_name = "x86"; - else if (arch == EM_X86_64) - arch_name = "x86_64"; - else if (arch == EM_SPARC32PLUS) - arch_name = "SPARC_32+"; - else { - printf("Please add more ARCH support\n"); - return false; - } - - unsigned char identifier[16]; - google_breakpad::FileID file_id(obj_file.c_str()); - if (file_id.ElfFileIdentifier(identifier)) { - char identifier_str[40]; - file_id.ConvertIdentifierToString(identifier, - identifier_str, sizeof(identifier_str)); - std::string filename = obj_file; - size_t slash_pos = obj_file.find_last_of("/"); - if (slash_pos != std::string::npos) - filename = obj_file.substr(slash_pos + 1); - return WriteFormat(fd, "MODULE solaris %s %s %s\n", arch_name, - identifier_str, filename.c_str()); - } - return false; -} - -bool WriteSourceFileInfo(int fd, const struct SymbolInfo &symbols) { - for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { - if (symbols.source_file_info[i].source_id != -1) { - const char *name = symbols.source_file_info[i].name; - if (!WriteFormat(fd, "FILE %d %s\n", - symbols.source_file_info[i].source_id, name)) - return false; - } - } - return true; -} - -bool WriteOneFunction(int fd, int source_id, - const struct FuncInfo &func_info){ - // Discard the ending part of the name. - std::string func_name(func_info.name); - std::string::size_type last_colon = func_name.find_last_of(':'); - if (last_colon != std::string::npos) - func_name = func_name.substr(0, last_colon); - func_name = Demangle(func_name.c_str()); - - if (func_info.size <= 0) - return true; - - // rva_to_base could be unsigned long(32 bit) or unsigned long long(64 bit). - if (WriteFormat(fd, "FUNC %llx %x %d %s\n", - (long long)func_info.rva_to_base, - func_info.size, - func_info.stack_param_size, - func_name.c_str())) { - for (size_t i = 0; i < func_info.line_info.size(); ++i) { - const struct LineInfo &line_info = func_info.line_info[i]; - if (line_info.line_num == 0) - return true; - if (!WriteFormat(fd, "%llx %x %d %d\n", - (long long)line_info.rva_to_base, - line_info.size, - line_info.line_num, - source_id)) - return false; - } - return true; - } - return false; -} - -bool WriteFunctionInfo(int fd, const struct SymbolInfo &symbols) { - for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { - const struct SourceFileInfo &file_info = symbols.source_file_info[i]; - for (size_t j = 0; j < file_info.func_info.size(); ++j) { - const struct FuncInfo &func_info = file_info.func_info[j]; - if (!WriteOneFunction(fd, file_info.source_id, func_info)) - return false; - } - } - return true; -} - -bool DumpStabSymbols(int fd, const struct SymbolInfo &symbols) { - return WriteSourceFileInfo(fd, symbols) && - WriteFunctionInfo(fd, symbols); -} - -// -// FDWrapper -// -// Wrapper class to make sure opened file is closed. -// -class FDWrapper { - public: - explicit FDWrapper(int fd) : - fd_(fd) { - } - ~FDWrapper() { - if (fd_ != -1) - close(fd_); - } - int get() { - return fd_; - } - int release() { - int fd = fd_; - fd_ = -1; - return fd; - } - private: - int fd_; -}; - -// -// MmapWrapper -// -// Wrapper class to make sure mapped regions are unmapped. -// -class MmapWrapper { - public: - MmapWrapper(void *mapped_address, size_t mapped_size) : - base_(mapped_address), size_(mapped_size) { - } - ~MmapWrapper() { - if (base_ != NULL) { - assert(size_ > 0); - munmap((char *)base_, size_); - } - } - void release() { - base_ = NULL; - size_ = 0; - } - - private: - void *base_; - size_t size_; -}; - -} // namespace - -namespace google_breakpad { - -class AutoElfEnder { - public: - AutoElfEnder(Elf *elf) : elf_(elf) {} - ~AutoElfEnder() { if (elf_) elf_end(elf_); } - private: - Elf *elf_; -}; - - -bool DumpSymbols::WriteSymbolFile(const std::string &obj_file, int sym_fd) { - if (elf_version(EV_CURRENT) == EV_NONE) { - fprintf(stderr, "elf_version() failed: %s\n", elf_errmsg(0)); - return false; - } - - int obj_fd = open(obj_file.c_str(), O_RDONLY); - if (obj_fd < 0) - return false; - FDWrapper obj_fd_wrapper(obj_fd); - struct stat st; - if (fstat(obj_fd, &st) != 0 && st.st_size <= 0) - return false; - void *obj_base = mmap(NULL, st.st_size, - PROT_READ, MAP_PRIVATE, obj_fd, 0); - if (obj_base == MAP_FAILED) - return false; - MmapWrapper map_wrapper(obj_base, st.st_size); - GElf_Ehdr elf_header; - Elf *elf = elf_begin(obj_fd, ELF_C_READ, NULL); - AutoElfEnder elfEnder(elf); - - if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr *)NULL) { - fprintf(stderr, "failed to read elf header: %s\n", elf_errmsg(-1)); - return false; - } - - if (!IsValidElf(&elf_header)) { - fprintf(stderr, "header magic doesn't match\n"); - return false; - } - struct SymbolInfo symbols; - if (!LoadSymbols(elf, &elf_header, &symbols, obj_base)) - return false; - // Write to symbol file. - if (WriteModuleInfo(sym_fd, elf_header.e_machine, obj_file) && - DumpStabSymbols(sym_fd, symbols)) - return true; - - return false; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.h b/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.h deleted file mode 100644 index 7f4baadcf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// dump_symbols.cc: Implements a Solaris stab debugging format dumper. -// -// Author: Alfred Peng - -#ifndef COMMON_SOLARIS_DUMP_SYMBOLS_H__ -#define COMMON_SOLARIS_DUMP_SYMBOLS_H__ - -#include - -namespace google_breakpad { - -class DumpSymbols { - public: - bool WriteSymbolFile(const std::string &obj_file, - int sym_fd); -}; - -} // namespace google_breakpad - -#endif // COMMON_SOLARIS_DUMP_SYMBOLS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.cc b/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.cc deleted file mode 100644 index 643a14629..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_id.cc: Return a unique identifier for a file -// -// See file_id.h for documentation -// -// Author: Alfred Peng - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common/md5.h" -#include "common/solaris/file_id.h" -#include "common/solaris/message_output.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -class AutoElfEnder { - public: - AutoElfEnder(Elf *elf) : elf_(elf) {} - ~AutoElfEnder() { if (elf_) elf_end(elf_); } - private: - Elf *elf_; -}; - -// Find the text section in elf object file. -// Return the section start address and the size. -static bool FindElfTextSection(int fd, const void *elf_base, - const void **text_start, - int *text_size) { - assert(text_start); - assert(text_size); - - *text_start = NULL; - *text_size = 0; - - if (elf_version(EV_CURRENT) == EV_NONE) { - print_message2(2, "elf_version() failed: %s\n", elf_errmsg(0)); - return false; - } - - GElf_Ehdr elf_header; - lseek(fd, 0L, 0); - Elf *elf = elf_begin(fd, ELF_C_READ, NULL); - AutoElfEnder elfEnder(elf); - - if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr *)NULL) { - print_message2(2, "failed to read elf header: %s\n", elf_errmsg(-1)); - return false; - } - - if (elf_header.e_ident[EI_MAG0] != ELFMAG0 || - elf_header.e_ident[EI_MAG1] != ELFMAG1 || - elf_header.e_ident[EI_MAG2] != ELFMAG2 || - elf_header.e_ident[EI_MAG3] != ELFMAG3) { - print_message1(2, "header magic doesn't match\n"); - return false; - } - - static const char kTextSectionName[] = ".text"; - const GElf_Shdr *text_section = NULL; - Elf_Scn *scn = NULL; - GElf_Shdr shdr; - - while ((scn = elf_nextscn(elf, scn)) != NULL) { - if (gelf_getshdr(scn, &shdr) == (GElf_Shdr *)0) { - print_message2(2, "failed to read section header: %s\n", elf_errmsg(0)); - return false; - } - - if (shdr.sh_type == SHT_PROGBITS) { - const char *section_name = elf_strptr(elf, elf_header.e_shstrndx, - shdr.sh_name); - if (!section_name) { - print_message2(2, "Section name error: %s\n", elf_errmsg(-1)); - continue; - } - - if (strcmp(section_name, kTextSectionName) == 0) { - text_section = &shdr; - break; - } - } - } - if (text_section != NULL && text_section->sh_size > 0) { - *text_start = (char *)elf_base + text_section->sh_offset; - *text_size = text_section->sh_size; - return true; - } - - return false; -} - -FileID::FileID(const char *path) { - strcpy(path_, path); -} - -class AutoCloser { - public: - AutoCloser(int fd) : fd_(fd) {} - ~AutoCloser() { if (fd_) close(fd_); } - private: - int fd_; -}; - -bool FileID::ElfFileIdentifier(unsigned char identifier[16]) { - int fd = 0; - if ((fd = open(path_, O_RDONLY)) < 0) - return false; - - AutoCloser autocloser(fd); - struct stat st; - if (fstat(fd, &st) != 0 || st.st_size <= 0) - return false; - - void *base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (base == MAP_FAILED) - return false; - - bool success = false; - const void *text_section = NULL; - int text_size = 0; - - if (FindElfTextSection(fd, base, &text_section, &text_size)) { - MD5Context md5; - MD5Init(&md5); - MD5Update(&md5, (const unsigned char *)text_section, text_size); - MD5Final(identifier, &md5); - success = true; - } - - munmap((char *)base, st.st_size); - return success; -} - -// static -bool FileID::ConvertIdentifierToString(const unsigned char identifier[16], - char *buffer, int buffer_length) { - if (buffer_length < 34) - return false; - - int buffer_idx = 0; - for (int idx = 0; idx < 16; ++idx) { - int hi = (identifier[idx] >> 4) & 0x0F; - int lo = (identifier[idx]) & 0x0F; - - buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi; - buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo; - } - - // Add an extra "0" by the end. - buffer[buffer_idx++] = '0'; - - // NULL terminate - buffer[buffer_idx] = 0; - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.h b/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.h deleted file mode 100644 index 375e85751..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_id.h: Return a unique identifier for a file -// -// Author: Alfred Peng - -#ifndef COMMON_SOLARIS_FILE_ID_H__ -#define COMMON_SOLARIS_FILE_ID_H__ - -#include - -namespace google_breakpad { - -class FileID { - public: - FileID(const char *path); - ~FileID() {}; - - // Load the identifier for the elf file path specified in the constructor into - // |identifier|. Return false if the identifier could not be created for the - // file. - // The current implementation will return the MD5 hash of the file's bytes. - bool ElfFileIdentifier(unsigned char identifier[16]); - - // Convert the |identifier| data to a NULL terminated string. The string will - // be formatted as a MDCVInfoPDB70 struct. - // The |buffer| should be at least 34 bytes long to receive all of the data - // and termination. Shorter buffers will return false. - static bool ConvertIdentifierToString(const unsigned char identifier[16], - char *buffer, int buffer_length); - - private: - // Storage for the path specified - char path_[PATH_MAX]; -}; - -} // namespace google_breakpad - -#endif // COMMON_SOLARIS_FILE_ID_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.cc b/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.cc deleted file mode 100644 index e9e6c6f5d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include - -#include -#include -#include - -#include "common/solaris/guid_creator.h" - -// -// GUIDGenerator -// -// This class is used to generate random GUID. -// Currently use random number to generate a GUID. This should be OK since -// we don't expect crash to happen very offen. -// -class GUIDGenerator { - public: - GUIDGenerator() { - srandom(time(NULL)); - } - - bool CreateGUID(GUID *guid) const { - guid->data1 = random(); - guid->data2 = (uint16_t)(random()); - guid->data3 = (uint16_t)(random()); - *reinterpret_cast(&guid->data4[0]) = random(); - *reinterpret_cast(&guid->data4[4]) = random(); - return true; - } -}; - -// Guid generator. -const GUIDGenerator kGuidGenerator; - -bool CreateGUID(GUID *guid) { - return kGuidGenerator.CreateGUID(guid); -} - -// Parse guid to string. -bool GUIDToString(const GUID *guid, char *buf, int buf_len) { - // Should allow more space the the max length of GUID. - assert(buf_len > kGUIDStringLength); - int num = snprintf(buf, buf_len, kGUIDFormatString, - guid->data1, guid->data2, guid->data3, - *reinterpret_cast(&(guid->data4[0])), - *reinterpret_cast(&(guid->data4[4]))); - if (num != kGUIDStringLength) - return false; - - buf[num] = '\0'; - return true; -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.h b/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.h deleted file mode 100644 index 4aee3a1c2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#ifndef COMMON_SOLARIS_GUID_CREATOR_H__ -#define COMMON_SOLARIS_GUID_CREATOR_H__ - -#include "google_breakpad/common/minidump_format.h" - -typedef MDGUID GUID; - -// Format string for parsing GUID. -#define kGUIDFormatString "%08x-%04x-%04x-%08x-%08x" -// Length of GUID string. Don't count the ending '\0'. -#define kGUIDStringLength 36 - -// Create a guid. -bool CreateGUID(GUID *guid); - -// Get the string from guid. -bool GUIDToString(const GUID *guid, char *buf, int buf_len); - -#endif // COMMON_SOLARIS_GUID_CREATOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/message_output.h b/toolkit/crashreporter/google-breakpad/src/common/solaris/message_output.h deleted file mode 100644 index 3e3b1d465..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/message_output.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#ifndef COMMON_SOLARIS_MESSAGE_OUTPUT_H__ -#define COMMON_SOLARIS_MESSAGE_OUTPUT_H__ - -namespace google_breakpad { - -const int MESSAGE_MAX = 1000; - -// Message output macros. -// snprintf doesn't operate heap on Solaris, while printf and fprintf do. -// Use snprintf here to avoid heap allocation. -#define print_message1(std, message) \ - char buffer[MESSAGE_MAX]; \ - int len = snprintf(buffer, MESSAGE_MAX, message); \ - write(std, buffer, len) - -#define print_message2(std, message, para) \ - char buffer[MESSAGE_MAX]; \ - int len = snprintf(buffer, MESSAGE_MAX, message, para); \ - write(std, buffer, len); - -} // namespace google_breakpad - -#endif // COMMON_SOLARIS_MESSAGE_OUTPUT_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/solaris/moz.build b/toolkit/crashreporter/google-breakpad/src/common/solaris/moz.build deleted file mode 100644 index c91b96fc7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/solaris/moz.build +++ /dev/null @@ -1,34 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'dump_symbols.cc', - 'file_id.cc', - 'guid_creator.cc', -] - -HostLibrary('host_breakpad_solaris_common_s') - -Library('breakpad_solaris_common_s') - -# not compiling http_upload.cc currently -# since it depends on libcurl -HOST_SOURCES += [ - 'dump_symbols.cc', - 'file_id.cc', - 'guid_creator.cc', -] -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../..', -] - diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc deleted file mode 100644 index 6019fc7ee..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// This file implements the google_breakpad::StabsReader class. -// See stabs_reader.h. - -#include "common/stabs_reader.h" - -#include -#include -#include - -#include - -#include "common/using_std_string.h" - -using std::vector; - -namespace google_breakpad { - -StabsReader::EntryIterator::EntryIterator(const ByteBuffer *buffer, - bool big_endian, size_t value_size) - : value_size_(value_size), cursor_(buffer, big_endian) { - // Actually, we could handle weird sizes just fine, but they're - // probably mistakes --- expressed in bits, say. - assert(value_size == 4 || value_size == 8); - entry_.index = 0; - Fetch(); -} - -void StabsReader::EntryIterator::Fetch() { - cursor_ - .Read(4, false, &entry_.name_offset) - .Read(1, false, &entry_.type) - .Read(1, false, &entry_.other) - .Read(2, false, &entry_.descriptor) - .Read(value_size_, false, &entry_.value); - entry_.at_end = !cursor_; -} - -StabsReader::StabsReader(const uint8_t *stab, size_t stab_size, - const uint8_t *stabstr, size_t stabstr_size, - bool big_endian, size_t value_size, bool unitized, - StabsHandler *handler) - : entries_(stab, stab_size), - strings_(stabstr, stabstr_size), - iterator_(&entries_, big_endian, value_size), - unitized_(unitized), - handler_(handler), - string_offset_(0), - next_cu_string_offset_(0), - current_source_file_(NULL) { } - -const char *StabsReader::SymbolString() { - ptrdiff_t offset = string_offset_ + iterator_->name_offset; - if (offset < 0 || (size_t) offset >= strings_.Size()) { - handler_->Warning("symbol %d: name offset outside the string section\n", - iterator_->index); - // Return our null string, to keep our promise about all names being - // taken from the string section. - offset = 0; - } - return reinterpret_cast(strings_.start + offset); -} - -bool StabsReader::Process() { - while (!iterator_->at_end) { - if (iterator_->type == N_SO) { - if (! ProcessCompilationUnit()) - return false; - } else if (iterator_->type == N_UNDF && unitized_) { - // In unitized STABS (including Linux STABS, and pretty much anything - // else that puts STABS data in sections), at the head of each - // compilation unit's entries there is an N_UNDF stab giving the - // number of symbols in the compilation unit, and the number of bytes - // that compilation unit's strings take up in the .stabstr section. - // Each CU's strings are separate; the n_strx values are offsets - // within the current CU's portion of the .stabstr section. - // - // As an optimization, the GNU linker combines all the - // compilation units into one, with a single N_UNDF at the - // beginning. However, other linkers, like Gold, do not perform - // this optimization. - string_offset_ = next_cu_string_offset_; - next_cu_string_offset_ = iterator_->value; - ++iterator_; - } -#if defined(HAVE_MACH_O_NLIST_H) - // Export symbols in Mach-O binaries look like this. - // This is necessary in order to be able to dump symbols - // from OS X system libraries. - else if ((iterator_->type & N_STAB) == 0 && - (iterator_->type & N_TYPE) == N_SECT) { - ProcessExtern(); - } -#endif - else { - ++iterator_; - } - } - return true; -} - -bool StabsReader::ProcessCompilationUnit() { - assert(!iterator_->at_end && iterator_->type == N_SO); - - // There may be an N_SO entry whose name ends with a slash, - // indicating the directory in which the compilation occurred. - // The build directory defaults to NULL. - const char *build_directory = NULL; - { - const char *name = SymbolString(); - if (name[0] && name[strlen(name) - 1] == '/') { - build_directory = name; - ++iterator_; - } - } - - // We expect to see an N_SO entry with a filename next, indicating - // the start of the compilation unit. - { - if (iterator_->at_end || iterator_->type != N_SO) - return true; - const char *name = SymbolString(); - if (name[0] == '\0') { - // This seems to be a stray end-of-compilation-unit marker; - // consume it, but don't report the end, since we didn't see a - // beginning. - ++iterator_; - return true; - } - current_source_file_ = name; - } - - if (! handler_->StartCompilationUnit(current_source_file_, - iterator_->value, - build_directory)) - return false; - - ++iterator_; - - // The STABS documentation says that some compilers may emit - // additional N_SO entries with names immediately following the - // first, and that they should be ignored. However, the original - // Breakpad STABS reader doesn't ignore them, so we won't either. - - // Process the body of the compilation unit, up to the next N_SO. - while (!iterator_->at_end && iterator_->type != N_SO) { - if (iterator_->type == N_FUN) { - if (! ProcessFunction()) - return false; - } else if (iterator_->type == N_SLINE) { - // Mac OS X STABS place SLINE records before functions. - Line line; - // The value of an N_SLINE entry that appears outside a function is - // the absolute address of the line. - line.address = iterator_->value; - line.filename = current_source_file_; - // The n_desc of a N_SLINE entry is the line number. It's a - // signed 16-bit field; line numbers from 32768 to 65535 are - // stored as n-65536. - line.number = (uint16_t) iterator_->descriptor; - queued_lines_.push_back(line); - ++iterator_; - } else if (iterator_->type == N_SOL) { - current_source_file_ = SymbolString(); - ++iterator_; - } else { - // Ignore anything else. - ++iterator_; - } - } - - // An N_SO with an empty name indicates the end of the compilation - // unit. Default to zero. - uint64_t ending_address = 0; - if (!iterator_->at_end) { - assert(iterator_->type == N_SO); - const char *name = SymbolString(); - if (name[0] == '\0') { - ending_address = iterator_->value; - ++iterator_; - } - } - - if (! handler_->EndCompilationUnit(ending_address)) - return false; - - queued_lines_.clear(); - - return true; -} - -bool StabsReader::ProcessFunction() { - assert(!iterator_->at_end && iterator_->type == N_FUN); - - uint64_t function_address = iterator_->value; - // The STABS string for an N_FUN entry is the name of the function, - // followed by a colon, followed by type information for the - // function. We want to pass the name alone to StartFunction. - const char *stab_string = SymbolString(); - const char *name_end = strchr(stab_string, ':'); - if (! name_end) - name_end = stab_string + strlen(stab_string); - string name(stab_string, name_end - stab_string); - if (! handler_->StartFunction(name, function_address)) - return false; - ++iterator_; - - // If there were any SLINE records given before the function, report them now. - for (vector::const_iterator it = queued_lines_.begin(); - it != queued_lines_.end(); it++) { - if (!handler_->Line(it->address, it->filename, it->number)) - return false; - } - queued_lines_.clear(); - - while (!iterator_->at_end) { - if (iterator_->type == N_SO || iterator_->type == N_FUN) - break; - else if (iterator_->type == N_SLINE) { - // The value of an N_SLINE entry is the offset of the line from - // the function's start address. - uint64_t line_address = function_address + iterator_->value; - // The n_desc of a N_SLINE entry is the line number. It's a - // signed 16-bit field; line numbers from 32768 to 65535 are - // stored as n-65536. - uint16_t line_number = iterator_->descriptor; - if (! handler_->Line(line_address, current_source_file_, line_number)) - return false; - ++iterator_; - } else if (iterator_->type == N_SOL) { - current_source_file_ = SymbolString(); - ++iterator_; - } else - // Ignore anything else. - ++iterator_; - } - - // We've reached the end of the function. See if we can figure out its - // ending address. - uint64_t ending_address = 0; - if (!iterator_->at_end) { - assert(iterator_->type == N_SO || iterator_->type == N_FUN); - if (iterator_->type == N_FUN) { - const char *symbol_name = SymbolString(); - if (symbol_name[0] == '\0') { - // An N_FUN entry with no name is a terminator for this function; - // its value is the function's size. - ending_address = function_address + iterator_->value; - ++iterator_; - } else { - // An N_FUN entry with a name is the next function, and we can take - // its value as our ending address. Don't advance the iterator, as - // we'll use this symbol to start the next function as well. - ending_address = iterator_->value; - } - } else { - // An N_SO entry could be an end-of-compilation-unit marker, or the - // start of the next compilation unit, but in either case, its value - // is our ending address. We don't advance the iterator; - // ProcessCompilationUnit will decide what to do with this symbol. - ending_address = iterator_->value; - } - } - - if (! handler_->EndFunction(ending_address)) - return false; - - return true; -} - -bool StabsReader::ProcessExtern() { -#if defined(HAVE_MACH_O_NLIST_H) - assert(!iterator_->at_end && - (iterator_->type & N_STAB) == 0 && - (iterator_->type & N_TYPE) == N_SECT); -#endif - - // TODO(mark): only do symbols in the text section? - if (!handler_->Extern(SymbolString(), iterator_->value)) - return false; - - ++iterator_; - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h deleted file mode 100644 index 98ee2dd53..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h +++ /dev/null @@ -1,325 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stabs_reader.h: Define StabsReader, a parser for STABS debugging -// information. A description of the STABS debugging format can be -// found at: -// -// http://sourceware.org/gdb/current/onlinedocs/stabs_toc.html -// -// The comments here assume you understand the format. -// -// This parser can handle big-endian and little-endian data, and the symbol -// values may be either 32 or 64 bits long. It handles both STABS in -// sections (as used on Linux) and STABS appearing directly in an -// a.out-like symbol table (as used in Darwin OS X Mach-O files). - -#ifndef COMMON_STABS_READER_H__ -#define COMMON_STABS_READER_H__ - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_MACH_O_NLIST_H -#include -#elif defined(HAVE_A_OUT_H) -#include -#endif - -#include -#include - -#include "common/byte_cursor.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -class StabsHandler; - -class StabsReader { - public: - // Create a reader for the STABS debug information whose .stab section is - // being traversed by ITERATOR, and whose .stabstr section is referred to - // by STRINGS. The reader will call the member functions of HANDLER to - // report the information it finds, when the reader's 'Process' member - // function is called. - // - // BIG_ENDIAN should be true if the entries in the .stab section are in - // big-endian form, or false if they are in little-endian form. - // - // VALUE_SIZE should be either 4 or 8, indicating the size of the 'value' - // field in each entry in bytes. - // - // UNITIZED should be true if the STABS data is stored in units with - // N_UNDF headers. This is usually the case for STABS stored in sections, - // like .stab/.stabstr, and usually not the case for STABS stored in the - // actual symbol table; UNITIZED should be true when parsing Linux stabs, - // false when parsing Mac OS X STABS. For details, see: - // http://sourceware.org/gdb/current/onlinedocs/stabs/Stab-Section-Basics.html - // - // Note that, in ELF, the .stabstr section should be found using the - // 'sh_link' field of the .stab section header, not by name. - StabsReader(const uint8_t *stab, size_t stab_size, - const uint8_t *stabstr, size_t stabstr_size, - bool big_endian, size_t value_size, bool unitized, - StabsHandler *handler); - - // Process the STABS data, calling the handler's member functions to - // report what we find. While the handler functions return true, - // continue to process until we reach the end of the section. If we - // processed the entire section and all handlers returned true, - // return true. If any handler returned false, return false. - // - // This is only meant to be called once per StabsReader instance; - // resuming a prior processing pass that stopped abruptly isn't supported. - bool Process(); - - private: - - // An class for walking arrays of STABS entries. This isolates the main - // STABS reader from the exact format (size; endianness) of the entries - // themselves. - class EntryIterator { - public: - // The contents of a STABS entry, adjusted for the host's endianness, - // word size, 'struct nlist' layout, and so on. - struct Entry { - // True if this iterator has reached the end of the entry array. When - // this is set, the other members of this structure are not valid. - bool at_end; - - // The number of this entry within the list. - size_t index; - - // The current entry's name offset. This is the offset within the - // current compilation unit's strings, as establish by the N_UNDF entries. - size_t name_offset; - - // The current entry's type, 'other' field, descriptor, and value. - unsigned char type; - unsigned char other; - short descriptor; - uint64_t value; - }; - - // Create a EntryIterator walking the entries in BUFFER. Treat the - // entries as big-endian if BIG_ENDIAN is true, as little-endian - // otherwise. Assume each entry has a 'value' field whose size is - // VALUE_SIZE. - // - // This would not be terribly clean to extend to other format variations, - // but it's enough to handle Linux and Mac, and we'd like STABS to die - // anyway. - // - // For the record: on Linux, STABS entry values are always 32 bits, - // regardless of the architecture address size (don't ask me why); on - // Mac, they are 32 or 64 bits long. Oddly, the section header's entry - // size for a Linux ELF .stab section varies according to the ELF class - // from 12 to 20 even as the actual entries remain unchanged. - EntryIterator(const ByteBuffer *buffer, bool big_endian, size_t value_size); - - // Move to the next entry. This function's behavior is undefined if - // at_end() is true when it is called. - EntryIterator &operator++() { Fetch(); entry_.index++; return *this; } - - // Dereferencing this iterator produces a reference to an Entry structure - // that holds the current entry's values. The entry is owned by this - // EntryIterator, and will be invalidated at the next call to operator++. - const Entry &operator*() const { return entry_; } - const Entry *operator->() const { return &entry_; } - - private: - // Read the STABS entry at cursor_, and set entry_ appropriately. - void Fetch(); - - // The size of entries' value field, in bytes. - size_t value_size_; - - // A byte cursor traversing buffer_. - ByteCursor cursor_; - - // Values for the entry this iterator refers to. - Entry entry_; - }; - - // A source line, saved to be reported later. - struct Line { - uint64_t address; - const char *filename; - int number; - }; - - // Return the name of the current symbol. - const char *SymbolString(); - - // Process a compilation unit starting at symbol_. Return true - // to continue processing, or false to abort. - bool ProcessCompilationUnit(); - - // Process a function in current_source_file_ starting at symbol_. - // Return true to continue processing, or false to abort. - bool ProcessFunction(); - - // Process an exported function symbol. - // Return true to continue processing, or false to abort. - bool ProcessExtern(); - - // The STABS entries being parsed. - ByteBuffer entries_; - - // The string section to which the entries refer. - ByteBuffer strings_; - - // The iterator walking the STABS entries. - EntryIterator iterator_; - - // True if the data is "unitized"; see the explanation in the comment for - // StabsReader::StabsReader. - bool unitized_; - - StabsHandler *handler_; - - // The offset of the current compilation unit's strings within stabstr_. - size_t string_offset_; - - // The value string_offset_ should have for the next compilation unit, - // as established by N_UNDF entries. - size_t next_cu_string_offset_; - - // The current source file name. - const char *current_source_file_; - - // Mac OS X STABS place SLINE records before functions; we accumulate a - // vector of these until we see the FUN record, and then report them - // after the StartFunction call. - std::vector queued_lines_; -}; - -// Consumer-provided callback structure for the STABS reader. Clients -// of the STABS reader provide an instance of this structure. The -// reader then invokes the member functions of that instance to report -// the information it finds. -// -// The default definitions of the member functions do nothing, and return -// true so processing will continue. -class StabsHandler { - public: - StabsHandler() { } - virtual ~StabsHandler() { } - - // Some general notes about the handler callback functions: - - // Processing proceeds until the end of the .stabs section, or until - // one of these functions returns false. - - // The addresses given are as reported in the STABS info, without - // regard for whether the module may be loaded at different - // addresses at different times (a shared library, say). When - // processing STABS from an ELF shared library, the addresses given - // all assume the library is loaded at its nominal load address. - // They are *not* offsets from the nominal load address. If you - // want offsets, you must subtract off the library's nominal load - // address. - - // The arguments to these functions named FILENAME are all - // references to strings stored in the .stabstr section. Because - // both the Linux and Solaris linkers factor out duplicate strings - // from the .stabstr section, the consumer can assume that if two - // FILENAME values are different addresses, they represent different - // file names. - // - // Thus, it's safe to use (say) std::map, which does - // string address comparisons, not string content comparisons. - // Since all the strings are in same array of characters --- the - // .stabstr section --- comparing their addresses produces - // predictable, if not lexicographically meaningful, results. - - // Begin processing a compilation unit whose main source file is - // named FILENAME, and whose base address is ADDRESS. If - // BUILD_DIRECTORY is non-NULL, it is the name of the build - // directory in which the compilation occurred. - virtual bool StartCompilationUnit(const char *filename, uint64_t address, - const char *build_directory) { - return true; - } - - // Finish processing the compilation unit. If ADDRESS is non-zero, - // it is the ending address of the compilation unit. If ADDRESS is - // zero, then the compilation unit's ending address is not - // available, and the consumer must infer it by other means. - virtual bool EndCompilationUnit(uint64_t address) { return true; } - - // Begin processing a function named NAME, whose starting address is - // ADDRESS. This function belongs to the compilation unit that was - // most recently started but not ended. - // - // Note that, unlike filenames, NAME is not a pointer into the - // .stabstr section; this is because the name as it appears in the - // STABS data is followed by type information. The value passed to - // StartFunction is the function name alone. - // - // In languages that use name mangling, like C++, NAME is mangled. - virtual bool StartFunction(const string &name, uint64_t address) { - return true; - } - - // Finish processing the function. If ADDRESS is non-zero, it is - // the ending address for the function. If ADDRESS is zero, then - // the function's ending address is not available, and the consumer - // must infer it by other means. - virtual bool EndFunction(uint64_t address) { return true; } - - // Report that the code at ADDRESS is attributable to line NUMBER of - // the source file named FILENAME. The caller must infer the ending - // address of the line. - virtual bool Line(uint64_t address, const char *filename, int number) { - return true; - } - - // Report that an exported function NAME is present at ADDRESS. - // The size of the function is unknown. - virtual bool Extern(const string &name, uint64_t address) { - return true; - } - - // Report a warning. FORMAT is a printf-like format string, - // specifying how to format the subsequent arguments. - virtual void Warning(const char *format, ...) = 0; -}; - -} // namespace google_breakpad - -#endif // COMMON_STABS_READER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader_unittest.cc deleted file mode 100644 index a84da1c4c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader_unittest.cc +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stabs_reader_unittest.cc: Unit tests for google_breakpad::StabsReader. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/stabs_reader.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" - -using ::testing::Eq; -using ::testing::InSequence; -using ::testing::Return; -using ::testing::StrEq; -using ::testing::Test; -using ::testing::_; -using google_breakpad::StabsHandler; -using google_breakpad::StabsReader; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using std::map; - -namespace { - -// A StringAssembler is a class for generating .stabstr sections to present -// as input to the STABS parser. -class StringAssembler: public Section { - public: - StringAssembler() : in_cu_(false) { StartCU(); } - - // Add the string S to this StringAssembler, and return the string's - // offset within this compilation unit's strings. If S has been added - // already, this returns the offset of its first instance. - size_t Add(const string &s) { - map::iterator it = added_.find(s); - if (it != added_.end()) - return it->second; - size_t offset = Size() - cu_start_; - AppendCString(s); - added_[s] = offset; - return offset; - } - - // Start a fresh compilation unit string collection. - void StartCU() { - // Ignore duplicate calls to StartCU. Our test data don't always call - // StartCU at all, meaning that our constructor has to take care of it, - // meaning that tests that *do* call StartCU call it twice at the - // beginning. This is not worth smoothing out. - if (in_cu_) return; - - added_.clear(); - cu_start_ = Size(); - - // Each compilation unit's strings start with an empty string. - AppendCString(""); - added_[""] = 0; - - in_cu_ = true; - } - - // Finish off the current CU's strings. - size_t EndCU() { - assert(in_cu_); - in_cu_ = false; - return Size() - cu_start_; - } - - private: - // The offset of the start of this compilation unit's strings. - size_t cu_start_; - - // True if we're in a CU. - bool in_cu_; - - // A map from the strings that have been added to this section to - // their starting indices within their compilation unit. - map added_; -}; - -// A StabsAssembler is a class for generating .stab sections to present as -// test input for the STABS parser. -class StabsAssembler: public Section { - public: - // Create a StabsAssembler that uses StringAssembler for its strings. - StabsAssembler(StringAssembler *string_assembler) - : Section(string_assembler->endianness()), - string_assembler_(string_assembler), - value_size_(0), - entry_count_(0), - cu_header_(NULL) { } - ~StabsAssembler() { assert(!cu_header_); } - - // Accessor and setter for value_size_. - size_t value_size() const { return value_size_; } - StabsAssembler &set_value_size(size_t value_size) { - value_size_ = value_size; - return *this; - } - - // Append a STAB entry to the end of this section with the given - // characteristics. NAME is the offset of this entry's name string within - // its compilation unit's portion of the .stabstr section; this can be a - // value generated by a StringAssembler. Return a reference to this - // StabsAssembler. - StabsAssembler &Stab(uint8_t type, uint8_t other, Label descriptor, - Label value, Label name) { - D32(name); - D8(type); - D8(other); - D16(descriptor); - Append(endianness(), value_size_, value); - entry_count_++; - return *this; - } - - // As above, but automatically add NAME to our StringAssembler. - StabsAssembler &Stab(uint8_t type, uint8_t other, Label descriptor, - Label value, const string &name) { - return Stab(type, other, descriptor, value, string_assembler_->Add(name)); - } - - // Start a compilation unit named NAME, with an N_UNDF symbol to start - // it, and its own portion of the string section. Return a reference to - // this StabsAssembler. - StabsAssembler &StartCU(const string &name) { - assert(!cu_header_); - cu_header_ = new CUHeader; - string_assembler_->StartCU(); - entry_count_ = 0; - return Stab(N_UNDF, 0, - cu_header_->final_entry_count, - cu_header_->final_string_size, - string_assembler_->Add(name)); - } - - // Close off the current compilation unit. Return a reference to this - // StabsAssembler. - StabsAssembler &EndCU() { - assert(cu_header_); - cu_header_->final_entry_count = entry_count_; - cu_header_->final_string_size = string_assembler_->EndCU(); - delete cu_header_; - cu_header_ = NULL; - return *this; - } - - private: - // Data used in a compilation unit header STAB that we won't know until - // we've finished the compilation unit. - struct CUHeader { - // The final number of entries this compilation unit will hold. - Label final_entry_count; - - // The final size of this compilation unit's strings. - Label final_string_size; - }; - - // The strings for our STABS entries. - StringAssembler *string_assembler_; - - // The size of the 'value' field of stabs entries in this section. - size_t value_size_; - - // The number of entries in this compilation unit so far. - size_t entry_count_; - - // Header labels for this compilation unit, if we've started one but not - // finished it. - CUHeader *cu_header_; -}; - -class MockStabsReaderHandler: public StabsHandler { - public: - MOCK_METHOD3(StartCompilationUnit, - bool(const char *, uint64_t, const char *)); - MOCK_METHOD1(EndCompilationUnit, bool(uint64_t)); - MOCK_METHOD2(StartFunction, bool(const string &, uint64_t)); - MOCK_METHOD1(EndFunction, bool(uint64_t)); - MOCK_METHOD3(Line, bool(uint64_t, const char *, int)); - MOCK_METHOD2(Extern, bool(const string &, uint64_t)); - void Warning(const char *format, ...) { MockWarning(format); } - MOCK_METHOD1(MockWarning, void(const char *)); -}; - -struct StabsFixture { - StabsFixture() : stabs(&strings), unitized(true) { } - - // Create a StabsReader to parse the mock stabs data in stabs and - // strings, and pass the parsed information to mock_handler. Use the - // endianness and value size of stabs to parse the data. If all goes - // well, return the result of calling the reader's Process member - // function. Otherwise, return false. - bool ApplyHandlerToMockStabsData() { - string stabs_contents, stabstr_contents; - if (!stabs.GetContents(&stabs_contents) || - !strings.GetContents(&stabstr_contents)) - return false; - - // Run the parser on the test input, passing whatever we find to HANDLER. - StabsReader reader( - reinterpret_cast(stabs_contents.data()), - stabs_contents.size(), - reinterpret_cast(stabstr_contents.data()), - stabstr_contents.size(), - stabs.endianness() == kBigEndian, stabs.value_size(), unitized, - &mock_handler); - return reader.Process(); - } - - StringAssembler strings; - StabsAssembler stabs; - bool unitized; - MockStabsReaderHandler mock_handler; -}; - -class Stabs: public StabsFixture, public Test { }; - -TEST_F(Stabs, MockStabsInput) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(4); - stabs - .Stab(N_SO, 149, 40232, 0x18a2a72bU, "builddir/") - .Stab(N_FUN, 83, 50010, 0x91a5353fU, - "not the SO with source file name we expected ") - .Stab(N_SO, 165, 24791, 0xfe69d23cU, "") - .Stab(N_SO, 184, 34178, 0xca4d883aU, "builddir1/") - .Stab(N_SO, 83, 40859, 0xd2fe5df3U, "file1.c") - .Stab(N_LSYM, 147, 39565, 0x60d4bb8aU, "not the FUN we're looking for") - .Stab(N_FUN, 120, 50271, 0xa049f4b1U, "fun1") - .Stab(N_BINCL, 150, 15694, 0xef65c659U, - "something to ignore in a FUN body") - .Stab(N_SLINE, 147, 4967, 0xd904b3f, "") - .Stab(N_SOL, 177, 56135, 0xbd97b1dcU, "header.h") - .Stab(N_SLINE, 130, 24610, 0x90f145b, "") - .Stab(N_FUN, 45, 32441, 0xbf27cf93U, - "fun2:some stabs type info here:to trim from the name") - .Stab(N_SLINE, 138, 39002, 0x8148b87, "") - .Stab(N_SOL, 60, 49318, 0x1d06e025U, "file1.c") - .Stab(N_SLINE, 29, 52163, 0x6eebbb7, "") - .Stab(N_SO, 167, 4647, 0xd04b7448U, "") - .Stab(N_LSYM, 58, 37837, 0xe6b14d37U, "") - .Stab(N_SO, 152, 7810, 0x11759f10U, "file3.c") - .Stab(N_SO, 218, 12447, 0x11cfe4b5U, ""); - - { - InSequence s; - - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file1.c"), 0xd2fe5df3U, - StrEq("builddir1/"))) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun1"), 0xa049f4b1U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0xa049f4b1U + 0xd904b3f, StrEq("file1.c"), 4967)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0xa049f4b1U + 0x90f145b, StrEq("header.h"), 24610)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xbf27cf93U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun2"), 0xbf27cf93U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0xbf27cf93U + 0x8148b87, StrEq("header.h"), 39002)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0xbf27cf93U + 0x6eebbb7, StrEq("file1.c"), 52163)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xd04b7448U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0xd04b7448U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file3.c"), - 0x11759f10U, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0x11cfe4b5U)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, AbruptCU) { - stabs.set_endianness(kBigEndian); - stabs.set_value_size(4); - stabs.Stab(N_SO, 177, 23446, 0xbf10d5e4, "file2-1.c"); - - { - InSequence s; - - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file2-1.c"), 0xbf10d5e4, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, AbruptFunction) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(8); - stabs - .Stab(N_SO, 218, 26631, 0xb83ddf10U, "file3-1.c") - .Stab(N_FUN, 113, 24765, 0xbbd4a145U, "fun3_1"); - - { - InSequence s; - - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file3-1.c"), 0xb83ddf10U, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartFunction(StrEq("fun3_1"), 0xbbd4a145U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, NoCU) { - stabs.set_endianness(kBigEndian); - stabs.set_value_size(8); - stabs.Stab(N_SO, 161, 25673, 0x8f676e7bU, "build-directory/"); - - EXPECT_CALL(mock_handler, StartCompilationUnit(_, _, _)) - .Times(0); - EXPECT_CALL(mock_handler, StartFunction(_, _)) - .Times(0); - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, NoCUEnd) { - stabs.set_endianness(kBigEndian); - stabs.set_value_size(8); - stabs - .Stab(N_SO, 116, 58280, 0x2f7493c9U, "file5-1.c") - .Stab(N_SO, 224, 23057, 0xf9f1d50fU, "file5-2.c"); - - { - InSequence s; - - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file5-1.c"), 0x2f7493c9U, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file5-2.c"), 0xf9f1d50fU, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -// On systems that store STABS in sections, string offsets are relative to -// the beginning of that compilation unit's strings, marked with N_UNDF -// symbols; see the comments for StabsReader::StabsReader. -TEST_F(Stabs, Unitized) { - stabs.set_endianness(kBigEndian); - stabs.set_value_size(4); - stabs - .StartCU("antimony") - .Stab(N_SO, 49, 26043, 0x7e259f1aU, "antimony") - .Stab(N_FUN, 101, 63253, 0x7fbcccaeU, "arsenic") - .Stab(N_SO, 124, 37175, 0x80b0014cU, "") - .EndCU() - .StartCU("aluminum") - .Stab(N_SO, 72, 23084, 0x86756839U, "aluminum") - .Stab(N_FUN, 59, 3305, 0xa8e120b0U, "selenium") - .Stab(N_SO, 178, 56949, 0xbffff983U, "") - .EndCU(); - - { - InSequence s; - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("antimony"), 0x7e259f1aU, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartFunction(Eq("arsenic"), 0x7fbcccaeU)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0x80b0014cU)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0x80b0014cU)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("aluminum"), 0x86756839U, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, StartFunction(Eq("selenium"), 0xa8e120b0U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xbffff983U)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0xbffff983U)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -// On systems that store STABS entries in the real symbol table, the N_UNDF -// entries have no special meaning, and shouldn't mess up the string -// indices. -TEST_F(Stabs, NonUnitized) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(4); - unitized = false; - stabs - .Stab(N_UNDF, 21, 11551, 0x9bad2b2e, "") - .Stab(N_UNDF, 21, 11551, 0x9bad2b2e, "") - .Stab(N_SO, 71, 45139, 0x11a97352, "Tanzania") - .Stab(N_SO, 221, 41976, 0x21a97352, ""); - - { - InSequence s; - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("Tanzania"), - 0x11a97352, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0x21a97352)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, FunctionEnd) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(8); - stabs - .Stab(N_SO, 102, 62362, 0x52a830d644cd6942ULL, "compilation unit") - // This function is terminated by the start of the next function. - .Stab(N_FUN, 216, 38405, 0xbb5ab70ecdd23bfeULL, "function 1") - // This function is terminated by an explicit end-of-function stab, - // whose value is a size in bytes. - .Stab(N_FUN, 240, 10973, 0xc954de9b8fb3e5e2ULL, "function 2") - .Stab(N_FUN, 14, 36749, 0xc1ab, "") - // This function is terminated by the end of the compilation unit. - .Stab(N_FUN, 143, 64514, 0xdff98c9a35386e1fULL, "function 3") - .Stab(N_SO, 164, 60142, 0xfdacb856e78bbf57ULL, ""); - - { - InSequence s; - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("compilation unit"), - 0x52a830d644cd6942ULL, NULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartFunction(Eq("function 1"), 0xbb5ab70ecdd23bfeULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xc954de9b8fb3e5e2ULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartFunction(Eq("function 2"), 0xc954de9b8fb3e5e2ULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xc954de9b8fb3e5e2ULL + 0xc1ab)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartFunction(Eq("function 3"), 0xdff98c9a35386e1fULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xfdacb856e78bbf57ULL)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0xfdacb856e78bbf57ULL)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -// On Mac OS X, SLINE records can appear before the FUN stab to which they -// belong, and their values are absolute addresses, not offsets. -TEST_F(Stabs, LeadingLine) { - stabs.set_endianness(kBigEndian); - stabs.set_value_size(4); - stabs - .Stab(N_SO, 179, 27357, 0x8adabc15, "build directory/") - .Stab(N_SO, 52, 53058, 0x4c7e3bf4, "compilation unit") - .Stab(N_SOL, 165, 12086, 0x6a797ca3, "source file name") - .Stab(N_SLINE, 229, 20015, 0x4cb3d7e0, "") - .Stab(N_SLINE, 89, 43802, 0x4cba8b88, "") - .Stab(N_FUN, 251, 51639, 0xce1b98fa, "rutabaga") - .Stab(N_FUN, 218, 16113, 0x5798, "") - .Stab(N_SO, 52, 53058, 0xd4af4415, ""); - - { - InSequence s; - EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("compilation unit"), - 0x4c7e3bf4, StrEq("build directory/"))) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - StartFunction(Eq("rutabaga"), 0xce1b98fa)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0x4cb3d7e0, StrEq("source file name"), 20015)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Line(0x4cba8b88, StrEq("source file name"), 43802)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndFunction(0xce1b98fa + 0x5798)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, EndCompilationUnit(0xd4af4415)) - .WillOnce(Return(true)); - } - - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - - -#if defined(HAVE_MACH_O_NLIST_H) -// These tests have no meaning on non-Mach-O-based systems, as -// only Mach-O uses N_SECT to represent public symbols. -TEST_F(Stabs, OnePublicSymbol) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(4); - - const uint32_t kExpectedAddress = 0x9000; - const string kExpectedFunctionName("public_function"); - stabs - .Stab(N_SECT, 1, 0, kExpectedAddress, kExpectedFunctionName); - - { - InSequence s; - EXPECT_CALL(mock_handler, - Extern(StrEq(kExpectedFunctionName), - kExpectedAddress)) - .WillOnce(Return(true)); - } - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -TEST_F(Stabs, TwoPublicSymbols) { - stabs.set_endianness(kLittleEndian); - stabs.set_value_size(4); - - const uint32_t kExpectedAddress1 = 0xB0B0B0B0; - const string kExpectedFunctionName1("public_function"); - const uint32_t kExpectedAddress2 = 0xF0F0F0F0; - const string kExpectedFunctionName2("something else"); - stabs - .Stab(N_SECT, 1, 0, kExpectedAddress1, kExpectedFunctionName1) - .Stab(N_SECT, 1, 0, kExpectedAddress2, kExpectedFunctionName2); - - { - InSequence s; - EXPECT_CALL(mock_handler, - Extern(StrEq(kExpectedFunctionName1), - kExpectedAddress1)) - .WillOnce(Return(true)); - EXPECT_CALL(mock_handler, - Extern(StrEq(kExpectedFunctionName2), - kExpectedAddress2)) - .WillOnce(Return(true)); - } - ASSERT_TRUE(ApplyHandlerToMockStabsData()); -} - -#endif - -} // anonymous namespace diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.cc deleted file mode 100644 index 0a83cf21c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dump_stabs.cc --- implement the StabsToModule class. - -#include -#include -#include -#include - -#include - -#include "common/stabs_to_module.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -// Demangle using abi call. -// Older GCC may not support it. -static string Demangle(const string &mangled) { - int status = 0; - char *demangled = abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status); - if (status == 0 && demangled != NULL) { - string str(demangled); - free(demangled); - return str; - } - return string(mangled); -} - -StabsToModule::~StabsToModule() { - // Free any functions we've accumulated but not added to the module. - for (vector::const_iterator func_it = functions_.begin(); - func_it != functions_.end(); func_it++) - delete *func_it; - // Free any function that we're currently within. - delete current_function_; -} - -bool StabsToModule::StartCompilationUnit(const char *name, uint64_t address, - const char *build_directory) { - assert(!in_compilation_unit_); - in_compilation_unit_ = true; - current_source_file_name_ = name; - current_source_file_ = module_->FindFile(name); - comp_unit_base_address_ = address; - boundaries_.push_back(static_cast(address)); - return true; -} - -bool StabsToModule::EndCompilationUnit(uint64_t address) { - assert(in_compilation_unit_); - in_compilation_unit_ = false; - comp_unit_base_address_ = 0; - current_source_file_ = NULL; - current_source_file_name_ = NULL; - if (address) - boundaries_.push_back(static_cast(address)); - return true; -} - -bool StabsToModule::StartFunction(const string &name, - uint64_t address) { - assert(!current_function_); - Module::Function *f = new Module::Function(Demangle(name), address); - f->size = 0; // We compute this in StabsToModule::Finalize(). - f->parameter_size = 0; // We don't provide this information. - current_function_ = f; - boundaries_.push_back(static_cast(address)); - return true; -} - -bool StabsToModule::EndFunction(uint64_t address) { - assert(current_function_); - // Functions in this compilation unit should have address bigger - // than the compilation unit's starting address. There may be a lot - // of duplicated entries for functions in the STABS data. We will - // count on the Module to remove the duplicates. - if (current_function_->address >= comp_unit_base_address_) - functions_.push_back(current_function_); - else - delete current_function_; - current_function_ = NULL; - if (address) - boundaries_.push_back(static_cast(address)); - return true; -} - -bool StabsToModule::Line(uint64_t address, const char *name, int number) { - assert(current_function_); - assert(current_source_file_); - if (name != current_source_file_name_) { - current_source_file_ = module_->FindFile(name); - current_source_file_name_ = name; - } - Module::Line line; - line.address = address; - line.size = 0; // We compute this in StabsToModule::Finalize(). - line.file = current_source_file_; - line.number = number; - current_function_->lines.push_back(line); - return true; -} - -bool StabsToModule::Extern(const string &name, uint64_t address) { - Module::Extern *ext = new Module::Extern(address); - // Older libstdc++ demangle implementations can crash on unexpected - // input, so be careful about what gets passed in. - if (name.compare(0, 3, "__Z") == 0) { - ext->name = Demangle(name.substr(1)); - } else if (name[0] == '_') { - ext->name = name.substr(1); - } else { - ext->name = name; - } - module_->AddExtern(ext); - return true; -} - -void StabsToModule::Warning(const char *format, ...) { - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); -} - -void StabsToModule::Finalize() { - // Sort our boundary list, so we can search it quickly. - sort(boundaries_.begin(), boundaries_.end()); - // Sort all functions by address, just for neatness. - sort(functions_.begin(), functions_.end(), - Module::Function::CompareByAddress); - - for (vector::const_iterator func_it = functions_.begin(); - func_it != functions_.end(); - func_it++) { - Module::Function *f = *func_it; - // Compute the function f's size. - vector::const_iterator boundary - = std::upper_bound(boundaries_.begin(), boundaries_.end(), f->address); - if (boundary != boundaries_.end()) - f->size = *boundary - f->address; - else - // If this is the last function in the module, and the STABS - // reader was unable to give us its ending address, then assign - // it a bogus, very large value. This will happen at most once - // per module: since we've added all functions' addresses to the - // boundary table, only one can be the last. - f->size = kFallbackSize; - - // Compute sizes for each of the function f's lines --- if it has any. - if (!f->lines.empty()) { - stable_sort(f->lines.begin(), f->lines.end(), - Module::Line::CompareByAddress); - vector::iterator last_line = f->lines.end() - 1; - for (vector::iterator line_it = f->lines.begin(); - line_it != last_line; line_it++) - line_it[0].size = line_it[1].address - line_it[0].address; - // Compute the size of the last line from f's end address. - last_line->size = (f->address + f->size) - last_line->address; - } - } - // Now that everything has a size, add our functions to the module, and - // dispose of our private list. - module_->AddFunctions(functions_.begin(), functions_.end()); - functions_.clear(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.h b/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.h deleted file mode 100644 index 5e04fa792..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.h +++ /dev/null @@ -1,143 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dump_stabs.h: Define the StabsToModule class, which receives -// STABS debugging information from a parser and adds it to a Breakpad -// symbol file. - -#ifndef BREAKPAD_COMMON_STABS_TO_MODULE_H_ -#define BREAKPAD_COMMON_STABS_TO_MODULE_H_ - -#include - -#include -#include - -#include "common/module.h" -#include "common/stabs_reader.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -using std::vector; - -// A StabsToModule is a handler that receives parsed STABS debugging -// information from a StabsReader, and uses that to populate -// a Module. (All classes are in the google_breakpad namespace.) A -// Module represents the contents of a Breakpad symbol file, and knows -// how to write itself out as such. A StabsToModule thus acts as -// the bridge between STABS and Breakpad data. -// When processing Darwin Mach-O files, this also receives public linker -// symbols, like those found in system libraries. -class StabsToModule: public google_breakpad::StabsHandler { - public: - // Receive parsed debugging information from a StabsReader, and - // store it all in MODULE. - StabsToModule(Module *module) : - module_(module), - in_compilation_unit_(false), - comp_unit_base_address_(0), - current_function_(NULL), - current_source_file_(NULL), - current_source_file_name_(NULL) { } - ~StabsToModule(); - - // The standard StabsHandler virtual member functions. - bool StartCompilationUnit(const char *name, uint64_t address, - const char *build_directory); - bool EndCompilationUnit(uint64_t address); - bool StartFunction(const string &name, uint64_t address); - bool EndFunction(uint64_t address); - bool Line(uint64_t address, const char *name, int number); - bool Extern(const string &name, uint64_t address); - void Warning(const char *format, ...); - - // Do any final processing necessary to make module_ contain all the - // data provided by the STABS reader. - // - // Because STABS does not provide reliable size information for - // functions and lines, we need to make a pass over the data after - // processing all the STABS to compute those sizes. We take care of - // that here. - void Finalize(); - - private: - - // An arbitrary, but very large, size to use for functions whose - // size we can't compute properly. - static const uint64_t kFallbackSize = 0x10000000; - - // The module we're contributing debugging info to. - Module *module_; - - // The functions we've generated so far. We don't add these to - // module_ as we parse them. Instead, we wait until we've computed - // their ending address, and their lines' ending addresses. - // - // We could just stick them in module_ from the outset, but if - // module_ already contains data gathered from other debugging - // formats, that would complicate the size computation. - vector functions_; - - // Boundary addresses. STABS doesn't necessarily supply sizes for - // functions and lines, so we need to compute them ourselves by - // finding the next object. - vector boundaries_; - - // True if we are currently within a compilation unit: we have gotten a - // StartCompilationUnit call, but no matching EndCompilationUnit call - // yet. We use this for sanity checks. - bool in_compilation_unit_; - - // The base address of the current compilation unit. We use this to - // recognize functions we should omit from the symbol file. (If you - // know the details of why we omit these, please patch this - // comment.) - Module::Address comp_unit_base_address_; - - // The function we're currently contributing lines to. - Module::Function *current_function_; - - // The last Module::File we got a line number in. - Module::File *current_source_file_; - - // The pointer in the .stabstr section of the name that - // current_source_file_ is built from. This allows us to quickly - // recognize when the current line is in the same file as the - // previous one (which it usually is). - const char *current_source_file_name_; -}; - -} // namespace google_breakpad - -#endif // BREAKPAD_COMMON_STABS_TO_MODULE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module_unittest.cc deleted file mode 100644 index d445d1d64..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module_unittest.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// dump_stabs_unittest.cc: Unit tests for StabsToModule. - -#include - -#include "breakpad_googletest_includes.h" -#include "common/stabs_to_module.h" - -using google_breakpad::Module; -using google_breakpad::StabsToModule; -using std::vector; - -TEST(StabsToModule, SimpleCU) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // Feed in a simple compilation unit that defines a function with - // one line. - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0x9f4d1271e50db93bLL, - "build-directory")); - EXPECT_TRUE(h.StartFunction("function", 0xfde4abbed390c394LL)); - EXPECT_TRUE(h.Line(0xfde4abbed390c394LL, "source-file-name", 174823314)); - EXPECT_TRUE(h.EndFunction(0xfde4abbed390c3a4LL)); - EXPECT_TRUE(h.EndCompilationUnit(0xfee4abbed390c3a4LL)); - h.Finalize(); - - // Now check to see what has been added to the Module. - Module::File *file = m.FindExistingFile("source-file-name"); - ASSERT_TRUE(file != NULL); - - vector functions; - m.GetFunctions(&functions, functions.end()); - ASSERT_EQ((size_t) 1, functions.size()); - Module::Function *function = functions[0]; - EXPECT_STREQ("function", function->name.c_str()); - EXPECT_EQ(0xfde4abbed390c394LL, function->address); - EXPECT_EQ(0x10U, function->size); - EXPECT_EQ(0U, function->parameter_size); - ASSERT_EQ((size_t) 1, function->lines.size()); - Module::Line *line = &function->lines[0]; - EXPECT_EQ(0xfde4abbed390c394LL, line->address); - EXPECT_EQ(0x10U, line->size); // derived from EndFunction - EXPECT_TRUE(line->file == file); - EXPECT_EQ(174823314, line->number); -} - -#ifdef __GNUC__ -// Function name mangling can vary by compiler, so only run mangled-name -// tests on GCC for simplicity's sake. -TEST(StabsToModule, Externs) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // Feed in a few Extern symbols. - EXPECT_TRUE(h.Extern("_foo", 0xffff)); - EXPECT_TRUE(h.Extern("__Z21dyldGlobalLockAcquirev", 0xaaaa)); - EXPECT_TRUE(h.Extern("_MorphTableGetNextMorphChain", 0x1111)); - h.Finalize(); - - // Now check to see what has been added to the Module. - vector externs; - m.GetExterns(&externs, externs.end()); - ASSERT_EQ((size_t) 3, externs.size()); - Module::Extern *extern1 = externs[0]; - EXPECT_STREQ("MorphTableGetNextMorphChain", extern1->name.c_str()); - EXPECT_EQ((Module::Address)0x1111, extern1->address); - Module::Extern *extern2 = externs[1]; - EXPECT_STREQ("dyldGlobalLockAcquire()", extern2->name.c_str()); - EXPECT_EQ((Module::Address)0xaaaa, extern2->address); - Module::Extern *extern3 = externs[2]; - EXPECT_STREQ("foo", extern3->name.c_str()); - EXPECT_EQ((Module::Address)0xffff, extern3->address); -} -#endif // __GNUC__ - -TEST(StabsToModule, DuplicateFunctionNames) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // Compilation unit with one function, mangled name. - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0xf2cfda36ecf7f46cLL, - "build-directory")); - EXPECT_TRUE(h.StartFunction("funcfoo", - 0xf2cfda36ecf7f46dLL)); - EXPECT_TRUE(h.EndFunction(0)); - EXPECT_TRUE(h.StartFunction("funcfoo", - 0xf2cfda36ecf7f46dLL)); - EXPECT_TRUE(h.EndFunction(0)); - EXPECT_TRUE(h.EndCompilationUnit(0)); - - h.Finalize(); - - // Now check to see what has been added to the Module. - Module::File *file = m.FindExistingFile("compilation-unit"); - ASSERT_TRUE(file != NULL); - - vector functions; - m.GetFunctions(&functions, functions.end()); - ASSERT_EQ(1U, functions.size()); - - Module::Function *function = functions[0]; - EXPECT_EQ(0xf2cfda36ecf7f46dLL, function->address); - EXPECT_LT(0U, function->size); // should have used dummy size - EXPECT_EQ(0U, function->parameter_size); - ASSERT_EQ(0U, function->lines.size()); -} - -TEST(InferSizes, LineSize) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // Feed in a simple compilation unit that defines a function with - // one line. - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0xb4513962eff94e92LL, - "build-directory")); - EXPECT_TRUE(h.StartFunction("function", 0xb4513962eff94e92LL)); - EXPECT_TRUE(h.Line(0xb4513962eff94e92LL, "source-file-name-1", 77396614)); - EXPECT_TRUE(h.Line(0xb4513963eff94e92LL, "source-file-name-2", 87660088)); - EXPECT_TRUE(h.EndFunction(0)); // unknown function end address - EXPECT_TRUE(h.EndCompilationUnit(0)); // unknown CU end address - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit-2", 0xb4523963eff94e92LL, - "build-directory-2")); // next boundary - EXPECT_TRUE(h.EndCompilationUnit(0)); - h.Finalize(); - - // Now check to see what has been added to the Module. - Module::File *file1 = m.FindExistingFile("source-file-name-1"); - ASSERT_TRUE(file1 != NULL); - Module::File *file2 = m.FindExistingFile("source-file-name-2"); - ASSERT_TRUE(file2 != NULL); - - vector functions; - m.GetFunctions(&functions, functions.end()); - ASSERT_EQ((size_t) 1, functions.size()); - - Module::Function *function = functions[0]; - EXPECT_STREQ("function", function->name.c_str()); - EXPECT_EQ(0xb4513962eff94e92LL, function->address); - EXPECT_EQ(0x1000100000000ULL, function->size); // inferred from CU end - EXPECT_EQ(0U, function->parameter_size); - ASSERT_EQ((size_t) 2, function->lines.size()); - - Module::Line *line1 = &function->lines[0]; - EXPECT_EQ(0xb4513962eff94e92LL, line1->address); - EXPECT_EQ(0x100000000ULL, line1->size); // derived from EndFunction - EXPECT_TRUE(line1->file == file1); - EXPECT_EQ(77396614, line1->number); - - Module::Line *line2 = &function->lines[1]; - EXPECT_EQ(0xb4513963eff94e92LL, line2->address); - EXPECT_EQ(0x1000000000000ULL, line2->size); // derived from EndFunction - EXPECT_TRUE(line2->file == file2); - EXPECT_EQ(87660088, line2->number); -} - -#ifdef __GNUC__ -// Function name mangling can vary by compiler, so only run mangled-name -// tests on GCC for simplicity's sake. -TEST(FunctionNames, Mangled) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // Compilation unit with one function, mangled name. - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0xf2cfda63cef7f46cLL, - "build-directory")); - EXPECT_TRUE(h.StartFunction("_ZNSt6vectorIySaIyEE9push_backERKy", - 0xf2cfda63cef7f46dLL)); - EXPECT_TRUE(h.EndFunction(0)); - EXPECT_TRUE(h.EndCompilationUnit(0)); - - h.Finalize(); - - // Now check to see what has been added to the Module. - Module::File *file = m.FindExistingFile("compilation-unit"); - ASSERT_TRUE(file != NULL); - - vector functions; - m.GetFunctions(&functions, functions.end()); - ASSERT_EQ(1U, functions.size()); - - Module::Function *function = functions[0]; - // This is GCC-specific, but we shouldn't be seeing STABS data anywhere - // but Linux. - EXPECT_STREQ("std::vector >::" - "push_back(unsigned long long const&)", - function->name.c_str()); - EXPECT_EQ(0xf2cfda63cef7f46dLL, function->address); - EXPECT_LT(0U, function->size); // should have used dummy size - EXPECT_EQ(0U, function->parameter_size); - ASSERT_EQ(0U, function->lines.size()); -} -#endif // __GNUC__ - -// The GNU toolchain can omit functions that are not used; however, -// when it does so, it doesn't clean up the debugging information that -// refers to them. In STABS, this results in compilation units whose -// SO addresses are zero. -TEST(Omitted, Function) { - Module m("name", "os", "arch", "id"); - StabsToModule h(&m); - - // The StartCompilationUnit and EndCompilationUnit calls may both have an - // address of zero if the compilation unit has had sections removed. - EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0, "build-directory")); - EXPECT_TRUE(h.StartFunction("function", 0x2a133596)); - EXPECT_TRUE(h.EndFunction(0)); - EXPECT_TRUE(h.EndCompilationUnit(0)); -} - -// TODO --- if we actually cared about STABS. Even without these we've -// got full coverage of non-failure source lines in dump_stabs.cc. - -// Line size from next line -// Line size from function end -// Line size from next function start -// line size from cu end -// line size from next cu start -// fallback size is something plausible - -// function size from function end -// function size from next function start -// function size from cu end -// function size from next cu start -// fallback size is something plausible - -// omitting functions outside the compilation unit's address range -// zero-line, one-line, many-line functions diff --git a/toolkit/crashreporter/google-breakpad/src/common/stdio_wrapper.h b/toolkit/crashreporter/google-breakpad/src/common/stdio_wrapper.h deleted file mode 100644 index a3dd50aab..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/stdio_wrapper.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2016, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H -#define GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H - -#include - -#if defined(_MSC_VER) && MSC_VER < 1900 -#include - -#define snprintf _snprintf -typedef SSIZE_T ssize_t; -#endif - - -#endif // GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H diff --git a/toolkit/crashreporter/google-breakpad/src/common/string_conversion.cc b/toolkit/crashreporter/google-breakpad/src/common/string_conversion.cc deleted file mode 100644 index 9c0d623fc..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/string_conversion.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include "common/convert_UTF.h" -#include "common/scoped_ptr.h" -#include "common/string_conversion.h" -#include "common/using_std_string.h" - -namespace google_breakpad { - -using std::vector; - -void UTF8ToUTF16(const char *in, vector *out) { - size_t source_length = strlen(in); - const UTF8 *source_ptr = reinterpret_cast(in); - const UTF8 *source_end_ptr = source_ptr + source_length; - // Erase the contents and zero fill to the expected size - out->clear(); - out->insert(out->begin(), source_length, 0); - uint16_t *target_ptr = &(*out)[0]; - uint16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(uint16_t); - ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr, - &target_ptr, target_end_ptr, - strictConversion); - - // Resize to be the size of the # of converted characters + NULL - out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0); -} - -int UTF8ToUTF16Char(const char *in, int in_length, uint16_t out[2]) { - const UTF8 *source_ptr = reinterpret_cast(in); - const UTF8 *source_end_ptr = source_ptr + sizeof(char); - uint16_t *target_ptr = out; - uint16_t *target_end_ptr = target_ptr + 2 * sizeof(uint16_t); - out[0] = out[1] = 0; - - // Process one character at a time - while (1) { - ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr, - &target_ptr, target_end_ptr, - strictConversion); - - if (result == conversionOK) - return static_cast(source_ptr - reinterpret_cast(in)); - - // Add another character to the input stream and try again - source_ptr = reinterpret_cast(in); - ++source_end_ptr; - - if (source_end_ptr > reinterpret_cast(in) + in_length) - break; - } - - return 0; -} - -void UTF32ToUTF16(const wchar_t *in, vector *out) { - size_t source_length = wcslen(in); - const UTF32 *source_ptr = reinterpret_cast(in); - const UTF32 *source_end_ptr = source_ptr + source_length; - // Erase the contents and zero fill to the expected size - out->clear(); - out->insert(out->begin(), source_length, 0); - uint16_t *target_ptr = &(*out)[0]; - uint16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(uint16_t); - ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr, - &target_ptr, target_end_ptr, - strictConversion); - - // Resize to be the size of the # of converted characters + NULL - out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0); -} - -void UTF32ToUTF16Char(wchar_t in, uint16_t out[2]) { - const UTF32 *source_ptr = reinterpret_cast(&in); - const UTF32 *source_end_ptr = source_ptr + 1; - uint16_t *target_ptr = out; - uint16_t *target_end_ptr = target_ptr + 2 * sizeof(uint16_t); - out[0] = out[1] = 0; - ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr, - &target_ptr, target_end_ptr, - strictConversion); - - if (result != conversionOK) { - out[0] = out[1] = 0; - } -} - -static inline uint16_t Swap(uint16_t value) { - return (value >> 8) | static_cast(value << 8); -} - -string UTF16ToUTF8(const vector &in, bool swap) { - const UTF16 *source_ptr = &in[0]; - scoped_array source_buffer; - - // If we're to swap, we need to make a local copy and swap each byte pair - if (swap) { - int idx = 0; - source_buffer.reset(new uint16_t[in.size()]); - UTF16 *source_buffer_ptr = source_buffer.get(); - for (vector::const_iterator it = in.begin(); - it != in.end(); ++it, ++idx) - source_buffer_ptr[idx] = Swap(*it); - - source_ptr = source_buffer.get(); - } - - // The maximum expansion would be 4x the size of the input string. - const UTF16 *source_end_ptr = source_ptr + in.size(); - size_t target_capacity = in.size() * 4; - scoped_array target_buffer(new UTF8[target_capacity]); - UTF8 *target_ptr = target_buffer.get(); - UTF8 *target_end_ptr = target_ptr + target_capacity; - ConversionResult result = ConvertUTF16toUTF8(&source_ptr, source_end_ptr, - &target_ptr, target_end_ptr, - strictConversion); - - if (result == conversionOK) { - const char *targetPtr = reinterpret_cast(target_buffer.get()); - return targetPtr; - } - - return ""; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/string_conversion.h b/toolkit/crashreporter/google-breakpad/src/common/string_conversion.h deleted file mode 100644 index b9ba96a2e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/string_conversion.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// string_conversion.h: Conversion between different UTF-8/16/32 encodings. - -#ifndef COMMON_STRING_CONVERSION_H__ -#define COMMON_STRING_CONVERSION_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -using std::vector; - -// Convert |in| to UTF-16 into |out|. Use platform byte ordering. If the -// conversion failed, |out| will be zero length. -void UTF8ToUTF16(const char *in, vector *out); - -// Convert at least one character (up to a maximum of |in_length|) from |in| -// to UTF-16 into |out|. Return the number of characters consumed from |in|. -// Any unused characters in |out| will be initialized to 0. No memory will -// be allocated by this routine. -int UTF8ToUTF16Char(const char *in, int in_length, uint16_t out[2]); - -// Convert |in| to UTF-16 into |out|. Use platform byte ordering. If the -// conversion failed, |out| will be zero length. -void UTF32ToUTF16(const wchar_t *in, vector *out); - -// Convert |in| to UTF-16 into |out|. Any unused characters in |out| will be -// initialized to 0. No memory will be allocated by this routine. -void UTF32ToUTF16Char(wchar_t in, uint16_t out[2]); - -// Convert |in| to UTF-8. If |swap| is true, swap bytes before converting. -string UTF16ToUTF8(const vector &in, bool swap); - -} // namespace google_breakpad - -#endif // COMMON_STRING_CONVERSION_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/common/symbol_data.h b/toolkit/crashreporter/google-breakpad/src/common/symbol_data.h deleted file mode 100644 index 2cf15a855..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/symbol_data.h +++ /dev/null @@ -1,42 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef COMMON_SYMBOL_DATA_H_ -#define COMMON_SYMBOL_DATA_H_ - -// Control what data is used from the symbol file. -enum SymbolData { - ALL_SYMBOL_DATA, - NO_CFI, - ONLY_CFI -}; - -#endif // COMMON_SYMBOL_DATA_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/test_assembler.cc b/toolkit/crashreporter/google-breakpad/src/common/test_assembler.cc deleted file mode 100644 index 1e783b45c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/test_assembler.cc +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// test_assembler.cc: Implementation of google_breakpad::TestAssembler. -// See test_assembler.h for details. - -#include "common/test_assembler.h" - -#include -#include - -#include - -namespace google_breakpad { -namespace test_assembler { - -using std::back_insert_iterator; - -Label::Label() : value_(new Binding()) { } -Label::Label(uint64_t value) : value_(new Binding(value)) { } -Label::Label(const Label &label) { - value_ = label.value_; - value_->Acquire(); -} -Label::~Label() { - if (value_->Release()) delete value_; -} - -Label &Label::operator=(uint64_t value) { - value_->Set(NULL, value); - return *this; -} - -Label &Label::operator=(const Label &label) { - value_->Set(label.value_, 0); - return *this; -} - -Label Label::operator+(uint64_t addend) const { - Label l; - l.value_->Set(this->value_, addend); - return l; -} - -Label Label::operator-(uint64_t subtrahend) const { - Label l; - l.value_->Set(this->value_, -subtrahend); - return l; -} - -// When NDEBUG is #defined, assert doesn't evaluate its argument. This -// means you can't simply use assert to check the return value of a -// function with necessary side effects. -// -// ALWAYS_EVALUATE_AND_ASSERT(x) evaluates x regardless of whether -// NDEBUG is #defined; when NDEBUG is not #defined, it further asserts -// that x is true. -#ifdef NDEBUG -#define ALWAYS_EVALUATE_AND_ASSERT(x) x -#else -#define ALWAYS_EVALUATE_AND_ASSERT(x) assert(x) -#endif - -uint64_t Label::operator-(const Label &label) const { - uint64_t offset; - ALWAYS_EVALUATE_AND_ASSERT(IsKnownOffsetFrom(label, &offset)); - return offset; -} - -uint64_t Label::Value() const { - uint64_t v = 0; - ALWAYS_EVALUATE_AND_ASSERT(IsKnownConstant(&v)); - return v; -}; - -bool Label::IsKnownConstant(uint64_t *value_p) const { - Binding *base; - uint64_t addend; - value_->Get(&base, &addend); - if (base != NULL) return false; - if (value_p) *value_p = addend; - return true; -} - -bool Label::IsKnownOffsetFrom(const Label &label, uint64_t *offset_p) const -{ - Binding *label_base, *this_base; - uint64_t label_addend, this_addend; - label.value_->Get(&label_base, &label_addend); - value_->Get(&this_base, &this_addend); - // If this and label are related, Get will find their final - // common ancestor, regardless of how indirect the relation is. This - // comparison also handles the constant vs. constant case. - if (this_base != label_base) return false; - if (offset_p) *offset_p = this_addend - label_addend; - return true; -} - -Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) { } - -Label::Binding::Binding(uint64_t addend) - : base_(NULL), addend_(addend), reference_count_(1) { } - -Label::Binding::~Binding() { - assert(reference_count_ == 0); - if (base_ && base_ != this && base_->Release()) - delete base_; -} - -void Label::Binding::Set(Binding *binding, uint64_t addend) { - if (!base_ && !binding) { - // We're equating two constants. This could be okay. - assert(addend_ == addend); - } else if (!base_) { - // We are a known constant, but BINDING may not be, so turn the - // tables and try to set BINDING's value instead. - binding->Set(NULL, addend_ - addend); - } else { - if (binding) { - // Find binding's final value. Since the final value is always either - // completely unconstrained or a constant, never a reference to - // another variable (otherwise, it wouldn't be final), this - // guarantees we won't create cycles here, even for code like this: - // l = m, m = n, n = l; - uint64_t binding_addend; - binding->Get(&binding, &binding_addend); - addend += binding_addend; - } - - // It seems likely that setting a binding to itself is a bug - // (although I can imagine this might turn out to be helpful to - // permit). - assert(binding != this); - - if (base_ != this) { - // Set the other bindings on our chain as well. Note that this - // is sufficient even though binding relationships form trees: - // All binding operations traverse their chains to the end, and - // all bindings related to us share some tail of our chain, so - // they will see the changes we make here. - base_->Set(binding, addend - addend_); - // We're not going to use base_ any more. - if (base_->Release()) delete base_; - } - - // Adopt BINDING as our base. Note that it should be correct to - // acquire here, after the release above, even though the usual - // reference-counting rules call for acquiring first, and then - // releasing: the self-reference assertion above should have - // complained if BINDING were 'this' or anywhere along our chain, - // so we didn't release BINDING. - if (binding) binding->Acquire(); - base_ = binding; - addend_ = addend; - } -} - -void Label::Binding::Get(Binding **base, uint64_t *addend) { - if (base_ && base_ != this) { - // Recurse to find the end of our reference chain (the root of our - // tree), and then rewrite every binding along the chain to refer - // to it directly, adjusting addends appropriately. (This is why - // this member function isn't this-const.) - Binding *final_base; - uint64_t final_addend; - base_->Get(&final_base, &final_addend); - if (final_base) final_base->Acquire(); - if (base_->Release()) delete base_; - base_ = final_base; - addend_ += final_addend; - } - *base = base_; - *addend = addend_; -} - -template -static inline void InsertEndian(test_assembler::Endianness endianness, - size_t size, uint64_t number, Inserter dest) { - assert(size > 0); - if (endianness == kLittleEndian) { - for (size_t i = 0; i < size; i++) { - *dest++ = (char) (number & 0xff); - number >>= 8; - } - } else { - assert(endianness == kBigEndian); - // The loop condition is odd, but it's correct for size_t. - for (size_t i = size - 1; i < size; i--) - *dest++ = (char) ((number >> (i * 8)) & 0xff); - } -} - -Section &Section::Append(Endianness endianness, size_t size, uint64_t number) { - InsertEndian(endianness, size, number, - back_insert_iterator(contents_)); - return *this; -} - -Section &Section::Append(Endianness endianness, size_t size, - const Label &label) { - // If this label's value is known, there's no reason to waste an - // entry in references_ on it. - uint64_t value; - if (label.IsKnownConstant(&value)) - return Append(endianness, size, value); - - // This will get caught when the references are resolved, but it's - // nicer to find out earlier. - assert(endianness != kUnsetEndian); - - references_.push_back(Reference(contents_.size(), endianness, size, label)); - contents_.append(size, 0); - return *this; -} - -#define ENDIANNESS_L kLittleEndian -#define ENDIANNESS_B kBigEndian -#define ENDIANNESS(e) ENDIANNESS_ ## e - -#define DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \ - Section &Section::e ## bits(uint ## bits ## _t v) { \ - InsertEndian(ENDIANNESS(e), bits / 8, v, \ - back_insert_iterator(contents_)); \ - return *this; \ - } - -#define DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits) \ - Section &Section::e ## bits(const Label &v) { \ - return Append(ENDIANNESS(e), bits / 8, v); \ - } - -// Define L16, B32, and friends. -#define DEFINE_SHORT_APPEND_ENDIAN(e, bits) \ - DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \ - DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits) - -DEFINE_SHORT_APPEND_LABEL_ENDIAN(L, 8); -DEFINE_SHORT_APPEND_LABEL_ENDIAN(B, 8); -DEFINE_SHORT_APPEND_ENDIAN(L, 16); -DEFINE_SHORT_APPEND_ENDIAN(L, 32); -DEFINE_SHORT_APPEND_ENDIAN(L, 64); -DEFINE_SHORT_APPEND_ENDIAN(B, 16); -DEFINE_SHORT_APPEND_ENDIAN(B, 32); -DEFINE_SHORT_APPEND_ENDIAN(B, 64); - -#define DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \ - Section &Section::D ## bits(uint ## bits ## _t v) { \ - InsertEndian(endianness_, bits / 8, v, \ - back_insert_iterator(contents_)); \ - return *this; \ - } -#define DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits) \ - Section &Section::D ## bits(const Label &v) { \ - return Append(endianness_, bits / 8, v); \ - } -#define DEFINE_SHORT_APPEND_DEFAULT(bits) \ - DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \ - DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits) - -DEFINE_SHORT_APPEND_LABEL_DEFAULT(8) -DEFINE_SHORT_APPEND_DEFAULT(16); -DEFINE_SHORT_APPEND_DEFAULT(32); -DEFINE_SHORT_APPEND_DEFAULT(64); - -Section &Section::Append(const Section §ion) { - size_t base = contents_.size(); - contents_.append(section.contents_); - for (vector::const_iterator it = section.references_.begin(); - it != section.references_.end(); it++) - references_.push_back(Reference(base + it->offset, it->endianness, - it->size, it->label)); - return *this; -} - -Section &Section::LEB128(long long value) { - while (value < -0x40 || 0x3f < value) { - contents_ += (value & 0x7f) | 0x80; - if (value < 0) - value = (value >> 7) | ~(((unsigned long long) -1) >> 7); - else - value = (value >> 7); - } - contents_ += value & 0x7f; - return *this; -} - -Section &Section::ULEB128(uint64_t value) { - while (value > 0x7f) { - contents_ += (value & 0x7f) | 0x80; - value = (value >> 7); - } - contents_ += value; - return *this; -} - -Section &Section::Align(size_t alignment, uint8_t pad_byte) { - // ALIGNMENT must be a power of two. - assert(((alignment - 1) & alignment) == 0); - size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1); - contents_.append(new_size - contents_.size(), pad_byte); - assert((contents_.size() & (alignment - 1)) == 0); - return *this; -} - -void Section::Clear() { - contents_.clear(); - references_.clear(); -} - -bool Section::GetContents(string *contents) { - // For each label reference, find the label's value, and patch it into - // the section's contents. - for (size_t i = 0; i < references_.size(); i++) { - Reference &r = references_[i]; - uint64_t value; - if (!r.label.IsKnownConstant(&value)) { - fprintf(stderr, "Undefined label #%zu at offset 0x%zx\n", i, r.offset); - return false; - } - assert(r.offset < contents_.size()); - assert(contents_.size() - r.offset >= r.size); - InsertEndian(r.endianness, r.size, value, contents_.begin() + r.offset); - } - contents->clear(); - std::swap(contents_, *contents); - references_.clear(); - return true; -} - -} // namespace test_assembler -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/test_assembler.h b/toolkit/crashreporter/google-breakpad/src/common/test_assembler.h deleted file mode 100644 index 373dbebac..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/test_assembler.h +++ /dev/null @@ -1,484 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// test-assembler.h: interface to class for building complex binary streams. - -// To test the Breakpad symbol dumper and processor thoroughly, for -// all combinations of host system and minidump processor -// architecture, we need to be able to easily generate complex test -// data like debugging information and minidump files. -// -// For example, if we want our unit tests to provide full code -// coverage for stack walking, it may be difficult to persuade the -// compiler to generate every possible sort of stack walking -// information that we want to support; there are probably DWARF CFI -// opcodes that GCC never emits. Similarly, if we want to test our -// error handling, we will need to generate damaged minidumps or -// debugging information that (we hope) the client or compiler will -// never produce on its own. -// -// google_breakpad::TestAssembler provides a predictable and -// (relatively) simple way to generate complex formatted data streams -// like minidumps and CFI. Furthermore, because TestAssembler is -// portable, developers without access to (say) Visual Studio or a -// SPARC assembler can still work on test data for those targets. - -#ifndef PROCESSOR_TEST_ASSEMBLER_H_ -#define PROCESSOR_TEST_ASSEMBLER_H_ - -#include -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -using std::list; -using std::vector; - -namespace test_assembler { - -// A Label represents a value not yet known that we need to store in a -// section. As long as all the labels a section refers to are defined -// by the time we retrieve its contents as bytes, we can use undefined -// labels freely in that section's construction. -// -// A label can be in one of three states: -// - undefined, -// - defined as the sum of some other label and a constant, or -// - a constant. -// -// A label's value never changes, but it can accumulate constraints. -// Adding labels and integers is permitted, and yields a label. -// Subtracting a constant from a label is permitted, and also yields a -// label. Subtracting two labels that have some relationship to each -// other is permitted, and yields a constant. -// -// For example: -// -// Label a; // a's value is undefined -// Label b; // b's value is undefined -// { -// Label c = a + 4; // okay, even though a's value is unknown -// b = c + 4; // also okay; b is now a+8 -// } -// Label d = b - 2; // okay; d == a+6, even though c is gone -// d.Value(); // error: d's value is not yet known -// d - a; // is 6, even though their values are not known -// a = 12; // now b == 20, and d == 18 -// d.Value(); // 18: no longer an error -// b.Value(); // 20 -// d = 10; // error: d is already defined. -// -// Label objects' lifetimes are unconstrained: notice that, in the -// above example, even though a and b are only related through c, and -// c goes out of scope, the assignment to a sets b's value as well. In -// particular, it's not necessary to ensure that a Label lives beyond -// Sections that refer to it. -class Label { - public: - Label(); // An undefined label. - Label(uint64_t value); // A label with a fixed value - Label(const Label &value); // A label equal to another. - ~Label(); - - // Return this label's value; it must be known. - // - // Providing this as a cast operator is nifty, but the conversions - // happen in unexpected places. In particular, ISO C++ says that - // Label + size_t becomes ambigious, because it can't decide whether - // to convert the Label to a uint64_t and then to a size_t, or use - // the overloaded operator that returns a new label, even though the - // former could fail if the label is not yet defined and the latter won't. - uint64_t Value() const; - - Label &operator=(uint64_t value); - Label &operator=(const Label &value); - Label operator+(uint64_t addend) const; - Label operator-(uint64_t subtrahend) const; - uint64_t operator-(const Label &subtrahend) const; - - // We could also provide == and != that work on undefined, but - // related, labels. - - // Return true if this label's value is known. If VALUE_P is given, - // set *VALUE_P to the known value if returning true. - bool IsKnownConstant(uint64_t *value_p = NULL) const; - - // Return true if the offset from LABEL to this label is known. If - // OFFSET_P is given, set *OFFSET_P to the offset when returning true. - // - // You can think of l.KnownOffsetFrom(m, &d) as being like 'd = l-m', - // except that it also returns a value indicating whether the - // subtraction is possible given what we currently know of l and m. - // It can be possible even if we don't know l and m's values. For - // example: - // - // Label l, m; - // m = l + 10; - // l.IsKnownConstant(); // false - // m.IsKnownConstant(); // false - // uint64_t d; - // l.IsKnownOffsetFrom(m, &d); // true, and sets d to -10. - // l-m // -10 - // m-l // 10 - // m.Value() // error: m's value is not known - bool IsKnownOffsetFrom(const Label &label, uint64_t *offset_p = NULL) const; - - private: - // A label's value, or if that is not yet known, how the value is - // related to other labels' values. A binding may be: - // - a known constant, - // - constrained to be equal to some other binding plus a constant, or - // - unconstrained, and free to take on any value. - // - // Many labels may point to a single binding, and each binding may - // refer to another, so bindings and labels form trees whose leaves - // are labels, whose interior nodes (and roots) are bindings, and - // where links point from children to parents. Bindings are - // reference counted, allowing labels to be lightweight, copyable, - // assignable, placed in containers, and so on. - class Binding { - public: - Binding(); - Binding(uint64_t addend); - ~Binding(); - - // Increment our reference count. - void Acquire() { reference_count_++; }; - // Decrement our reference count, and return true if it is zero. - bool Release() { return --reference_count_ == 0; } - - // Set this binding to be equal to BINDING + ADDEND. If BINDING is - // NULL, then set this binding to the known constant ADDEND. - // Update every binding on this binding's chain to point directly - // to BINDING, or to be a constant, with addends adjusted - // appropriately. - void Set(Binding *binding, uint64_t value); - - // Return what we know about the value of this binding. - // - If this binding's value is a known constant, set BASE to - // NULL, and set ADDEND to its value. - // - If this binding is not a known constant but related to other - // bindings, set BASE to the binding at the end of the relation - // chain (which will always be unconstrained), and set ADDEND to the - // value to add to that binding's value to get this binding's - // value. - // - If this binding is unconstrained, set BASE to this, and leave - // ADDEND unchanged. - void Get(Binding **base, uint64_t *addend); - - private: - // There are three cases: - // - // - A binding representing a known constant value has base_ NULL, - // and addend_ equal to the value. - // - // - A binding representing a completely unconstrained value has - // base_ pointing to this; addend_ is unused. - // - // - A binding whose value is related to some other binding's - // value has base_ pointing to that other binding, and addend_ - // set to the amount to add to that binding's value to get this - // binding's value. We only represent relationships of the form - // x = y+c. - // - // Thus, the bind_ links form a chain terminating in either a - // known constant value or a completely unconstrained value. Most - // operations on bindings do path compression: they change every - // binding on the chain to point directly to the final value, - // adjusting addends as appropriate. - Binding *base_; - uint64_t addend_; - - // The number of Labels and Bindings pointing to this binding. - // (When a binding points to itself, indicating a completely - // unconstrained binding, that doesn't count as a reference.) - int reference_count_; - }; - - // This label's value. - Binding *value_; -}; - -inline Label operator+(uint64_t a, const Label &l) { return l + a; } -// Note that int-Label isn't defined, as negating a Label is not an -// operation we support. - -// Conventions for representing larger numbers as sequences of bytes. -enum Endianness { - kBigEndian, // Big-endian: the most significant byte comes first. - kLittleEndian, // Little-endian: the least significant byte comes first. - kUnsetEndian, // used internally -}; - -// A section is a sequence of bytes, constructed by appending bytes -// to the end. Sections have a convenient and flexible set of member -// functions for appending data in various formats: big-endian and -// little-endian signed and unsigned values of different sizes; -// LEB128 and ULEB128 values (see below), and raw blocks of bytes. -// -// If you need to append a value to a section that is not convenient -// to compute immediately, you can create a label, append the -// label's value to the section, and then set the label's value -// later, when it's convenient to do so. Once a label's value is -// known, the section class takes care of updating all previously -// appended references to it. -// -// Once all the labels to which a section refers have had their -// values determined, you can get a copy of the section's contents -// as a string. -// -// Note that there is no specified "start of section" label. This is -// because there are typically several different meanings for "the -// start of a section": the offset of the section within an object -// file, the address in memory at which the section's content appear, -// and so on. It's up to the code that uses the Section class to -// keep track of these explicitly, as they depend on the application. -class Section { - public: - Section(Endianness endianness = kUnsetEndian) - : endianness_(endianness) { }; - - // A base class destructor should be either public and virtual, - // or protected and nonvirtual. - virtual ~Section() { }; - - // Set the default endianness of this section to ENDIANNESS. This - // sets the behavior of the D appending functions. If the - // assembler's default endianness was set, this is the - void set_endianness(Endianness endianness) { - endianness_ = endianness; - } - - // Return the default endianness of this section. - Endianness endianness() const { return endianness_; } - - // Append the SIZE bytes at DATA or the contents of STRING to the - // end of this section. Return a reference to this section. - Section &Append(const uint8_t *data, size_t size) { - contents_.append(reinterpret_cast(data), size); - return *this; - }; - Section &Append(const string &data) { - contents_.append(data); - return *this; - }; - - // Append SIZE copies of BYTE to the end of this section. Return a - // reference to this section. - Section &Append(size_t size, uint8_t byte) { - contents_.append(size, (char) byte); - return *this; - } - - // Append NUMBER to this section. ENDIANNESS is the endianness to - // use to write the number. SIZE is the length of the number in - // bytes. Return a reference to this section. - Section &Append(Endianness endianness, size_t size, uint64_t number); - Section &Append(Endianness endianness, size_t size, const Label &label); - - // Append SECTION to the end of this section. The labels SECTION - // refers to need not be defined yet. - // - // Note that this has no effect on any Labels' values, or on - // SECTION. If placing SECTION within 'this' provides new - // constraints on existing labels' values, then it's up to the - // caller to fiddle with those labels as needed. - Section &Append(const Section §ion); - - // Append the contents of DATA as a series of bytes terminated by - // a NULL character. - Section &AppendCString(const string &data) { - Append(data); - contents_ += '\0'; - return *this; - } - - // Append at most SIZE bytes from DATA; if DATA is less than SIZE bytes - // long, pad with '\0' characters. - Section &AppendCString(const string &data, size_t size) { - contents_.append(data, 0, size); - if (data.size() < size) - Append(size - data.size(), 0); - return *this; - } - - // Append VALUE or LABEL to this section, with the given bit width and - // endianness. Return a reference to this section. - // - // The names of these functions have the form : - // is either 'L' (little-endian, least significant byte first), - // 'B' (big-endian, most significant byte first), or - // 'D' (default, the section's default endianness) - // is 8, 16, 32, or 64. - // - // Since endianness doesn't matter for a single byte, all the - // =8 functions are equivalent. - // - // These can be used to write both signed and unsigned values, as - // the compiler will properly sign-extend a signed value before - // passing it to the function, at which point the function's - // behavior is the same either way. - Section &L8(uint8_t value) { contents_ += value; return *this; } - Section &B8(uint8_t value) { contents_ += value; return *this; } - Section &D8(uint8_t value) { contents_ += value; return *this; } - Section &L16(uint16_t), &L32(uint32_t), &L64(uint64_t), - &B16(uint16_t), &B32(uint32_t), &B64(uint64_t), - &D16(uint16_t), &D32(uint32_t), &D64(uint64_t); - Section &L8(const Label &label), &L16(const Label &label), - &L32(const Label &label), &L64(const Label &label), - &B8(const Label &label), &B16(const Label &label), - &B32(const Label &label), &B64(const Label &label), - &D8(const Label &label), &D16(const Label &label), - &D32(const Label &label), &D64(const Label &label); - - // Append VALUE in a signed LEB128 (Little-Endian Base 128) form. - // - // The signed LEB128 representation of an integer N is a variable - // number of bytes: - // - // - If N is between -0x40 and 0x3f, then its signed LEB128 - // representation is a single byte whose value is N. - // - // - Otherwise, its signed LEB128 representation is (N & 0x7f) | - // 0x80, followed by the signed LEB128 representation of N / 128, - // rounded towards negative infinity. - // - // In other words, we break VALUE into groups of seven bits, put - // them in little-endian order, and then write them as eight-bit - // bytes with the high bit on all but the last. - // - // Note that VALUE cannot be a Label (we would have to implement - // relaxation). - Section &LEB128(long long value); - - // Append VALUE in unsigned LEB128 (Little-Endian Base 128) form. - // - // The unsigned LEB128 representation of an integer N is a variable - // number of bytes: - // - // - If N is between 0 and 0x7f, then its unsigned LEB128 - // representation is a single byte whose value is N. - // - // - Otherwise, its unsigned LEB128 representation is (N & 0x7f) | - // 0x80, followed by the unsigned LEB128 representation of N / - // 128, rounded towards negative infinity. - // - // Note that VALUE cannot be a Label (we would have to implement - // relaxation). - Section &ULEB128(uint64_t value); - - // Jump to the next location aligned on an ALIGNMENT-byte boundary, - // relative to the start of the section. Fill the gap with PAD_BYTE. - // ALIGNMENT must be a power of two. Return a reference to this - // section. - Section &Align(size_t alignment, uint8_t pad_byte = 0); - - // Clear the contents of this section. - void Clear(); - - // Return the current size of the section. - size_t Size() const { return contents_.size(); } - - // Return a label representing the start of the section. - // - // It is up to the user whether this label represents the section's - // position in an object file, the section's address in memory, or - // what have you; some applications may need both, in which case - // this simple-minded interface won't be enough. This class only - // provides a single start label, for use with the Here and Mark - // member functions. - // - // Ideally, we'd provide this in a subclass that actually knows more - // about the application at hand and can provide an appropriate - // collection of start labels. But then the appending member - // functions like Append and D32 would return a reference to the - // base class, not the derived class, and the chaining won't work. - // Since the only value here is in pretty notation, that's a fatal - // flaw. - Label start() const { return start_; } - - // Return a label representing the point at which the next Appended - // item will appear in the section, relative to start(). - Label Here() const { return start_ + Size(); } - - // Set *LABEL to Here, and return a reference to this section. - Section &Mark(Label *label) { *label = Here(); return *this; } - - // If there are no undefined label references left in this - // section, set CONTENTS to the contents of this section, as a - // string, and clear this section. Return true on success, or false - // if there were still undefined labels. - bool GetContents(string *contents); - - private: - // Used internally. A reference to a label's value. - struct Reference { - Reference(size_t set_offset, Endianness set_endianness, size_t set_size, - const Label &set_label) - : offset(set_offset), endianness(set_endianness), size(set_size), - label(set_label) { } - - // The offset of the reference within the section. - size_t offset; - - // The endianness of the reference. - Endianness endianness; - - // The size of the reference. - size_t size; - - // The label to which this is a reference. - Label label; - }; - - // The default endianness of this section. - Endianness endianness_; - - // The contents of the section. - string contents_; - - // References to labels within those contents. - vector references_; - - // A label referring to the beginning of the section. - Label start_; -}; - -} // namespace test_assembler -} // namespace google_breakpad - -#endif // PROCESSOR_TEST_ASSEMBLER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/test_assembler_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/test_assembler_unittest.cc deleted file mode 100644 index 94b5a5ce5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/test_assembler_unittest.cc +++ /dev/null @@ -1,1662 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// test_assembler_unittest.cc: Unit tests for google_breakpad::TestAssembler. - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" - -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using testing::Test; - -TEST(ConstructLabel, Simple) { - Label l; -} - -TEST(ConstructLabel, Undefined) { - Label l; - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(ConstructLabelDeathTest, Undefined) { - Label l; - ASSERT_DEATH(l.Value(), "IsKnownConstant\\(&v\\)"); -} - -TEST(ConstructLabel, Constant) { - Label l(0x060b9f974eaf301eULL); - uint64_t v; - EXPECT_TRUE(l.IsKnownConstant(&v)); - EXPECT_EQ(v, 0x060b9f974eaf301eULL); - EXPECT_EQ(l.Value(), 0x060b9f974eaf301eULL); -} - -TEST(ConstructLabel, Copy) { - Label l; - Label m(l); - uint64_t v; - EXPECT_TRUE(l.IsKnownOffsetFrom(m, &v)); - EXPECT_EQ(0U, v); -} - -// The left-hand-side of a label assignment can be either -// unconstrained, related, or known. The right-hand-side can be any of -// those, or an integer. -TEST(Assignment, UnconstrainedToUnconstrained) { - Label l, m; - l = m; - EXPECT_EQ(0U, l-m); - EXPECT_TRUE(l.IsKnownOffsetFrom(m)); - uint64_t d; - EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d)); - EXPECT_EQ(0U, d); - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(Assignment, UnconstrainedToRelated) { - Label l, m, n; - l = n; - l = m; - EXPECT_EQ(0U, l-m); - EXPECT_TRUE(l.IsKnownOffsetFrom(m)); - uint64_t d; - EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d)); - EXPECT_EQ(0U, d); - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(Assignment, UnconstrainedToKnown) { - Label l, m; - l = 0x8fd16e55b20a39c1ULL; - l = m; - EXPECT_EQ(0U, l-m); - EXPECT_TRUE(l.IsKnownOffsetFrom(m)); - uint64_t d; - EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d)); - EXPECT_EQ(0U, d); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x8fd16e55b20a39c1ULL, m.Value()); -} - -TEST(Assignment, RelatedToUnconstrained) { - Label l, m, n; - m = n; - l = m; - EXPECT_EQ(0U, l-n); - EXPECT_TRUE(l.IsKnownOffsetFrom(n)); - uint64_t d; - EXPECT_TRUE(l.IsKnownOffsetFrom(n, &d)); - EXPECT_EQ(0U, d); - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(Assignment, RelatedToRelated) { - Label l, m, n, o; - l = n; - m = o; - l = m; - EXPECT_EQ(0U, n-o); - EXPECT_TRUE(n.IsKnownOffsetFrom(o)); - uint64_t d; - EXPECT_TRUE(n.IsKnownOffsetFrom(o, &d)); - EXPECT_EQ(0U, d); - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(Assignment, RelatedToKnown) { - Label l, m, n; - m = n; - l = 0xd2011f8c82ad56f2ULL; - l = m; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0xd2011f8c82ad56f2ULL, l.Value()); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0xd2011f8c82ad56f2ULL, m.Value()); - EXPECT_TRUE(n.IsKnownConstant()); - EXPECT_EQ(0xd2011f8c82ad56f2ULL, n.Value()); -} - -TEST(Assignment, KnownToUnconstrained) { - Label l, m; - m = 0x50b024c0d6073887ULL; - l = m; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0x50b024c0d6073887ULL, l.Value()); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x50b024c0d6073887ULL, m.Value()); -} - -TEST(Assignment, KnownToRelated) { - Label l, m, n; - l = n; - m = 0x5348883655c727e5ULL; - l = m; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0x5348883655c727e5ULL, l.Value()); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x5348883655c727e5ULL, m.Value()); - EXPECT_TRUE(n.IsKnownConstant()); - EXPECT_EQ(0x5348883655c727e5ULL, n.Value()); -} - -TEST(Assignment, KnownToKnown) { - Label l, m; - l = 0x36c209c20987564eULL; - m = 0x36c209c20987564eULL; - l = m; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0x36c209c20987564eULL, l.Value()); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x36c209c20987564eULL, m.Value()); -} - -TEST(Assignment, ConstantToUnconstrained) { - Label l; - l = 0xc02495f4d7f5a957ULL; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0xc02495f4d7f5a957ULL, l.Value()); -} - -TEST(Assignment, ConstantToRelated) { - Label l, m; - l = m; - l = 0x4577901cf275488dULL; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0x4577901cf275488dULL, l.Value()); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x4577901cf275488dULL, m.Value()); -} - -TEST(Assignment, ConstantToKnown) { - Label l; - l = 0xec0b9c369b7e8ea7ULL; - l = 0xec0b9c369b7e8ea7ULL; - EXPECT_TRUE(l.IsKnownConstant()); - EXPECT_EQ(0xec0b9c369b7e8ea7ULL, l.Value()); -} - -TEST(AssignmentDeathTest, Self) { - Label l; - ASSERT_DEATH(l = l, "binding != this"); -} - -TEST(AssignmentDeathTest, IndirectCycle) { - Label l, m, n; - l = m; - m = n; - ASSERT_DEATH(n = l, "binding != this"); -} - -TEST(AssignmentDeathTest, Cycle) { - Label l, m, n, o; - l = m; - m = n; - o = n; - ASSERT_DEATH(o = l, "binding != this"); -} - -TEST(Addition, LabelConstant) { - Label l, m; - m = l + 0x5248d93e8bbe9497ULL; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(0x5248d93e8bbe9497ULL, d); - EXPECT_FALSE(m.IsKnownConstant()); -} - -TEST(Addition, ConstantLabel) { - Label l, m; - m = 0xf51e94e00d6e3c84ULL + l; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(0xf51e94e00d6e3c84ULL, d); - EXPECT_FALSE(m.IsKnownConstant()); -} - -TEST(Addition, KnownLabelConstant) { - Label l, m; - l = 0x16286307042ce0d8ULL; - m = l + 0x3fdddd91306719d7ULL; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(0x3fdddd91306719d7ULL, d); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x16286307042ce0d8ULL + 0x3fdddd91306719d7ULL, m.Value()); -} - -TEST(Addition, ConstantKnownLabel) { - Label l, m; - l = 0x50f62d0cdd1031deULL; - m = 0x1b13462d8577c538ULL + l; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(0x1b13462d8577c538ULL, d); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x50f62d0cdd1031deULL + 0x1b13462d8577c538ULL, m.Value()); -} - -TEST(Subtraction, LabelConstant) { - Label l, m; - m = l - 0x0620884d21d3138eULL; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(-0x0620884d21d3138eULL, d); - EXPECT_FALSE(m.IsKnownConstant()); -} - -TEST(Subtraction, KnownLabelConstant) { - Label l, m; - l = 0x6237fbaf9ef7929eULL; - m = l - 0x317730995d2ab6eeULL; - EXPECT_TRUE(m.IsKnownOffsetFrom(l)); - uint64_t d; - EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d)); - EXPECT_EQ(-0x317730995d2ab6eeULL, d); - EXPECT_TRUE(m.IsKnownConstant()); - EXPECT_EQ(0x6237fbaf9ef7929eULL - 0x317730995d2ab6eeULL, m.Value()); -} - -TEST(SubtractionDeathTest, LabelLabel) { - Label l, m; - ASSERT_DEATH(l - m, "IsKnownOffsetFrom\\(label, &offset\\)"); -} - -TEST(Subtraction, LabelLabel) { - Label l, m; - l = m + 0x7fa77ec63e28a17aULL; - EXPECT_EQ(0x7fa77ec63e28a17aULL, l - m); - EXPECT_EQ(-0x7fa77ec63e28a17aULL, m - l); -} - -TEST(IsKnownConstant, Undefined) { - Label l; - EXPECT_FALSE(l.IsKnownConstant()); -} - -TEST(IsKnownConstant, RelatedLabel) { - Label l, m; - l = m; - EXPECT_FALSE(l.IsKnownConstant()); - EXPECT_FALSE(m.IsKnownConstant()); -} - -TEST(IsKnownConstant, Constant) { - Label l; - l = 0xf374b1bdd6a22576ULL; - EXPECT_TRUE(l.IsKnownConstant()); -} - -TEST(IsKnownOffsetFrom, Unrelated) { - Label l, m; - EXPECT_FALSE(l.IsKnownOffsetFrom(m)); -} - -TEST(IsKnownOffsetFrom, Related) { - Label l, m; - l = m; - EXPECT_TRUE(l.IsKnownOffsetFrom(m)); -} - -// Test the construction of chains of related labels, and the -// propagation of values through them. -// -// Although the relations between labels are supposed to behave -// symmetrically --- that is, 'a = b' should put a and b in -// indistinguishable states --- there's a distinction made internally -// between the target (a) and the source (b). -// -// So there are five test axes to cover: -// -// - Do we construct the chain with assignment ("Assign") or with constructors -// ("Construct")? -// -// - Do we set the value of the label at the start of the chain -// ("Start") or the label at the end ("End")? -// -// - Are we testing the propagation of a relationship between variable -// values ("Relation"), or the propagation of a known constant value -// ("Value")? -// -// - Do we set the value before building the chain ("Before") or after -// the chain has been built ("After")? -// -// - Do we add new relationships to the end of the existing chain -// ("Forward") or to the beginning ("Backward")? -// -// Of course, "Construct" and "Backward" can't be combined, which -// eliminates eight combinations, and "Construct", "End", and "Before" -// can't be combined, which eliminates two more, so there are are 22 -// combinations, not 32. - -TEST(LabelChain, AssignStartRelationBeforeForward) { - Label a, b, c, d; - Label x; - a = x; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, AssignStartRelationBeforeBackward) { - Label a, b, c, d; - Label x; - a = x; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, AssignStartRelationAfterForward) { - Label a, b, c, d; - Label x; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - a = x; - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, AssignStartRelationAfterBackward) { - Label a, b, c, d; - Label x; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - a = x; - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, AssignStartValueBeforeForward) { - Label a, b, c, d; - a = 0xa131200190546ac2ULL; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - EXPECT_EQ(0xa131200190546ac2ULL + 0x111U, d.Value()); - EXPECT_EQ(0xa131200190546ac2ULL + 0x11U, c.Value()); - EXPECT_EQ(0xa131200190546ac2ULL + 0x1U, b.Value()); - EXPECT_EQ(0xa131200190546ac2ULL + 0U, a.Value()); -} - -TEST(LabelChain, AssignStartValueBeforeBackward) { - Label a, b, c, d; - a = 0x8da17e1670ad4fa2ULL; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x111U, d.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x11U, c.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x1U, b.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0U, a.Value()); -} - -TEST(LabelChain, AssignStartValueAfterForward) { - Label a, b, c, d; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - a = 0x99b8f51bafd41adaULL; - EXPECT_EQ(0x99b8f51bafd41adaULL + 0x111U, d.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL + 0x11U, c.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL + 0x1U, b.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL + 0U, a.Value()); -} - -TEST(LabelChain, AssignStartValueAfterBackward) { - Label a, b, c, d; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - a = 0xc86ca1d97ab5df6eULL; - EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x111U, d.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x11U, c.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x1U, b.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0U, a.Value()); -} - -TEST(LabelChain, AssignEndRelationBeforeForward) { - Label a, b, c, d; - Label x; - x = d; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - EXPECT_EQ(-(uint64_t)0x111U, a-x); - EXPECT_EQ(-(uint64_t)0x110U, b-x); - EXPECT_EQ(-(uint64_t)0x100U, c-x); - EXPECT_EQ(-(uint64_t)0U, d-x); -} - -TEST(LabelChain, AssignEndRelationBeforeBackward) { - Label a, b, c, d; - Label x; - x = d; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - EXPECT_EQ(-(uint64_t)0x111U, a-x); - EXPECT_EQ(-(uint64_t)0x110U, b-x); - EXPECT_EQ(-(uint64_t)0x100U, c-x); - EXPECT_EQ(-(uint64_t)0U, d-x); -} - -TEST(LabelChain, AssignEndRelationAfterForward) { - Label a, b, c, d; - Label x; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - x = d; - EXPECT_EQ(-(uint64_t)0x111U, a-x); - EXPECT_EQ(-(uint64_t)0x110U, b-x); - EXPECT_EQ(-(uint64_t)0x100U, c-x); - EXPECT_EQ(-(uint64_t)0x000U, d-x); -} - -TEST(LabelChain, AssignEndRelationAfterBackward) { - Label a, b, c, d; - Label x; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - x = d; - EXPECT_EQ(-(uint64_t)0x111U, a-x); - EXPECT_EQ(-(uint64_t)0x110U, b-x); - EXPECT_EQ(-(uint64_t)0x100U, c-x); - EXPECT_EQ(-(uint64_t)0x000U, d-x); -} - -TEST(LabelChain, AssignEndValueBeforeForward) { - Label a, b, c, d; - d = 0xa131200190546ac2ULL; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - EXPECT_EQ(0xa131200190546ac2ULL - 0x111, a.Value()); - EXPECT_EQ(0xa131200190546ac2ULL - 0x110, b.Value()); - EXPECT_EQ(0xa131200190546ac2ULL - 0x100, c.Value()); - EXPECT_EQ(0xa131200190546ac2ULL - 0x000, d.Value()); -} - -TEST(LabelChain, AssignEndValueBeforeBackward) { - Label a, b, c, d; - d = 0x8da17e1670ad4fa2ULL; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x111, a.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x110, b.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x100, c.Value()); - EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x000, d.Value()); -} - -TEST(LabelChain, AssignEndValueAfterForward) { - Label a, b, c, d; - b = a + 0x1; - c = b + 0x10; - d = c + 0x100; - d = 0x99b8f51bafd41adaULL; - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x111, a.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x110, b.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x100, c.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x000, d.Value()); -} - -TEST(LabelChain, AssignEndValueAfterBackward) { - Label a, b, c, d; - d = c + 0x100; - c = b + 0x10; - b = a + 0x1; - d = 0xc86ca1d97ab5df6eULL; - EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x111, a.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x110, b.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x100, c.Value()); - EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x000, d.Value()); -} - -TEST(LabelChain, ConstructStartRelationBeforeForward) { - Label x; - Label a(x); - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, ConstructStartRelationAfterForward) { - Label x; - Label a; - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - a = x; - EXPECT_EQ(0x111U, d-x); - EXPECT_EQ(0x11U, c-x); - EXPECT_EQ(0x1U, b-x); - EXPECT_EQ(0U, a-x); -} - -TEST(LabelChain, ConstructStartValueBeforeForward) { - Label a(0x5d234d177d01ccc8ULL); - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x111U, d.Value()); - EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x011U, c.Value()); - EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x001U, b.Value()); - EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x000U, a.Value()); -} - -TEST(LabelChain, ConstructStartValueAfterForward) { - Label a; - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - a = 0xded85d54586e84fcULL; - EXPECT_EQ(0xded85d54586e84fcULL + 0x111U, d.Value()); - EXPECT_EQ(0xded85d54586e84fcULL + 0x011U, c.Value()); - EXPECT_EQ(0xded85d54586e84fcULL + 0x001U, b.Value()); - EXPECT_EQ(0xded85d54586e84fcULL + 0x000U, a.Value()); -} - -TEST(LabelChain, ConstructEndRelationAfterForward) { - Label x; - Label a; - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - x = d; - EXPECT_EQ(-(uint64_t)0x111U, a-x); - EXPECT_EQ(-(uint64_t)0x110U, b-x); - EXPECT_EQ(-(uint64_t)0x100U, c-x); - EXPECT_EQ(-(uint64_t)0x000U, d-x); -} - -TEST(LabelChain, ConstructEndValueAfterForward) { - Label a; - Label b(a + 0x1); - Label c(b + 0x10); - Label d(c + 0x100); - d = 0x99b8f51bafd41adaULL; - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x111, a.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x110, b.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x100, c.Value()); - EXPECT_EQ(0x99b8f51bafd41adaULL - 0x000, d.Value()); -} - -TEST(LabelTree, KnownValue) { - Label l, m, n, o, p; - l = m; - m = n; - o = p; - p = n; - l = 0x536b5de3d468a1b5ULL; - EXPECT_EQ(0x536b5de3d468a1b5ULL, o.Value()); -} - -TEST(LabelTree, Related) { - Label l, m, n, o, p; - l = m - 1; - m = n - 10; - o = p + 100; - p = n + 1000; - EXPECT_EQ(1111U, o - l); -} - -TEST(EquationDeathTest, EqualConstants) { - Label m = 0x0d3962f280f07d24ULL; - Label n = 0x0d3962f280f07d24ULL; - m = n; // no death expected -} - -TEST(EquationDeathTest, EqualIndirectConstants) { - Label m = 0xa347f1e5238fe6a1ULL; - Label n; - Label o = n; - n = 0xa347f1e5238fe6a1ULL; - n = m; // no death expected -} - -TEST(EquationDeathTest, ConstantClash) { - Label m = 0xd4cc0f4f630ec741ULL; - Label n = 0x934cd2d8254fc3eaULL; - ASSERT_DEATH(m = n, "addend_ == addend"); -} - -TEST(EquationDeathTest, IndirectConstantClash) { - Label m = 0xd4cc0f4f630ec741ULL; - Label n, o; - n = o; - o = 0xcfbe3b83ac49ce86ULL; - ASSERT_DEATH(m = n, "addend_ == addend"); -} - -// Assigning to a related label may free the next Binding on its -// chain. This test always passes; it is interesting to memory -// checkers and coverage analysis. -TEST(LabelReferenceCount, AssignmentFree) { - Label l; - { - Label m; - l = m; - } - // This should free m's Binding. - l = 0xca8bae92f0376d4fULL; - ASSERT_EQ(0xca8bae92f0376d4fULL, l.Value()); -} - -// Finding the value of a label may free the Binding it refers to. This test -// always passes; it is interesting to memory checkers and coverage analysis. -TEST(LabelReferenceCount, FindValueFree) { - Label l; - { - Label m, n; - l = m; - m = n; - n = 0x7a0b0c576672daafULL; - // At this point, l's Binding refers to m's Binding, which refers - // to n's binding. - } - // Now, l is the only reference keeping the three Bindings alive. - // Resolving its value should free l's and m's original bindings. - ASSERT_EQ(0x7a0b0c576672daafULL, l.Value()); -} - -TEST(ConstructSection, Simple) { - Section s; -} - -TEST(ConstructSection, WithEndian) { - Section s(kBigEndian); -} - -// A fixture class for TestAssembler::Section tests. -class SectionFixture { - public: - Section section; - string contents; - static const uint8_t data[]; - static const size_t data_size; -}; - -const uint8_t SectionFixture::data[] = { - 0x87, 0x4f, 0x43, 0x67, 0x30, 0xd0, 0xd4, 0x0e -}; - -#define I0() -#define I1(a) { a } -#define I2(a,b) { a,b } -#define I3(a,b,c) { a,b,c } -#define I4(a,b,c,d) { a,b,c,d } -#define I5(a,b,c,d,e) { a,b,c,d,e } -#define I6(a,b,c,d,e,f) { a,b,c,d,e,f } -#define I7(a,b,c,d,e,f,g) { a,b,c,d,e,f,g } -#define I8(a,b,c,d,e,f,g,h) { a,b,c,d,e,f,g,h } -#define I9(a,b,c,d,e,f,g,h,i) { a,b,c,d,e,f,g,h,i } -#define ASSERT_BYTES(s, b) \ - do \ - { \ - static const uint8_t expected_bytes[] = b; \ - ASSERT_EQ(sizeof(expected_bytes), s.size()); \ - ASSERT_TRUE(memcmp(s.data(), (const char *) expected_bytes, \ - sizeof(expected_bytes)) == 0); \ - } \ - while(0) - -class Append: public SectionFixture, public Test { }; - -TEST_F(Append, Bytes) { - section.Append(data, sizeof(data)); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_EQ(sizeof(data), contents.size()); - EXPECT_TRUE(0 == memcmp(contents.data(), (const char *) data, sizeof(data))); -} - -TEST_F(Append, BytesTwice) { - section.Append(data, sizeof(data)); - section.Append(data, sizeof(data)); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_EQ(2 * sizeof(data), contents.size()); - ASSERT_TRUE(0 == memcmp(contents.data(), (const char *) data, sizeof(data))); - ASSERT_TRUE(0 == memcmp(contents.data() + sizeof(data), - (const char *) data, sizeof(data))); -} - -TEST_F(Append, String) { - string s1 = "howdy "; - string s2 = "there"; - section.Append(s1); - section.Append(s2); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_STREQ(contents.c_str(), "howdy there"); -} - -TEST_F(Append, CString) { - section.AppendCString("howdy"); - section.AppendCString(""); - section.AppendCString("there"); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_EQ(string("howdy\0\0there\0", 13), contents); -} - -TEST_F(Append, CStringSize) { - section.AppendCString("howdy", 3); - section.AppendCString("there", 5); - section.AppendCString("fred", 6); - section.AppendCString("natalie", 0); - section.AppendCString("", 10); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_EQ(string("howtherefred\0\0\0\0\0\0\0\0\0\0\0\0", 24), contents); -} - -TEST_F(Append, RepeatedBytes) { - section.Append((size_t) 10, '*'); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_STREQ(contents.c_str(), "**********"); -} - -TEST_F(Append, GeneralLE1) { - section.Append(kLittleEndian, 1, 42); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I1(42)); -} - -TEST_F(Append, GeneralLE2) { - section.Append(kLittleEndian, 2, 0x15a1); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0xa1, 0x15)); -} - -TEST_F(Append, GeneralLE3) { - section.Append(kLittleEndian, 3, 0x59ae8d); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x8d, 0xae, 0x59)); -} - -TEST_F(Append, GeneralLE4) { - section.Append(kLittleEndian, 4, 0x51603c56); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I4(0x56, 0x3c, 0x60, 0x51)); -} - -TEST_F(Append, GeneralLE5) { - section.Append(kLittleEndian, 5, 0x385e2803b4ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0xb4, 0x03, 0x28, 0x5e, 0x38)); -} - -TEST_F(Append, GeneralLE6) { - section.Append(kLittleEndian, 6, 0xc7db9534dd1fULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I6(0x1f, 0xdd, 0x34, 0x95, 0xdb, 0xc7)); -} - -TEST_F(Append, GeneralLE7) { - section.Append(kLittleEndian, 7, 0x1445c9f1b843e6ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I7(0xe6, 0x43, 0xb8, 0xf1, 0xc9, 0x45, 0x14)); -} - -TEST_F(Append, GeneralLE8) { - section.Append(kLittleEndian, 8, 0xaf48019dfe5c01e5ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I8(0xe5, 0x01, 0x5c, 0xfe, 0x9d, 0x01, 0x48, 0xaf)); -} - -TEST_F(Append, GeneralBE1) { - section.Append(kBigEndian, 1, 0xd0ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I1(0xd0)); -} - -TEST_F(Append, GeneralBE2) { - section.Append(kBigEndian, 2, 0x2e7eULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2e, 0x7e)); -} - -TEST_F(Append, GeneralBE3) { - section.Append(kBigEndian, 3, 0x37dad6ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x37, 0xda, 0xd6)); -} - -TEST_F(Append, GeneralBE4) { - section.Append(kBigEndian, 4, 0x715935c7ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I4(0x71, 0x59, 0x35, 0xc7)); -} - -TEST_F(Append, GeneralBE5) { - section.Append(kBigEndian, 5, 0x42baeb02b7ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x42, 0xba, 0xeb, 0x02, 0xb7)); -} - -TEST_F(Append, GeneralBE6) { - section.Append(kBigEndian, 6, 0xf1cdf10e7b18ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I6(0xf1, 0xcd, 0xf1, 0x0e, 0x7b, 0x18)); -} - -TEST_F(Append, GeneralBE7) { - section.Append(kBigEndian, 7, 0xf50a724f0b0d20ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I7(0xf5, 0x0a, 0x72, 0x4f, 0x0b, 0x0d, 0x20)); -} - -TEST_F(Append, GeneralBE8) { - section.Append(kBigEndian, 8, 0xa6b2cb5e98dc9c16ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I8(0xa6, 0xb2, 0xcb, 0x5e, 0x98, 0xdc, 0x9c, 0x16)); -} - -TEST_F(Append, GeneralLE1Label) { - Label l; - section.Append(kLittleEndian, 1, l); - l = 42; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I1(42)); -} - -TEST_F(Append, GeneralLE2Label) { - Label l; - section.Append(kLittleEndian, 2, l); - l = 0x15a1; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0xa1, 0x15)); -} - -TEST_F(Append, GeneralLE3Label) { - Label l; - section.Append(kLittleEndian, 3, l); - l = 0x59ae8d; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x8d, 0xae, 0x59)); -} - -TEST_F(Append, GeneralLE4Label) { - Label l; - section.Append(kLittleEndian, 4, l); - l = 0x51603c56; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I4(0x56, 0x3c, 0x60, 0x51)); -} - -TEST_F(Append, GeneralLE5Label) { - Label l; - section.Append(kLittleEndian, 5, l); - l = 0x385e2803b4ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0xb4, 0x03, 0x28, 0x5e, 0x38)); -} - -TEST_F(Append, GeneralLE6Label) { - Label l; - section.Append(kLittleEndian, 6, l); - l = 0xc7db9534dd1fULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I6(0x1f, 0xdd, 0x34, 0x95, 0xdb, 0xc7)); -} - -TEST_F(Append, GeneralLE7Label) { - Label l; - section.Append(kLittleEndian, 7, l); - l = 0x1445c9f1b843e6ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I7(0xe6, 0x43, 0xb8, 0xf1, 0xc9, 0x45, 0x14)); -} - -TEST_F(Append, GeneralLE8Label) { - Label l; - section.Append(kLittleEndian, 8, l); - l = 0xaf48019dfe5c01e5ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I8(0xe5, 0x01, 0x5c, 0xfe, 0x9d, 0x01, 0x48, 0xaf)); -} - -TEST_F(Append, GeneralBE1Label) { - Label l; - section.Append(kBigEndian, 1, l); - l = 0xd0ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I1(0xd0)); -} - -TEST_F(Append, GeneralBE2Label) { - Label l; - section.Append(kBigEndian, 2, l); - l = 0x2e7eULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2e, 0x7e)); -} - -TEST_F(Append, GeneralBE3Label) { - Label l; - section.Append(kBigEndian, 3, l); - l = 0x37dad6ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x37, 0xda, 0xd6)); -} - -TEST_F(Append, GeneralBE4Label) { - Label l; - section.Append(kBigEndian, 4, l); - l = 0x715935c7ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I4(0x71, 0x59, 0x35, 0xc7)); -} - -TEST_F(Append, GeneralBE5Label) { - Label l; - section.Append(kBigEndian, 5, l); - l = 0x42baeb02b7ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x42, 0xba, 0xeb, 0x02, 0xb7)); -} - -TEST_F(Append, GeneralBE6Label) { - Label l; - section.Append(kBigEndian, 6, l); - l = 0xf1cdf10e7b18ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I6(0xf1, 0xcd, 0xf1, 0x0e, 0x7b, 0x18)); -} - -TEST_F(Append, GeneralBE7Label) { - Label l; - section.Append(kBigEndian, 7, l); - l = 0xf50a724f0b0d20ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I7(0xf5, 0x0a, 0x72, 0x4f, 0x0b, 0x0d, 0x20)); -} - -TEST_F(Append, GeneralBE8Label) { - Label l; - section.Append(kBigEndian, 8, l); - l = 0xa6b2cb5e98dc9c16ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I8(0xa6, 0xb2, 0xcb, 0x5e, 0x98, 0xdc, 0x9c, 0x16)); -} - -TEST_F(Append, B8) { - section.Append(1, 0x2a); - section.B8(0xd3U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0xd3)); -} - -TEST_F(Append, B8Label) { - Label l; - section.Append(1, 0x2a); - section.B8(l); - l = 0x4bU; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0x4b)); -} - -TEST_F(Append, B16) { - section.Append(1, 0x2a); - section.B16(0x472aU); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x47, 0x2a)); -} - -TEST_F(Append, B16Label) { - Label l; - section.Append(1, 0x2a); - section.B16(l); - l = 0x55e8U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x55, 0xe8)); -} - -TEST_F(Append, B32) { - section.Append(1, 0x2a); - section.B32(0xbd412cbcU); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0xbd, 0x41, 0x2c, 0xbc)); -} - -TEST_F(Append, B32Label) { - Label l; - section.Append(1, 0x2a); - section.B32(l); - l = 0x208e37d5U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0x20, 0x8e, 0x37, 0xd5)); -} - -TEST_F(Append, B64) { - section.Append(1, 0x2a); - section.B64(0x3402a013111e68adULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0x34, 0x02, 0xa0, 0x13, 0x11, 0x1e, 0x68, 0xad)); -} - -TEST_F(Append, B64Label) { - Label l; - section.Append(1, 0x2a); - section.B64(l); - l = 0x355dbfbb4ac6d57fULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0x35, 0x5d, 0xbf, 0xbb, 0x4a, 0xc6, 0xd5, 0x7f)); -} - -TEST_F(Append, L8) { - section.Append(1, 0x2a); - section.L8(0x26U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0x26)); -} - -TEST_F(Append, L8Label) { - Label l; - section.Append(1, 0x2a); - section.L8(l); - l = 0xa8U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0xa8)); -} - -TEST_F(Append, L16) { - section.Append(1, 0x2a); - section.L16(0xca6dU); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x6d, 0xca)); -} - -TEST_F(Append, L16Label) { - Label l; - section.Append(1, 0x2a); - section.L16(l); - l = 0xd21fU; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x1f, 0xd2)); -} - -TEST_F(Append, L32) { - section.Append(1, 0x2a); - section.L32(0x558f6181U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0x81, 0x61, 0x8f, 0x55)); -} - -TEST_F(Append, L32Label) { - Label l; - section.Append(1, 0x2a); - section.L32(l); - l = 0x4b810f82U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0x82, 0x0f, 0x81, 0x4b)); -} - -TEST_F(Append, L64) { - section.Append(1, 0x2a); - section.L64(0x564384f7579515bfULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0xbf, 0x15, 0x95, 0x57, 0xf7, 0x84, 0x43, 0x56)); -} - -TEST_F(Append, L64Label) { - Label l; - section.Append(1, 0x2a); - section.L64(l); - l = 0x424b1d020667c8dbULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0xdb, 0xc8, 0x67, 0x06, 0x02, 0x1d, 0x4b, 0x42)); -} - -TEST_F(Append, D8Big) { - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D8(0xe6U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0xe6)); -} - -TEST_F(Append, D8BigLabel) { - Label l; - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D8(l); - l = 0xeeU; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0xee)); -} - -TEST_F(Append, D16Big) { - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D16(0x83b1U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x83, 0xb1)); -} - -TEST_F(Append, D16BigLabel) { - Label l; - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D16(l); - l = 0x5b55U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x5b, 0x55)); -} - -TEST_F(Append, D32Big) { - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D32(0xd0b0e431U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0xd0, 0xb0, 0xe4, 0x31)); -} - -TEST_F(Append, D32BigLabel) { - Label l; - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D32(l); - l = 0x312fb340U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0x31, 0x2f, 0xb3, 0x40)); -} - -TEST_F(Append, D64Big) { - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D64(0xb109843500dbcb16ULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0xb1, 0x09, 0x84, 0x35, 0x00, 0xdb, 0xcb, 0x16)); -} - -TEST_F(Append, D64BigLabel) { - Label l; - section.set_endianness(kBigEndian); - section.Append(1, 0x2a); - section.D64(l); - l = 0x9a0d61b70f671fd7ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0x9a, 0x0d, 0x61, 0xb7, 0x0f, 0x67, 0x1f, 0xd7)); -} - -TEST_F(Append, D8Little) { - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D8(0x42U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0x42)); -} - -TEST_F(Append, D8LittleLabel) { - Label l; - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D8(l); - l = 0x05U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I2(0x2a, 0x05)); -} - -TEST_F(Append, D16Little) { - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D16(0xc5c5U); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0xc5, 0xc5)); -} - -TEST_F(Append, D16LittleLabel) { - Label l; - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D16(l); - l = 0xb620U; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I3(0x2a, 0x20, 0xb6)); -} - -TEST_F(Append, D32Little) { - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D32(0x1a87d0feU); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0xfe, 0xd0, 0x87, 0x1a)); -} - -TEST_F(Append, D32LittleLabel) { - Label l; - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D32(l); - l = 0xb8012d6bU; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I5(0x2a, 0x6b, 0x2d, 0x01, 0xb8)); -} - -TEST_F(Append, D64Little) { - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D64(0x42de75c61375a1deULL); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0xde, 0xa1, 0x75, 0x13, 0xc6, 0x75, 0xde, 0x42)); -} - -TEST_F(Append, D64LittleLabel) { - Label l; - section.set_endianness(kLittleEndian); - section.Append(1, 0x2a); - section.D64(l); - l = 0x8b3bececf3fb5312ULL; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, - I9(0x2a, 0x12, 0x53, 0xfb, 0xf3, 0xec, 0xec, 0x3b, 0x8b)); -} - -TEST_F(Append, Variety) { - Label a, b, c, d, e, f, g, h; - section.Append(kBigEndian, 1, a) - .Append(kLittleEndian, 8, h) - .Append(kBigEndian, 1, 0x8bULL) - .Append(kLittleEndian, 8, 0x0ea56540448f4439ULL) - .Append(kBigEndian, 2, b) - .Append(kLittleEndian, 7, g) - .Append(kBigEndian, 2, 0xcf15ULL) - .Append(kLittleEndian, 7, 0x29694f04c5724aULL) - .Append(kBigEndian, 3, c) - .Append(kLittleEndian, 6, f) - .Append(kBigEndian, 3, 0x8c3ffdULL) - .Append(kLittleEndian, 6, 0x6f11ba80187aULL) - .Append(kBigEndian, 4, d) - .Append(kLittleEndian, 5, e) - .Append(kBigEndian, 4, 0x2fda2472ULL) - .Append(kLittleEndian, 5, 0x0aa02d423fULL) - .Append(kBigEndian, 5, e) - .Append(kLittleEndian, 4, d) - .Append(kBigEndian, 5, 0x53ba432138ULL) - .Append(kLittleEndian, 4, 0xf139ae60ULL) - .Append(kBigEndian, 6, f) - .Append(kLittleEndian, 3, c) - .Append(kBigEndian, 6, 0x168e436af716ULL) - .Append(kLittleEndian, 3, 0x3ef189ULL) - .Append(kBigEndian, 7, g) - .Append(kLittleEndian, 2, b) - .Append(kBigEndian, 7, 0xacd4ef233e47d9ULL) - .Append(kLittleEndian, 2, 0x5311ULL) - .Append(kBigEndian, 8, h) - .Append(kLittleEndian, 1, a) - .Append(kBigEndian, 8, 0x4668d5f1c93637a1ULL) - .Append(kLittleEndian, 1, 0x65ULL); - a = 0x79ac9bd8aa256b35ULL; - b = 0x22d13097ef86c91cULL; - c = 0xf204968b0a05862fULL; - d = 0x163177f15a0eb4ecULL; - e = 0xbd1b0f1d977f2246ULL; - f = 0x2b0842eee83c6461ULL; - g = 0x92f4b928a4bf875eULL; - h = 0x61a199a8f7286ba6ULL; - ASSERT_EQ(8 * 18U, section.Size()); - ASSERT_TRUE(section.GetContents(&contents)); - - static const uint8_t expected[] = { - 0x35, 0xa6, 0x6b, 0x28, 0xf7, 0xa8, 0x99, 0xa1, 0x61, - 0x8b, 0x39, 0x44, 0x8f, 0x44, 0x40, 0x65, 0xa5, 0x0e, - 0xc9, 0x1c, 0x5e, 0x87, 0xbf, 0xa4, 0x28, 0xb9, 0xf4, - 0xcf, 0x15, 0x4a, 0x72, 0xc5, 0x04, 0x4f, 0x69, 0x29, - 0x05, 0x86, 0x2f, 0x61, 0x64, 0x3c, 0xe8, 0xee, 0x42, - 0x8c, 0x3f, 0xfd, 0x7a, 0x18, 0x80, 0xba, 0x11, 0x6f, - 0x5a, 0x0e, 0xb4, 0xec, 0x46, 0x22, 0x7f, 0x97, 0x1d, - 0x2f, 0xda, 0x24, 0x72, 0x3f, 0x42, 0x2d, 0xa0, 0x0a, - 0x1d, 0x97, 0x7f, 0x22, 0x46, 0xec, 0xb4, 0x0e, 0x5a, - 0x53, 0xba, 0x43, 0x21, 0x38, 0x60, 0xae, 0x39, 0xf1, - 0x42, 0xee, 0xe8, 0x3c, 0x64, 0x61, 0x2f, 0x86, 0x05, - 0x16, 0x8e, 0x43, 0x6a, 0xf7, 0x16, 0x89, 0xf1, 0x3e, - 0xf4, 0xb9, 0x28, 0xa4, 0xbf, 0x87, 0x5e, 0x1c, 0xc9, - 0xac, 0xd4, 0xef, 0x23, 0x3e, 0x47, 0xd9, 0x11, 0x53, - 0x61, 0xa1, 0x99, 0xa8, 0xf7, 0x28, 0x6b, 0xa6, 0x35, - 0x46, 0x68, 0xd5, 0xf1, 0xc9, 0x36, 0x37, 0xa1, 0x65, - }; - - ASSERT_TRUE(0 == memcmp(contents.data(), expected, sizeof(expected))); -} - -TEST_F(Append, Section) { - section.Append("murder"); - { - Section middle; - middle.Append(" she"); - section.Append(middle); - } - section.Append(" wrote"); - EXPECT_EQ(16U, section.Size()); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_STREQ(contents.c_str(), "murder she wrote"); -} - -TEST_F(Append, SectionRefs) { - section.Append("sugar "); - Label l; - { - Section middle; - Label m; - middle.B32(m); - section.Append(middle); - m = 0x66726565; - } - section.Append(" jazz"); - EXPECT_EQ(15U, section.Size()); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_STREQ(contents.c_str(), "sugar free jazz"); -} - -TEST_F(Append, LEB128_0) { - section.LEB128(0); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\0", 1), contents); -} - -TEST_F(Append, LEB128_0x3f) { - section.LEB128(0x3f); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x3f", 1), contents); -} - -TEST_F(Append, LEB128_0x40) { - section.LEB128(0x40); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xc0\x00", 2), contents); -} - -TEST_F(Append, LEB128_0x7f) { - section.LEB128(0x7f); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x00", 2), contents); -} - -TEST_F(Append, LEB128_0x80) { - section.LEB128(0x80); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x01", 2), contents); -} - -TEST_F(Append, LEB128_0xff) { - section.LEB128(0xff); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x01", 2), contents); -} - -TEST_F(Append, LEB128_0x1fff) { - section.LEB128(0x1fff); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x3f", 2), contents); -} - -TEST_F(Append, LEB128_0x2000) { - section.LEB128(0x2000); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\xc0\x00", 3), contents); -} - -TEST_F(Append, LEB128_n1) { - section.LEB128(-1); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x7f", 1), contents); -} - -TEST_F(Append, LEB128_n0x40) { - section.LEB128(-0x40); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x40", 1), contents); -} - -TEST_F(Append, LEB128_n0x41) { - section.LEB128(-0x41); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xbf\x7f", 2), contents); -} - -TEST_F(Append, LEB128_n0x7f) { - section.LEB128(-0x7f); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x81\x7f", 2), contents); -} - -TEST_F(Append, LEB128_n0x80) { - section.LEB128(-0x80); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x7f", 2), contents); -} - -TEST_F(Append, LEB128_n0x2000) { - section.LEB128(-0x2000); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x40", 2), contents); -} - -TEST_F(Append, LEB128_n0x2001) { - section.LEB128(-0x2001); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\xbf\x7f", 3), contents); -} - -TEST_F(Append,ULEB128_0) { - section.ULEB128(0); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\0", 1), contents); -} - -TEST_F(Append,ULEB128_1) { - section.ULEB128(1); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x01", 1), contents); -} - -TEST_F(Append,ULEB128_0x3f) { - section.ULEB128(0x3f); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x3f", 1), contents); -} - -TEST_F(Append,ULEB128_0x40) { - section.ULEB128(0x40); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x40", 1), contents); -} - -TEST_F(Append,ULEB128_0x7f) { - section.ULEB128(0x7f); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x7f", 1), contents); -} - -TEST_F(Append,ULEB128_0x80) { - section.ULEB128(0x80); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x01", 2), contents); -} - -TEST_F(Append,ULEB128_0xff) { - section.ULEB128(0xff); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x01", 2), contents); -} - -TEST_F(Append,ULEB128_0x100) { - section.ULEB128(0x100); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x02", 2), contents); -} - -TEST_F(Append,ULEB128_0x1fff) { - section.ULEB128(0x1fff); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x3f", 2), contents); -} - -TEST_F(Append,ULEB128_0x2000) { - section.ULEB128(0x2000); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x40", 2), contents); -} - -TEST_F(Append,ULEB128_0x3fff) { - section.ULEB128(0x3fff); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xff\x7f", 2), contents); -} - -TEST_F(Append,ULEB128_0x4000) { - section.ULEB128(0x4000); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x80\x01", 3), contents); -} - -TEST_F(Append,ULEB128_12857) { - section.ULEB128(12857); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\xb9\x64", 2), contents); -} - -TEST_F(Append, LEBChain) { - section.LEB128(-0x80).ULEB128(12857).Append("*"); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x80\x7f\xb9\x64*", 5), contents); -} - - -class GetContents: public SectionFixture, public Test { }; - -TEST_F(GetContents, Undefined) { - Label l; - section.Append(kLittleEndian, 8, l); - ASSERT_FALSE(section.GetContents(&contents)); -} - -TEST_F(GetContents, ClearsContents) { - section.Append((size_t) 10, '*'); - EXPECT_EQ(10U, section.Size()); - EXPECT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(0U, section.Size()); -} - -TEST_F(GetContents, ClearsReferences) { - Label l; - section.Append(kBigEndian, 1, l); - l = 42; - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_BYTES(contents, I1(42)); - ASSERT_TRUE(section.GetContents(&contents)); // should not die -} - -class Miscellanea: public SectionFixture, public Test { }; - -TEST_F(Miscellanea, Clear) { - section.Append("howdy"); - Label l; - section.L32(l); - EXPECT_EQ(9U, section.Size()); - section.Clear(); - EXPECT_EQ(0U, section.Size()); - l = 0x8d231bf0U; - ASSERT_TRUE(section.GetContents(&contents)); // should not die -} - -TEST_F(Miscellanea, Align) { - section.Append("*"); - EXPECT_EQ(1U, section.Size()); - section.Align(4).Append("*"); - EXPECT_EQ(5U, section.Size()); - section.Append("*").Align(2); - EXPECT_EQ(6U, section.Size()); -} - -TEST_F(Miscellanea, AlignPad) { - section.Append("*"); - EXPECT_EQ(1U, section.Size()); - section.Align(4, ' ').Append("*"); - EXPECT_EQ(5U, section.Size()); - section.Append("*").Align(2, ' '); - EXPECT_EQ(6U, section.Size()); - ASSERT_TRUE(section.GetContents(&contents)); - ASSERT_EQ(string("* **"), contents); -} - -TEST_F(Miscellanea, StartHereMark) { - Label m; - section.Append(42, ' ').Mark(&m).Append(13, '+'); - EXPECT_EQ(42U, m - section.start()); - EXPECT_EQ(42U + 13U, section.Here() - section.start()); - EXPECT_FALSE(section.start().IsKnownConstant()); - EXPECT_FALSE(m.IsKnownConstant()); - EXPECT_FALSE(section.Here().IsKnownConstant()); -} - -TEST_F(Miscellanea, Endianness) { - section.set_endianness(kBigEndian); - EXPECT_EQ(kBigEndian, section.endianness()); - section.set_endianness(kLittleEndian); - EXPECT_EQ(kLittleEndian, section.endianness()); -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/testdata/func-line-pairing.h b/toolkit/crashreporter/google-breakpad/src/common/testdata/func-line-pairing.h deleted file mode 100644 index 05538f961..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/testdata/func-line-pairing.h +++ /dev/null @@ -1,676 +0,0 @@ -// -*- mode: c++ -*- - -// Test data for pairing functions and lines. -// -// For a pair of functions that are adjacent (10,20),(20,25) and a -// pair that are not (10,15),(20,25), we include a test case for every -// possible arrangement of two lines relative to those functions. We -// include cases only for non-empty ranges, since empty functions and -// lines are dropped before we do any pairing. -// -// Each test case is represented by a macro call of the form: -// -// PAIRING(func1_start, func1_end, func2_start, func2_end, -// line1_start, line1_end, line2_start, line2_end, -// func1_num_lines, func2_num_lines, -// func1_line1_start, func1_line1_end, -// func1_line2_start, func1_line2_end, -// func2_line1_start, func2_line1_end, -// func2_line2_start, func2_line2_end, -// uncovered_funcs, uncovered_lines) -// -// where: -// - funcN_{start,end} is the range of the N'th function -// - lineN_{start,end} is the range of the N'th function -// - funcN_num_lines is the number of source lines that should be -// paired with the N'th function -// - funcN_lineM_{start,end} is the range of the M'th line -// paired with the N'th function, where 0,0 indicates that -// there should be no such line paired -// - uncovered_funcs is the number of functions with area that is -// uncovered by any line, and -// - uncovered_lines is the reverse. - -// func1 func2 line1 line2 num pairing1 pairing2 uncovered -PAIRING(10, 20, 20, 25, 6, 7, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #0 -PAIRING(10, 20, 20, 25, 6, 7, 7, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #1 -PAIRING(10, 20, 20, 25, 6, 7, 7, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #2 -PAIRING(10, 20, 20, 25, 6, 7, 7, 20, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 2) // #3 -PAIRING(10, 20, 20, 25, 6, 7, 7, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 2) // #4 -PAIRING(10, 20, 20, 25, 6, 7, 7, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #5 -PAIRING(10, 20, 20, 25, 6, 7, 7, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #6 -PAIRING(10, 20, 20, 25, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #7 -PAIRING(10, 20, 20, 25, 6, 7, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #8 -PAIRING(10, 20, 20, 25, 6, 7, 8, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #9 -PAIRING(10, 20, 20, 25, 6, 7, 8, 20, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 2) // #10 -PAIRING(10, 20, 20, 25, 6, 7, 8, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 2) // #11 -PAIRING(10, 20, 20, 25, 6, 7, 8, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #12 -PAIRING(10, 20, 20, 25, 6, 7, 8, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #13 -PAIRING(10, 20, 20, 25, 6, 7, 10, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #14 -PAIRING(10, 20, 20, 25, 6, 7, 10, 20, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 1) // #15 -PAIRING(10, 20, 20, 25, 6, 7, 10, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 1) // #16 -PAIRING(10, 20, 20, 25, 6, 7, 10, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #17 -PAIRING(10, 20, 20, 25, 6, 7, 10, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #18 -PAIRING(10, 20, 20, 25, 6, 7, 11, 12, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #19 -PAIRING(10, 20, 20, 25, 6, 7, 11, 20, 1, 0, 11, 20, 0, 0, 0, 0, 0, 0, 2, 1) // #20 -PAIRING(10, 20, 20, 25, 6, 7, 11, 21, 1, 1, 11, 20, 0, 0, 20, 21, 0, 0, 2, 1) // #21 -PAIRING(10, 20, 20, 25, 6, 7, 11, 25, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 1) // #22 -PAIRING(10, 20, 20, 25, 6, 7, 11, 26, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 2) // #23 -PAIRING(10, 20, 20, 25, 6, 7, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #24 -PAIRING(10, 20, 20, 25, 6, 7, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #25 -PAIRING(10, 20, 20, 25, 6, 7, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #26 -PAIRING(10, 20, 20, 25, 6, 7, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #27 -PAIRING(10, 20, 20, 25, 6, 7, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #28 -PAIRING(10, 20, 20, 25, 6, 7, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #29 -PAIRING(10, 20, 20, 25, 6, 7, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #30 -PAIRING(10, 20, 20, 25, 6, 7, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #31 -PAIRING(10, 20, 20, 25, 6, 10, 10, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #32 -PAIRING(10, 20, 20, 25, 6, 10, 10, 20, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 1) // #33 -PAIRING(10, 20, 20, 25, 6, 10, 10, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 1) // #34 -PAIRING(10, 20, 20, 25, 6, 10, 10, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #35 -PAIRING(10, 20, 20, 25, 6, 10, 10, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #36 -PAIRING(10, 20, 20, 25, 6, 10, 11, 12, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #37 -PAIRING(10, 20, 20, 25, 6, 10, 11, 20, 1, 0, 11, 20, 0, 0, 0, 0, 0, 0, 2, 1) // #38 -PAIRING(10, 20, 20, 25, 6, 10, 11, 21, 1, 1, 11, 20, 0, 0, 20, 21, 0, 0, 2, 1) // #39 -PAIRING(10, 20, 20, 25, 6, 10, 11, 25, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 1) // #40 -PAIRING(10, 20, 20, 25, 6, 10, 11, 26, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 2) // #41 -PAIRING(10, 20, 20, 25, 6, 10, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #42 -PAIRING(10, 20, 20, 25, 6, 10, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #43 -PAIRING(10, 20, 20, 25, 6, 10, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #44 -PAIRING(10, 20, 20, 25, 6, 10, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #45 -PAIRING(10, 20, 20, 25, 6, 10, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #46 -PAIRING(10, 20, 20, 25, 6, 10, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #47 -PAIRING(10, 20, 20, 25, 6, 10, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #48 -PAIRING(10, 20, 20, 25, 6, 10, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #49 -PAIRING(10, 20, 20, 25, 6, 11, 11, 12, 2, 0, 10, 11, 11, 12, 0, 0, 0, 0, 2, 1) // #50 -PAIRING(10, 20, 20, 25, 6, 11, 11, 20, 2, 0, 10, 11, 11, 20, 0, 0, 0, 0, 1, 1) // #51 -PAIRING(10, 20, 20, 25, 6, 11, 11, 21, 2, 1, 10, 11, 11, 20, 20, 21, 0, 0, 1, 1) // #52 -PAIRING(10, 20, 20, 25, 6, 11, 11, 25, 2, 1, 10, 11, 11, 20, 20, 25, 0, 0, 0, 1) // #53 -PAIRING(10, 20, 20, 25, 6, 11, 11, 26, 2, 1, 10, 11, 11, 20, 20, 25, 0, 0, 0, 2) // #54 -PAIRING(10, 20, 20, 25, 6, 11, 12, 13, 2, 0, 10, 11, 12, 13, 0, 0, 0, 0, 2, 1) // #55 -PAIRING(10, 20, 20, 25, 6, 11, 12, 20, 2, 0, 10, 11, 12, 20, 0, 0, 0, 0, 2, 1) // #56 -PAIRING(10, 20, 20, 25, 6, 11, 12, 21, 2, 1, 10, 11, 12, 20, 20, 21, 0, 0, 2, 1) // #57 -PAIRING(10, 20, 20, 25, 6, 11, 12, 25, 2, 1, 10, 11, 12, 20, 20, 25, 0, 0, 1, 1) // #58 -PAIRING(10, 20, 20, 25, 6, 11, 12, 26, 2, 1, 10, 11, 12, 20, 20, 25, 0, 0, 1, 2) // #59 -PAIRING(10, 20, 20, 25, 6, 11, 20, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 1) // #60 -PAIRING(10, 20, 20, 25, 6, 11, 20, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #61 -PAIRING(10, 20, 20, 25, 6, 11, 20, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #62 -PAIRING(10, 20, 20, 25, 6, 11, 21, 22, 1, 1, 10, 11, 0, 0, 21, 22, 0, 0, 2, 1) // #63 -PAIRING(10, 20, 20, 25, 6, 11, 21, 25, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 1) // #64 -PAIRING(10, 20, 20, 25, 6, 11, 21, 26, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 2) // #65 -PAIRING(10, 20, 20, 25, 6, 11, 25, 26, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #66 -PAIRING(10, 20, 20, 25, 6, 11, 26, 27, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #67 -PAIRING(10, 20, 20, 25, 6, 20, 20, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 1) // #68 -PAIRING(10, 20, 20, 25, 6, 20, 20, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #69 -PAIRING(10, 20, 20, 25, 6, 20, 20, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #70 -PAIRING(10, 20, 20, 25, 6, 20, 21, 22, 1, 1, 10, 20, 0, 0, 21, 22, 0, 0, 1, 1) // #71 -PAIRING(10, 20, 20, 25, 6, 20, 21, 25, 1, 1, 10, 20, 0, 0, 21, 25, 0, 0, 1, 1) // #72 -PAIRING(10, 20, 20, 25, 6, 20, 21, 26, 1, 1, 10, 20, 0, 0, 21, 25, 0, 0, 1, 2) // #73 -PAIRING(10, 20, 20, 25, 6, 20, 25, 26, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 2) // #74 -PAIRING(10, 20, 20, 25, 6, 20, 26, 27, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 2) // #75 -PAIRING(10, 20, 20, 25, 6, 21, 21, 22, 1, 2, 10, 20, 0, 0, 20, 21, 21, 22, 1, 1) // #76 -PAIRING(10, 20, 20, 25, 6, 21, 21, 25, 1, 2, 10, 20, 0, 0, 20, 21, 21, 25, 0, 1) // #77 -PAIRING(10, 20, 20, 25, 6, 21, 21, 26, 1, 2, 10, 20, 0, 0, 20, 21, 21, 25, 0, 2) // #78 -PAIRING(10, 20, 20, 25, 6, 21, 22, 23, 1, 2, 10, 20, 0, 0, 20, 21, 22, 23, 1, 1) // #79 -PAIRING(10, 20, 20, 25, 6, 21, 22, 25, 1, 2, 10, 20, 0, 0, 20, 21, 22, 25, 1, 1) // #80 -PAIRING(10, 20, 20, 25, 6, 21, 22, 26, 1, 2, 10, 20, 0, 0, 20, 21, 22, 25, 1, 2) // #81 -PAIRING(10, 20, 20, 25, 6, 21, 25, 26, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 2) // #82 -PAIRING(10, 20, 20, 25, 6, 21, 26, 27, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 2) // #83 -PAIRING(10, 20, 20, 25, 6, 25, 25, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #84 -PAIRING(10, 20, 20, 25, 6, 25, 26, 27, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #85 -PAIRING(10, 20, 20, 25, 6, 26, 26, 27, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #86 -PAIRING(10, 20, 20, 25, 6, 26, 27, 28, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #87 -PAIRING(10, 20, 20, 25, 10, 11, 11, 12, 2, 0, 10, 11, 11, 12, 0, 0, 0, 0, 2, 0) // #88 -PAIRING(10, 20, 20, 25, 10, 11, 11, 20, 2, 0, 10, 11, 11, 20, 0, 0, 0, 0, 1, 0) // #89 -PAIRING(10, 20, 20, 25, 10, 11, 11, 21, 2, 1, 10, 11, 11, 20, 20, 21, 0, 0, 1, 0) // #90 -PAIRING(10, 20, 20, 25, 10, 11, 11, 25, 2, 1, 10, 11, 11, 20, 20, 25, 0, 0, 0, 0) // #91 -PAIRING(10, 20, 20, 25, 10, 11, 11, 26, 2, 1, 10, 11, 11, 20, 20, 25, 0, 0, 0, 1) // #92 -PAIRING(10, 20, 20, 25, 10, 11, 12, 13, 2, 0, 10, 11, 12, 13, 0, 0, 0, 0, 2, 0) // #93 -PAIRING(10, 20, 20, 25, 10, 11, 12, 20, 2, 0, 10, 11, 12, 20, 0, 0, 0, 0, 2, 0) // #94 -PAIRING(10, 20, 20, 25, 10, 11, 12, 21, 2, 1, 10, 11, 12, 20, 20, 21, 0, 0, 2, 0) // #95 -PAIRING(10, 20, 20, 25, 10, 11, 12, 25, 2, 1, 10, 11, 12, 20, 20, 25, 0, 0, 1, 0) // #96 -PAIRING(10, 20, 20, 25, 10, 11, 12, 26, 2, 1, 10, 11, 12, 20, 20, 25, 0, 0, 1, 1) // #97 -PAIRING(10, 20, 20, 25, 10, 11, 20, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 0) // #98 -PAIRING(10, 20, 20, 25, 10, 11, 20, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 0) // #99 -PAIRING(10, 20, 20, 25, 10, 11, 20, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #100 -PAIRING(10, 20, 20, 25, 10, 11, 21, 22, 1, 1, 10, 11, 0, 0, 21, 22, 0, 0, 2, 0) // #101 -PAIRING(10, 20, 20, 25, 10, 11, 21, 25, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 0) // #102 -PAIRING(10, 20, 20, 25, 10, 11, 21, 26, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 1) // #103 -PAIRING(10, 20, 20, 25, 10, 11, 25, 26, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #104 -PAIRING(10, 20, 20, 25, 10, 11, 26, 27, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #105 -PAIRING(10, 20, 20, 25, 10, 20, 20, 21, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 0) // #106 -PAIRING(10, 20, 20, 25, 10, 20, 20, 25, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 0) // #107 -PAIRING(10, 20, 20, 25, 10, 20, 20, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #108 -PAIRING(10, 20, 20, 25, 10, 20, 21, 22, 1, 1, 10, 20, 0, 0, 21, 22, 0, 0, 1, 0) // #109 -PAIRING(10, 20, 20, 25, 10, 20, 21, 25, 1, 1, 10, 20, 0, 0, 21, 25, 0, 0, 1, 0) // #110 -PAIRING(10, 20, 20, 25, 10, 20, 21, 26, 1, 1, 10, 20, 0, 0, 21, 25, 0, 0, 1, 1) // #111 -PAIRING(10, 20, 20, 25, 10, 20, 25, 26, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 1) // #112 -PAIRING(10, 20, 20, 25, 10, 20, 26, 27, 1, 0, 10, 20, 0, 0, 0, 0, 0, 0, 1, 1) // #113 -PAIRING(10, 20, 20, 25, 10, 21, 21, 22, 1, 2, 10, 20, 0, 0, 20, 21, 21, 22, 1, 0) // #114 -PAIRING(10, 20, 20, 25, 10, 21, 21, 25, 1, 2, 10, 20, 0, 0, 20, 21, 21, 25, 0, 0) // #115 -PAIRING(10, 20, 20, 25, 10, 21, 21, 26, 1, 2, 10, 20, 0, 0, 20, 21, 21, 25, 0, 1) // #116 -PAIRING(10, 20, 20, 25, 10, 21, 22, 23, 1, 2, 10, 20, 0, 0, 20, 21, 22, 23, 1, 0) // #117 -PAIRING(10, 20, 20, 25, 10, 21, 22, 25, 1, 2, 10, 20, 0, 0, 20, 21, 22, 25, 1, 0) // #118 -PAIRING(10, 20, 20, 25, 10, 21, 22, 26, 1, 2, 10, 20, 0, 0, 20, 21, 22, 25, 1, 1) // #119 -PAIRING(10, 20, 20, 25, 10, 21, 25, 26, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 1) // #120 -PAIRING(10, 20, 20, 25, 10, 21, 26, 27, 1, 1, 10, 20, 0, 0, 20, 21, 0, 0, 1, 1) // #121 -PAIRING(10, 20, 20, 25, 10, 25, 25, 26, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #122 -PAIRING(10, 20, 20, 25, 10, 25, 26, 27, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 1) // #123 -PAIRING(10, 20, 20, 25, 10, 26, 26, 27, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #124 -PAIRING(10, 20, 20, 25, 10, 26, 27, 28, 1, 1, 10, 20, 0, 0, 20, 25, 0, 0, 0, 2) // #125 -PAIRING(10, 20, 20, 25, 11, 12, 12, 13, 2, 0, 11, 12, 12, 13, 0, 0, 0, 0, 2, 0) // #126 -PAIRING(10, 20, 20, 25, 11, 12, 12, 20, 2, 0, 11, 12, 12, 20, 0, 0, 0, 0, 2, 0) // #127 -PAIRING(10, 20, 20, 25, 11, 12, 12, 21, 2, 1, 11, 12, 12, 20, 20, 21, 0, 0, 2, 0) // #128 -PAIRING(10, 20, 20, 25, 11, 12, 12, 25, 2, 1, 11, 12, 12, 20, 20, 25, 0, 0, 1, 0) // #129 -PAIRING(10, 20, 20, 25, 11, 12, 12, 26, 2, 1, 11, 12, 12, 20, 20, 25, 0, 0, 1, 1) // #130 -PAIRING(10, 20, 20, 25, 11, 12, 13, 14, 2, 0, 11, 12, 13, 14, 0, 0, 0, 0, 2, 0) // #131 -PAIRING(10, 20, 20, 25, 11, 12, 13, 20, 2, 0, 11, 12, 13, 20, 0, 0, 0, 0, 2, 0) // #132 -PAIRING(10, 20, 20, 25, 11, 12, 13, 21, 2, 1, 11, 12, 13, 20, 20, 21, 0, 0, 2, 0) // #133 -PAIRING(10, 20, 20, 25, 11, 12, 13, 25, 2, 1, 11, 12, 13, 20, 20, 25, 0, 0, 1, 0) // #134 -PAIRING(10, 20, 20, 25, 11, 12, 13, 26, 2, 1, 11, 12, 13, 20, 20, 25, 0, 0, 1, 1) // #135 -PAIRING(10, 20, 20, 25, 11, 12, 20, 21, 1, 1, 11, 12, 0, 0, 20, 21, 0, 0, 2, 0) // #136 -PAIRING(10, 20, 20, 25, 11, 12, 20, 25, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 0) // #137 -PAIRING(10, 20, 20, 25, 11, 12, 20, 26, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #138 -PAIRING(10, 20, 20, 25, 11, 12, 21, 22, 1, 1, 11, 12, 0, 0, 21, 22, 0, 0, 2, 0) // #139 -PAIRING(10, 20, 20, 25, 11, 12, 21, 25, 1, 1, 11, 12, 0, 0, 21, 25, 0, 0, 2, 0) // #140 -PAIRING(10, 20, 20, 25, 11, 12, 21, 26, 1, 1, 11, 12, 0, 0, 21, 25, 0, 0, 2, 1) // #141 -PAIRING(10, 20, 20, 25, 11, 12, 25, 26, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #142 -PAIRING(10, 20, 20, 25, 11, 12, 26, 27, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #143 -PAIRING(10, 20, 20, 25, 11, 20, 20, 21, 1, 1, 11, 20, 0, 0, 20, 21, 0, 0, 2, 0) // #144 -PAIRING(10, 20, 20, 25, 11, 20, 20, 25, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 0) // #145 -PAIRING(10, 20, 20, 25, 11, 20, 20, 26, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 1) // #146 -PAIRING(10, 20, 20, 25, 11, 20, 21, 22, 1, 1, 11, 20, 0, 0, 21, 22, 0, 0, 2, 0) // #147 -PAIRING(10, 20, 20, 25, 11, 20, 21, 25, 1, 1, 11, 20, 0, 0, 21, 25, 0, 0, 2, 0) // #148 -PAIRING(10, 20, 20, 25, 11, 20, 21, 26, 1, 1, 11, 20, 0, 0, 21, 25, 0, 0, 2, 1) // #149 -PAIRING(10, 20, 20, 25, 11, 20, 25, 26, 1, 0, 11, 20, 0, 0, 0, 0, 0, 0, 2, 1) // #150 -PAIRING(10, 20, 20, 25, 11, 20, 26, 27, 1, 0, 11, 20, 0, 0, 0, 0, 0, 0, 2, 1) // #151 -PAIRING(10, 20, 20, 25, 11, 21, 21, 22, 1, 2, 11, 20, 0, 0, 20, 21, 21, 22, 2, 0) // #152 -PAIRING(10, 20, 20, 25, 11, 21, 21, 25, 1, 2, 11, 20, 0, 0, 20, 21, 21, 25, 1, 0) // #153 -PAIRING(10, 20, 20, 25, 11, 21, 21, 26, 1, 2, 11, 20, 0, 0, 20, 21, 21, 25, 1, 1) // #154 -PAIRING(10, 20, 20, 25, 11, 21, 22, 23, 1, 2, 11, 20, 0, 0, 20, 21, 22, 23, 2, 0) // #155 -PAIRING(10, 20, 20, 25, 11, 21, 22, 25, 1, 2, 11, 20, 0, 0, 20, 21, 22, 25, 2, 0) // #156 -PAIRING(10, 20, 20, 25, 11, 21, 22, 26, 1, 2, 11, 20, 0, 0, 20, 21, 22, 25, 2, 1) // #157 -PAIRING(10, 20, 20, 25, 11, 21, 25, 26, 1, 1, 11, 20, 0, 0, 20, 21, 0, 0, 2, 1) // #158 -PAIRING(10, 20, 20, 25, 11, 21, 26, 27, 1, 1, 11, 20, 0, 0, 20, 21, 0, 0, 2, 1) // #159 -PAIRING(10, 20, 20, 25, 11, 25, 25, 26, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 1) // #160 -PAIRING(10, 20, 20, 25, 11, 25, 26, 27, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 1) // #161 -PAIRING(10, 20, 20, 25, 11, 26, 26, 27, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 2) // #162 -PAIRING(10, 20, 20, 25, 11, 26, 27, 28, 1, 1, 11, 20, 0, 0, 20, 25, 0, 0, 1, 2) // #163 -PAIRING(10, 20, 20, 25, 20, 21, 21, 22, 0, 2, 0, 0, 0, 0, 20, 21, 21, 22, 2, 0) // #164 -PAIRING(10, 20, 20, 25, 20, 21, 21, 25, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 0) // #165 -PAIRING(10, 20, 20, 25, 20, 21, 21, 26, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 1) // #166 -PAIRING(10, 20, 20, 25, 20, 21, 22, 23, 0, 2, 0, 0, 0, 0, 20, 21, 22, 23, 2, 0) // #167 -PAIRING(10, 20, 20, 25, 20, 21, 22, 25, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 0) // #168 -PAIRING(10, 20, 20, 25, 20, 21, 22, 26, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 1) // #169 -PAIRING(10, 20, 20, 25, 20, 21, 25, 26, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #170 -PAIRING(10, 20, 20, 25, 20, 21, 26, 27, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #171 -PAIRING(10, 20, 20, 25, 20, 25, 25, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #172 -PAIRING(10, 20, 20, 25, 20, 25, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #173 -PAIRING(10, 20, 20, 25, 20, 26, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #174 -PAIRING(10, 20, 20, 25, 20, 26, 27, 28, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #175 -PAIRING(10, 20, 20, 25, 21, 22, 22, 23, 0, 2, 0, 0, 0, 0, 21, 22, 22, 23, 2, 0) // #176 -PAIRING(10, 20, 20, 25, 21, 22, 22, 25, 0, 2, 0, 0, 0, 0, 21, 22, 22, 25, 2, 0) // #177 -PAIRING(10, 20, 20, 25, 21, 22, 22, 26, 0, 2, 0, 0, 0, 0, 21, 22, 22, 25, 2, 1) // #178 -PAIRING(10, 20, 20, 25, 21, 22, 23, 24, 0, 2, 0, 0, 0, 0, 21, 22, 23, 24, 2, 0) // #179 -PAIRING(10, 20, 20, 25, 21, 22, 23, 25, 0, 2, 0, 0, 0, 0, 21, 22, 23, 25, 2, 0) // #180 -PAIRING(10, 20, 20, 25, 21, 22, 23, 26, 0, 2, 0, 0, 0, 0, 21, 22, 23, 25, 2, 1) // #181 -PAIRING(10, 20, 20, 25, 21, 22, 25, 26, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #182 -PAIRING(10, 20, 20, 25, 21, 22, 26, 27, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #183 -PAIRING(10, 20, 20, 25, 21, 25, 25, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #184 -PAIRING(10, 20, 20, 25, 21, 25, 26, 27, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #185 -PAIRING(10, 20, 20, 25, 21, 26, 26, 27, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #186 -PAIRING(10, 20, 20, 25, 21, 26, 27, 28, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #187 -PAIRING(10, 20, 20, 25, 25, 26, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #188 -PAIRING(10, 20, 20, 25, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #189 -PAIRING(10, 20, 20, 25, 26, 27, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #190 -PAIRING(10, 20, 20, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #191 -PAIRING(10, 15, 20, 25, 6, 7, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #192 -PAIRING(10, 15, 20, 25, 6, 7, 7, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #193 -PAIRING(10, 15, 20, 25, 6, 7, 7, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #194 -PAIRING(10, 15, 20, 25, 6, 7, 7, 15, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #195 -PAIRING(10, 15, 20, 25, 6, 7, 7, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #196 -PAIRING(10, 15, 20, 25, 6, 7, 7, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #197 -PAIRING(10, 15, 20, 25, 6, 7, 7, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #198 -PAIRING(10, 15, 20, 25, 6, 7, 7, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #199 -PAIRING(10, 15, 20, 25, 6, 7, 7, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #200 -PAIRING(10, 15, 20, 25, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #201 -PAIRING(10, 15, 20, 25, 6, 7, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #202 -PAIRING(10, 15, 20, 25, 6, 7, 8, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #203 -PAIRING(10, 15, 20, 25, 6, 7, 8, 15, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #204 -PAIRING(10, 15, 20, 25, 6, 7, 8, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #205 -PAIRING(10, 15, 20, 25, 6, 7, 8, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #206 -PAIRING(10, 15, 20, 25, 6, 7, 8, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #207 -PAIRING(10, 15, 20, 25, 6, 7, 8, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #208 -PAIRING(10, 15, 20, 25, 6, 7, 8, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #209 -PAIRING(10, 15, 20, 25, 6, 7, 10, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #210 -PAIRING(10, 15, 20, 25, 6, 7, 10, 15, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #211 -PAIRING(10, 15, 20, 25, 6, 7, 10, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #212 -PAIRING(10, 15, 20, 25, 6, 7, 10, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #213 -PAIRING(10, 15, 20, 25, 6, 7, 10, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #214 -PAIRING(10, 15, 20, 25, 6, 7, 10, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #215 -PAIRING(10, 15, 20, 25, 6, 7, 10, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #216 -PAIRING(10, 15, 20, 25, 6, 7, 11, 12, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #217 -PAIRING(10, 15, 20, 25, 6, 7, 11, 15, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #218 -PAIRING(10, 15, 20, 25, 6, 7, 11, 16, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #219 -PAIRING(10, 15, 20, 25, 6, 7, 11, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #220 -PAIRING(10, 15, 20, 25, 6, 7, 11, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #221 -PAIRING(10, 15, 20, 25, 6, 7, 11, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #222 -PAIRING(10, 15, 20, 25, 6, 7, 11, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #223 -PAIRING(10, 15, 20, 25, 6, 7, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #224 -PAIRING(10, 15, 20, 25, 6, 7, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #225 -PAIRING(10, 15, 20, 25, 6, 7, 15, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #226 -PAIRING(10, 15, 20, 25, 6, 7, 15, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #227 -PAIRING(10, 15, 20, 25, 6, 7, 15, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #228 -PAIRING(10, 15, 20, 25, 6, 7, 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #229 -PAIRING(10, 15, 20, 25, 6, 7, 16, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #230 -PAIRING(10, 15, 20, 25, 6, 7, 16, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #231 -PAIRING(10, 15, 20, 25, 6, 7, 16, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #232 -PAIRING(10, 15, 20, 25, 6, 7, 16, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #233 -PAIRING(10, 15, 20, 25, 6, 7, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #234 -PAIRING(10, 15, 20, 25, 6, 7, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #235 -PAIRING(10, 15, 20, 25, 6, 7, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #236 -PAIRING(10, 15, 20, 25, 6, 7, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #237 -PAIRING(10, 15, 20, 25, 6, 7, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #238 -PAIRING(10, 15, 20, 25, 6, 7, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #239 -PAIRING(10, 15, 20, 25, 6, 7, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #240 -PAIRING(10, 15, 20, 25, 6, 7, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #241 -PAIRING(10, 15, 20, 25, 6, 10, 10, 11, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #242 -PAIRING(10, 15, 20, 25, 6, 10, 10, 15, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #243 -PAIRING(10, 15, 20, 25, 6, 10, 10, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #244 -PAIRING(10, 15, 20, 25, 6, 10, 10, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #245 -PAIRING(10, 15, 20, 25, 6, 10, 10, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #246 -PAIRING(10, 15, 20, 25, 6, 10, 10, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #247 -PAIRING(10, 15, 20, 25, 6, 10, 10, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #248 -PAIRING(10, 15, 20, 25, 6, 10, 11, 12, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #249 -PAIRING(10, 15, 20, 25, 6, 10, 11, 15, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #250 -PAIRING(10, 15, 20, 25, 6, 10, 11, 16, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #251 -PAIRING(10, 15, 20, 25, 6, 10, 11, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #252 -PAIRING(10, 15, 20, 25, 6, 10, 11, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #253 -PAIRING(10, 15, 20, 25, 6, 10, 11, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #254 -PAIRING(10, 15, 20, 25, 6, 10, 11, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #255 -PAIRING(10, 15, 20, 25, 6, 10, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #256 -PAIRING(10, 15, 20, 25, 6, 10, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #257 -PAIRING(10, 15, 20, 25, 6, 10, 15, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #258 -PAIRING(10, 15, 20, 25, 6, 10, 15, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #259 -PAIRING(10, 15, 20, 25, 6, 10, 15, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #260 -PAIRING(10, 15, 20, 25, 6, 10, 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #261 -PAIRING(10, 15, 20, 25, 6, 10, 16, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #262 -PAIRING(10, 15, 20, 25, 6, 10, 16, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #263 -PAIRING(10, 15, 20, 25, 6, 10, 16, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #264 -PAIRING(10, 15, 20, 25, 6, 10, 16, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #265 -PAIRING(10, 15, 20, 25, 6, 10, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #266 -PAIRING(10, 15, 20, 25, 6, 10, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #267 -PAIRING(10, 15, 20, 25, 6, 10, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #268 -PAIRING(10, 15, 20, 25, 6, 10, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #269 -PAIRING(10, 15, 20, 25, 6, 10, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #270 -PAIRING(10, 15, 20, 25, 6, 10, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #271 -PAIRING(10, 15, 20, 25, 6, 10, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #272 -PAIRING(10, 15, 20, 25, 6, 10, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #273 -PAIRING(10, 15, 20, 25, 6, 11, 11, 12, 2, 0, 10, 11, 11, 12, 0, 0, 0, 0, 2, 1) // #274 -PAIRING(10, 15, 20, 25, 6, 11, 11, 15, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 1) // #275 -PAIRING(10, 15, 20, 25, 6, 11, 11, 16, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 2) // #276 -PAIRING(10, 15, 20, 25, 6, 11, 11, 20, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 1) // #277 -PAIRING(10, 15, 20, 25, 6, 11, 11, 21, 2, 1, 10, 11, 11, 15, 20, 21, 0, 0, 1, 2) // #278 -PAIRING(10, 15, 20, 25, 6, 11, 11, 25, 2, 1, 10, 11, 11, 15, 20, 25, 0, 0, 0, 2) // #279 -PAIRING(10, 15, 20, 25, 6, 11, 11, 26, 2, 1, 10, 11, 11, 15, 20, 25, 0, 0, 0, 2) // #280 -PAIRING(10, 15, 20, 25, 6, 11, 12, 13, 2, 0, 10, 11, 12, 13, 0, 0, 0, 0, 2, 1) // #281 -PAIRING(10, 15, 20, 25, 6, 11, 12, 15, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 1) // #282 -PAIRING(10, 15, 20, 25, 6, 11, 12, 16, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 2) // #283 -PAIRING(10, 15, 20, 25, 6, 11, 12, 20, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 1) // #284 -PAIRING(10, 15, 20, 25, 6, 11, 12, 21, 2, 1, 10, 11, 12, 15, 20, 21, 0, 0, 2, 2) // #285 -PAIRING(10, 15, 20, 25, 6, 11, 12, 25, 2, 1, 10, 11, 12, 15, 20, 25, 0, 0, 1, 2) // #286 -PAIRING(10, 15, 20, 25, 6, 11, 12, 26, 2, 1, 10, 11, 12, 15, 20, 25, 0, 0, 1, 2) // #287 -PAIRING(10, 15, 20, 25, 6, 11, 15, 16, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #288 -PAIRING(10, 15, 20, 25, 6, 11, 15, 20, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #289 -PAIRING(10, 15, 20, 25, 6, 11, 15, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 2) // #290 -PAIRING(10, 15, 20, 25, 6, 11, 15, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #291 -PAIRING(10, 15, 20, 25, 6, 11, 15, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #292 -PAIRING(10, 15, 20, 25, 6, 11, 16, 17, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #293 -PAIRING(10, 15, 20, 25, 6, 11, 16, 20, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #294 -PAIRING(10, 15, 20, 25, 6, 11, 16, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 2) // #295 -PAIRING(10, 15, 20, 25, 6, 11, 16, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #296 -PAIRING(10, 15, 20, 25, 6, 11, 16, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #297 -PAIRING(10, 15, 20, 25, 6, 11, 20, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 1) // #298 -PAIRING(10, 15, 20, 25, 6, 11, 20, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #299 -PAIRING(10, 15, 20, 25, 6, 11, 20, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 2) // #300 -PAIRING(10, 15, 20, 25, 6, 11, 21, 22, 1, 1, 10, 11, 0, 0, 21, 22, 0, 0, 2, 1) // #301 -PAIRING(10, 15, 20, 25, 6, 11, 21, 25, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 1) // #302 -PAIRING(10, 15, 20, 25, 6, 11, 21, 26, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 2) // #303 -PAIRING(10, 15, 20, 25, 6, 11, 25, 26, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #304 -PAIRING(10, 15, 20, 25, 6, 11, 26, 27, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 2) // #305 -PAIRING(10, 15, 20, 25, 6, 15, 15, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #306 -PAIRING(10, 15, 20, 25, 6, 15, 15, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #307 -PAIRING(10, 15, 20, 25, 6, 15, 15, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #308 -PAIRING(10, 15, 20, 25, 6, 15, 15, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #309 -PAIRING(10, 15, 20, 25, 6, 15, 15, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #310 -PAIRING(10, 15, 20, 25, 6, 15, 16, 17, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #311 -PAIRING(10, 15, 20, 25, 6, 15, 16, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #312 -PAIRING(10, 15, 20, 25, 6, 15, 16, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #313 -PAIRING(10, 15, 20, 25, 6, 15, 16, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #314 -PAIRING(10, 15, 20, 25, 6, 15, 16, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #315 -PAIRING(10, 15, 20, 25, 6, 15, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #316 -PAIRING(10, 15, 20, 25, 6, 15, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #317 -PAIRING(10, 15, 20, 25, 6, 15, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #318 -PAIRING(10, 15, 20, 25, 6, 15, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 1) // #319 -PAIRING(10, 15, 20, 25, 6, 15, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #320 -PAIRING(10, 15, 20, 25, 6, 15, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 2) // #321 -PAIRING(10, 15, 20, 25, 6, 15, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #322 -PAIRING(10, 15, 20, 25, 6, 15, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #323 -PAIRING(10, 15, 20, 25, 6, 16, 16, 17, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #324 -PAIRING(10, 15, 20, 25, 6, 16, 16, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #325 -PAIRING(10, 15, 20, 25, 6, 16, 16, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #326 -PAIRING(10, 15, 20, 25, 6, 16, 16, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #327 -PAIRING(10, 15, 20, 25, 6, 16, 16, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #328 -PAIRING(10, 15, 20, 25, 6, 16, 17, 18, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #329 -PAIRING(10, 15, 20, 25, 6, 16, 17, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #330 -PAIRING(10, 15, 20, 25, 6, 16, 17, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #331 -PAIRING(10, 15, 20, 25, 6, 16, 17, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #332 -PAIRING(10, 15, 20, 25, 6, 16, 17, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #333 -PAIRING(10, 15, 20, 25, 6, 16, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #334 -PAIRING(10, 15, 20, 25, 6, 16, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #335 -PAIRING(10, 15, 20, 25, 6, 16, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #336 -PAIRING(10, 15, 20, 25, 6, 16, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 1) // #337 -PAIRING(10, 15, 20, 25, 6, 16, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #338 -PAIRING(10, 15, 20, 25, 6, 16, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 2) // #339 -PAIRING(10, 15, 20, 25, 6, 16, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #340 -PAIRING(10, 15, 20, 25, 6, 16, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #341 -PAIRING(10, 15, 20, 25, 6, 20, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #342 -PAIRING(10, 15, 20, 25, 6, 20, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #343 -PAIRING(10, 15, 20, 25, 6, 20, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #344 -PAIRING(10, 15, 20, 25, 6, 20, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 1) // #345 -PAIRING(10, 15, 20, 25, 6, 20, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #346 -PAIRING(10, 15, 20, 25, 6, 20, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 2) // #347 -PAIRING(10, 15, 20, 25, 6, 20, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #348 -PAIRING(10, 15, 20, 25, 6, 20, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #349 -PAIRING(10, 15, 20, 25, 6, 21, 21, 22, 1, 2, 10, 15, 0, 0, 20, 21, 21, 22, 1, 1) // #350 -PAIRING(10, 15, 20, 25, 6, 21, 21, 25, 1, 2, 10, 15, 0, 0, 20, 21, 21, 25, 0, 1) // #351 -PAIRING(10, 15, 20, 25, 6, 21, 21, 26, 1, 2, 10, 15, 0, 0, 20, 21, 21, 25, 0, 2) // #352 -PAIRING(10, 15, 20, 25, 6, 21, 22, 23, 1, 2, 10, 15, 0, 0, 20, 21, 22, 23, 1, 1) // #353 -PAIRING(10, 15, 20, 25, 6, 21, 22, 25, 1, 2, 10, 15, 0, 0, 20, 21, 22, 25, 1, 1) // #354 -PAIRING(10, 15, 20, 25, 6, 21, 22, 26, 1, 2, 10, 15, 0, 0, 20, 21, 22, 25, 1, 2) // #355 -PAIRING(10, 15, 20, 25, 6, 21, 25, 26, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #356 -PAIRING(10, 15, 20, 25, 6, 21, 26, 27, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #357 -PAIRING(10, 15, 20, 25, 6, 25, 25, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #358 -PAIRING(10, 15, 20, 25, 6, 25, 26, 27, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #359 -PAIRING(10, 15, 20, 25, 6, 26, 26, 27, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #360 -PAIRING(10, 15, 20, 25, 6, 26, 27, 28, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #361 -PAIRING(10, 15, 20, 25, 10, 11, 11, 12, 2, 0, 10, 11, 11, 12, 0, 0, 0, 0, 2, 0) // #362 -PAIRING(10, 15, 20, 25, 10, 11, 11, 15, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 0) // #363 -PAIRING(10, 15, 20, 25, 10, 11, 11, 16, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 1) // #364 -PAIRING(10, 15, 20, 25, 10, 11, 11, 20, 2, 0, 10, 11, 11, 15, 0, 0, 0, 0, 1, 0) // #365 -PAIRING(10, 15, 20, 25, 10, 11, 11, 21, 2, 1, 10, 11, 11, 15, 20, 21, 0, 0, 1, 1) // #366 -PAIRING(10, 15, 20, 25, 10, 11, 11, 25, 2, 1, 10, 11, 11, 15, 20, 25, 0, 0, 0, 1) // #367 -PAIRING(10, 15, 20, 25, 10, 11, 11, 26, 2, 1, 10, 11, 11, 15, 20, 25, 0, 0, 0, 1) // #368 -PAIRING(10, 15, 20, 25, 10, 11, 12, 13, 2, 0, 10, 11, 12, 13, 0, 0, 0, 0, 2, 0) // #369 -PAIRING(10, 15, 20, 25, 10, 11, 12, 15, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 0) // #370 -PAIRING(10, 15, 20, 25, 10, 11, 12, 16, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 1) // #371 -PAIRING(10, 15, 20, 25, 10, 11, 12, 20, 2, 0, 10, 11, 12, 15, 0, 0, 0, 0, 2, 0) // #372 -PAIRING(10, 15, 20, 25, 10, 11, 12, 21, 2, 1, 10, 11, 12, 15, 20, 21, 0, 0, 2, 1) // #373 -PAIRING(10, 15, 20, 25, 10, 11, 12, 25, 2, 1, 10, 11, 12, 15, 20, 25, 0, 0, 1, 1) // #374 -PAIRING(10, 15, 20, 25, 10, 11, 12, 26, 2, 1, 10, 11, 12, 15, 20, 25, 0, 0, 1, 1) // #375 -PAIRING(10, 15, 20, 25, 10, 11, 15, 16, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #376 -PAIRING(10, 15, 20, 25, 10, 11, 15, 20, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #377 -PAIRING(10, 15, 20, 25, 10, 11, 15, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 1) // #378 -PAIRING(10, 15, 20, 25, 10, 11, 15, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #379 -PAIRING(10, 15, 20, 25, 10, 11, 15, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #380 -PAIRING(10, 15, 20, 25, 10, 11, 16, 17, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #381 -PAIRING(10, 15, 20, 25, 10, 11, 16, 20, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #382 -PAIRING(10, 15, 20, 25, 10, 11, 16, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 1) // #383 -PAIRING(10, 15, 20, 25, 10, 11, 16, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #384 -PAIRING(10, 15, 20, 25, 10, 11, 16, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #385 -PAIRING(10, 15, 20, 25, 10, 11, 20, 21, 1, 1, 10, 11, 0, 0, 20, 21, 0, 0, 2, 0) // #386 -PAIRING(10, 15, 20, 25, 10, 11, 20, 25, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 0) // #387 -PAIRING(10, 15, 20, 25, 10, 11, 20, 26, 1, 1, 10, 11, 0, 0, 20, 25, 0, 0, 1, 1) // #388 -PAIRING(10, 15, 20, 25, 10, 11, 21, 22, 1, 1, 10, 11, 0, 0, 21, 22, 0, 0, 2, 0) // #389 -PAIRING(10, 15, 20, 25, 10, 11, 21, 25, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 0) // #390 -PAIRING(10, 15, 20, 25, 10, 11, 21, 26, 1, 1, 10, 11, 0, 0, 21, 25, 0, 0, 2, 1) // #391 -PAIRING(10, 15, 20, 25, 10, 11, 25, 26, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #392 -PAIRING(10, 15, 20, 25, 10, 11, 26, 27, 1, 0, 10, 11, 0, 0, 0, 0, 0, 0, 2, 1) // #393 -PAIRING(10, 15, 20, 25, 10, 15, 15, 16, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #394 -PAIRING(10, 15, 20, 25, 10, 15, 15, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #395 -PAIRING(10, 15, 20, 25, 10, 15, 15, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #396 -PAIRING(10, 15, 20, 25, 10, 15, 15, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #397 -PAIRING(10, 15, 20, 25, 10, 15, 15, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #398 -PAIRING(10, 15, 20, 25, 10, 15, 16, 17, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #399 -PAIRING(10, 15, 20, 25, 10, 15, 16, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #400 -PAIRING(10, 15, 20, 25, 10, 15, 16, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #401 -PAIRING(10, 15, 20, 25, 10, 15, 16, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #402 -PAIRING(10, 15, 20, 25, 10, 15, 16, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #403 -PAIRING(10, 15, 20, 25, 10, 15, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 0) // #404 -PAIRING(10, 15, 20, 25, 10, 15, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 0) // #405 -PAIRING(10, 15, 20, 25, 10, 15, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #406 -PAIRING(10, 15, 20, 25, 10, 15, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 0) // #407 -PAIRING(10, 15, 20, 25, 10, 15, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 0) // #408 -PAIRING(10, 15, 20, 25, 10, 15, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #409 -PAIRING(10, 15, 20, 25, 10, 15, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #410 -PAIRING(10, 15, 20, 25, 10, 15, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #411 -PAIRING(10, 15, 20, 25, 10, 16, 16, 17, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #412 -PAIRING(10, 15, 20, 25, 10, 16, 16, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #413 -PAIRING(10, 15, 20, 25, 10, 16, 16, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #414 -PAIRING(10, 15, 20, 25, 10, 16, 16, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #415 -PAIRING(10, 15, 20, 25, 10, 16, 16, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #416 -PAIRING(10, 15, 20, 25, 10, 16, 17, 18, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #417 -PAIRING(10, 15, 20, 25, 10, 16, 17, 20, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #418 -PAIRING(10, 15, 20, 25, 10, 16, 17, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #419 -PAIRING(10, 15, 20, 25, 10, 16, 17, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #420 -PAIRING(10, 15, 20, 25, 10, 16, 17, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #421 -PAIRING(10, 15, 20, 25, 10, 16, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 1) // #422 -PAIRING(10, 15, 20, 25, 10, 16, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #423 -PAIRING(10, 15, 20, 25, 10, 16, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #424 -PAIRING(10, 15, 20, 25, 10, 16, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 1) // #425 -PAIRING(10, 15, 20, 25, 10, 16, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #426 -PAIRING(10, 15, 20, 25, 10, 16, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 2) // #427 -PAIRING(10, 15, 20, 25, 10, 16, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #428 -PAIRING(10, 15, 20, 25, 10, 16, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 2) // #429 -PAIRING(10, 15, 20, 25, 10, 20, 20, 21, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 0) // #430 -PAIRING(10, 15, 20, 25, 10, 20, 20, 25, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 0) // #431 -PAIRING(10, 15, 20, 25, 10, 20, 20, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 1) // #432 -PAIRING(10, 15, 20, 25, 10, 20, 21, 22, 1, 1, 10, 15, 0, 0, 21, 22, 0, 0, 1, 0) // #433 -PAIRING(10, 15, 20, 25, 10, 20, 21, 25, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 0) // #434 -PAIRING(10, 15, 20, 25, 10, 20, 21, 26, 1, 1, 10, 15, 0, 0, 21, 25, 0, 0, 1, 1) // #435 -PAIRING(10, 15, 20, 25, 10, 20, 25, 26, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #436 -PAIRING(10, 15, 20, 25, 10, 20, 26, 27, 1, 0, 10, 15, 0, 0, 0, 0, 0, 0, 1, 1) // #437 -PAIRING(10, 15, 20, 25, 10, 21, 21, 22, 1, 2, 10, 15, 0, 0, 20, 21, 21, 22, 1, 1) // #438 -PAIRING(10, 15, 20, 25, 10, 21, 21, 25, 1, 2, 10, 15, 0, 0, 20, 21, 21, 25, 0, 1) // #439 -PAIRING(10, 15, 20, 25, 10, 21, 21, 26, 1, 2, 10, 15, 0, 0, 20, 21, 21, 25, 0, 2) // #440 -PAIRING(10, 15, 20, 25, 10, 21, 22, 23, 1, 2, 10, 15, 0, 0, 20, 21, 22, 23, 1, 1) // #441 -PAIRING(10, 15, 20, 25, 10, 21, 22, 25, 1, 2, 10, 15, 0, 0, 20, 21, 22, 25, 1, 1) // #442 -PAIRING(10, 15, 20, 25, 10, 21, 22, 26, 1, 2, 10, 15, 0, 0, 20, 21, 22, 25, 1, 2) // #443 -PAIRING(10, 15, 20, 25, 10, 21, 25, 26, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #444 -PAIRING(10, 15, 20, 25, 10, 21, 26, 27, 1, 1, 10, 15, 0, 0, 20, 21, 0, 0, 1, 2) // #445 -PAIRING(10, 15, 20, 25, 10, 25, 25, 26, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #446 -PAIRING(10, 15, 20, 25, 10, 25, 26, 27, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #447 -PAIRING(10, 15, 20, 25, 10, 26, 26, 27, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #448 -PAIRING(10, 15, 20, 25, 10, 26, 27, 28, 1, 1, 10, 15, 0, 0, 20, 25, 0, 0, 0, 2) // #449 -PAIRING(10, 15, 20, 25, 11, 12, 12, 13, 2, 0, 11, 12, 12, 13, 0, 0, 0, 0, 2, 0) // #450 -PAIRING(10, 15, 20, 25, 11, 12, 12, 15, 2, 0, 11, 12, 12, 15, 0, 0, 0, 0, 2, 0) // #451 -PAIRING(10, 15, 20, 25, 11, 12, 12, 16, 2, 0, 11, 12, 12, 15, 0, 0, 0, 0, 2, 1) // #452 -PAIRING(10, 15, 20, 25, 11, 12, 12, 20, 2, 0, 11, 12, 12, 15, 0, 0, 0, 0, 2, 0) // #453 -PAIRING(10, 15, 20, 25, 11, 12, 12, 21, 2, 1, 11, 12, 12, 15, 20, 21, 0, 0, 2, 1) // #454 -PAIRING(10, 15, 20, 25, 11, 12, 12, 25, 2, 1, 11, 12, 12, 15, 20, 25, 0, 0, 1, 1) // #455 -PAIRING(10, 15, 20, 25, 11, 12, 12, 26, 2, 1, 11, 12, 12, 15, 20, 25, 0, 0, 1, 1) // #456 -PAIRING(10, 15, 20, 25, 11, 12, 13, 14, 2, 0, 11, 12, 13, 14, 0, 0, 0, 0, 2, 0) // #457 -PAIRING(10, 15, 20, 25, 11, 12, 13, 15, 2, 0, 11, 12, 13, 15, 0, 0, 0, 0, 2, 0) // #458 -PAIRING(10, 15, 20, 25, 11, 12, 13, 16, 2, 0, 11, 12, 13, 15, 0, 0, 0, 0, 2, 1) // #459 -PAIRING(10, 15, 20, 25, 11, 12, 13, 20, 2, 0, 11, 12, 13, 15, 0, 0, 0, 0, 2, 0) // #460 -PAIRING(10, 15, 20, 25, 11, 12, 13, 21, 2, 1, 11, 12, 13, 15, 20, 21, 0, 0, 2, 1) // #461 -PAIRING(10, 15, 20, 25, 11, 12, 13, 25, 2, 1, 11, 12, 13, 15, 20, 25, 0, 0, 1, 1) // #462 -PAIRING(10, 15, 20, 25, 11, 12, 13, 26, 2, 1, 11, 12, 13, 15, 20, 25, 0, 0, 1, 1) // #463 -PAIRING(10, 15, 20, 25, 11, 12, 15, 16, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #464 -PAIRING(10, 15, 20, 25, 11, 12, 15, 20, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #465 -PAIRING(10, 15, 20, 25, 11, 12, 15, 21, 1, 1, 11, 12, 0, 0, 20, 21, 0, 0, 2, 1) // #466 -PAIRING(10, 15, 20, 25, 11, 12, 15, 25, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #467 -PAIRING(10, 15, 20, 25, 11, 12, 15, 26, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #468 -PAIRING(10, 15, 20, 25, 11, 12, 16, 17, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #469 -PAIRING(10, 15, 20, 25, 11, 12, 16, 20, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #470 -PAIRING(10, 15, 20, 25, 11, 12, 16, 21, 1, 1, 11, 12, 0, 0, 20, 21, 0, 0, 2, 1) // #471 -PAIRING(10, 15, 20, 25, 11, 12, 16, 25, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #472 -PAIRING(10, 15, 20, 25, 11, 12, 16, 26, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #473 -PAIRING(10, 15, 20, 25, 11, 12, 20, 21, 1, 1, 11, 12, 0, 0, 20, 21, 0, 0, 2, 0) // #474 -PAIRING(10, 15, 20, 25, 11, 12, 20, 25, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 0) // #475 -PAIRING(10, 15, 20, 25, 11, 12, 20, 26, 1, 1, 11, 12, 0, 0, 20, 25, 0, 0, 1, 1) // #476 -PAIRING(10, 15, 20, 25, 11, 12, 21, 22, 1, 1, 11, 12, 0, 0, 21, 22, 0, 0, 2, 0) // #477 -PAIRING(10, 15, 20, 25, 11, 12, 21, 25, 1, 1, 11, 12, 0, 0, 21, 25, 0, 0, 2, 0) // #478 -PAIRING(10, 15, 20, 25, 11, 12, 21, 26, 1, 1, 11, 12, 0, 0, 21, 25, 0, 0, 2, 1) // #479 -PAIRING(10, 15, 20, 25, 11, 12, 25, 26, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #480 -PAIRING(10, 15, 20, 25, 11, 12, 26, 27, 1, 0, 11, 12, 0, 0, 0, 0, 0, 0, 2, 1) // #481 -PAIRING(10, 15, 20, 25, 11, 15, 15, 16, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #482 -PAIRING(10, 15, 20, 25, 11, 15, 15, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #483 -PAIRING(10, 15, 20, 25, 11, 15, 15, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 1) // #484 -PAIRING(10, 15, 20, 25, 11, 15, 15, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #485 -PAIRING(10, 15, 20, 25, 11, 15, 15, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #486 -PAIRING(10, 15, 20, 25, 11, 15, 16, 17, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #487 -PAIRING(10, 15, 20, 25, 11, 15, 16, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #488 -PAIRING(10, 15, 20, 25, 11, 15, 16, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 1) // #489 -PAIRING(10, 15, 20, 25, 11, 15, 16, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #490 -PAIRING(10, 15, 20, 25, 11, 15, 16, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #491 -PAIRING(10, 15, 20, 25, 11, 15, 20, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 0) // #492 -PAIRING(10, 15, 20, 25, 11, 15, 20, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 0) // #493 -PAIRING(10, 15, 20, 25, 11, 15, 20, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #494 -PAIRING(10, 15, 20, 25, 11, 15, 21, 22, 1, 1, 11, 15, 0, 0, 21, 22, 0, 0, 2, 0) // #495 -PAIRING(10, 15, 20, 25, 11, 15, 21, 25, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 0) // #496 -PAIRING(10, 15, 20, 25, 11, 15, 21, 26, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 1) // #497 -PAIRING(10, 15, 20, 25, 11, 15, 25, 26, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #498 -PAIRING(10, 15, 20, 25, 11, 15, 26, 27, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #499 -PAIRING(10, 15, 20, 25, 11, 16, 16, 17, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #500 -PAIRING(10, 15, 20, 25, 11, 16, 16, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #501 -PAIRING(10, 15, 20, 25, 11, 16, 16, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #502 -PAIRING(10, 15, 20, 25, 11, 16, 16, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #503 -PAIRING(10, 15, 20, 25, 11, 16, 16, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #504 -PAIRING(10, 15, 20, 25, 11, 16, 17, 18, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #505 -PAIRING(10, 15, 20, 25, 11, 16, 17, 20, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #506 -PAIRING(10, 15, 20, 25, 11, 16, 17, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #507 -PAIRING(10, 15, 20, 25, 11, 16, 17, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #508 -PAIRING(10, 15, 20, 25, 11, 16, 17, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #509 -PAIRING(10, 15, 20, 25, 11, 16, 20, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 1) // #510 -PAIRING(10, 15, 20, 25, 11, 16, 20, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #511 -PAIRING(10, 15, 20, 25, 11, 16, 20, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #512 -PAIRING(10, 15, 20, 25, 11, 16, 21, 22, 1, 1, 11, 15, 0, 0, 21, 22, 0, 0, 2, 1) // #513 -PAIRING(10, 15, 20, 25, 11, 16, 21, 25, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 1) // #514 -PAIRING(10, 15, 20, 25, 11, 16, 21, 26, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 2) // #515 -PAIRING(10, 15, 20, 25, 11, 16, 25, 26, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #516 -PAIRING(10, 15, 20, 25, 11, 16, 26, 27, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 2) // #517 -PAIRING(10, 15, 20, 25, 11, 20, 20, 21, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 0) // #518 -PAIRING(10, 15, 20, 25, 11, 20, 20, 25, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 0) // #519 -PAIRING(10, 15, 20, 25, 11, 20, 20, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 1) // #520 -PAIRING(10, 15, 20, 25, 11, 20, 21, 22, 1, 1, 11, 15, 0, 0, 21, 22, 0, 0, 2, 0) // #521 -PAIRING(10, 15, 20, 25, 11, 20, 21, 25, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 0) // #522 -PAIRING(10, 15, 20, 25, 11, 20, 21, 26, 1, 1, 11, 15, 0, 0, 21, 25, 0, 0, 2, 1) // #523 -PAIRING(10, 15, 20, 25, 11, 20, 25, 26, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #524 -PAIRING(10, 15, 20, 25, 11, 20, 26, 27, 1, 0, 11, 15, 0, 0, 0, 0, 0, 0, 2, 1) // #525 -PAIRING(10, 15, 20, 25, 11, 21, 21, 22, 1, 2, 11, 15, 0, 0, 20, 21, 21, 22, 2, 1) // #526 -PAIRING(10, 15, 20, 25, 11, 21, 21, 25, 1, 2, 11, 15, 0, 0, 20, 21, 21, 25, 1, 1) // #527 -PAIRING(10, 15, 20, 25, 11, 21, 21, 26, 1, 2, 11, 15, 0, 0, 20, 21, 21, 25, 1, 2) // #528 -PAIRING(10, 15, 20, 25, 11, 21, 22, 23, 1, 2, 11, 15, 0, 0, 20, 21, 22, 23, 2, 1) // #529 -PAIRING(10, 15, 20, 25, 11, 21, 22, 25, 1, 2, 11, 15, 0, 0, 20, 21, 22, 25, 2, 1) // #530 -PAIRING(10, 15, 20, 25, 11, 21, 22, 26, 1, 2, 11, 15, 0, 0, 20, 21, 22, 25, 2, 2) // #531 -PAIRING(10, 15, 20, 25, 11, 21, 25, 26, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #532 -PAIRING(10, 15, 20, 25, 11, 21, 26, 27, 1, 1, 11, 15, 0, 0, 20, 21, 0, 0, 2, 2) // #533 -PAIRING(10, 15, 20, 25, 11, 25, 25, 26, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #534 -PAIRING(10, 15, 20, 25, 11, 25, 26, 27, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #535 -PAIRING(10, 15, 20, 25, 11, 26, 26, 27, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #536 -PAIRING(10, 15, 20, 25, 11, 26, 27, 28, 1, 1, 11, 15, 0, 0, 20, 25, 0, 0, 1, 2) // #537 -PAIRING(10, 15, 20, 25, 15, 16, 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #538 -PAIRING(10, 15, 20, 25, 15, 16, 16, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #539 -PAIRING(10, 15, 20, 25, 15, 16, 16, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #540 -PAIRING(10, 15, 20, 25, 15, 16, 16, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #541 -PAIRING(10, 15, 20, 25, 15, 16, 16, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #542 -PAIRING(10, 15, 20, 25, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #543 -PAIRING(10, 15, 20, 25, 15, 16, 17, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #544 -PAIRING(10, 15, 20, 25, 15, 16, 17, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #545 -PAIRING(10, 15, 20, 25, 15, 16, 17, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #546 -PAIRING(10, 15, 20, 25, 15, 16, 17, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #547 -PAIRING(10, 15, 20, 25, 15, 16, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #548 -PAIRING(10, 15, 20, 25, 15, 16, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #549 -PAIRING(10, 15, 20, 25, 15, 16, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #550 -PAIRING(10, 15, 20, 25, 15, 16, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #551 -PAIRING(10, 15, 20, 25, 15, 16, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #552 -PAIRING(10, 15, 20, 25, 15, 16, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #553 -PAIRING(10, 15, 20, 25, 15, 16, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #554 -PAIRING(10, 15, 20, 25, 15, 16, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #555 -PAIRING(10, 15, 20, 25, 15, 20, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #556 -PAIRING(10, 15, 20, 25, 15, 20, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #557 -PAIRING(10, 15, 20, 25, 15, 20, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #558 -PAIRING(10, 15, 20, 25, 15, 20, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #559 -PAIRING(10, 15, 20, 25, 15, 20, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #560 -PAIRING(10, 15, 20, 25, 15, 20, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #561 -PAIRING(10, 15, 20, 25, 15, 20, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #562 -PAIRING(10, 15, 20, 25, 15, 20, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #563 -PAIRING(10, 15, 20, 25, 15, 21, 21, 22, 0, 2, 0, 0, 0, 0, 20, 21, 21, 22, 2, 1) // #564 -PAIRING(10, 15, 20, 25, 15, 21, 21, 25, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 1) // #565 -PAIRING(10, 15, 20, 25, 15, 21, 21, 26, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 2) // #566 -PAIRING(10, 15, 20, 25, 15, 21, 22, 23, 0, 2, 0, 0, 0, 0, 20, 21, 22, 23, 2, 1) // #567 -PAIRING(10, 15, 20, 25, 15, 21, 22, 25, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 1) // #568 -PAIRING(10, 15, 20, 25, 15, 21, 22, 26, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 2) // #569 -PAIRING(10, 15, 20, 25, 15, 21, 25, 26, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #570 -PAIRING(10, 15, 20, 25, 15, 21, 26, 27, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #571 -PAIRING(10, 15, 20, 25, 15, 25, 25, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #572 -PAIRING(10, 15, 20, 25, 15, 25, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #573 -PAIRING(10, 15, 20, 25, 15, 26, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #574 -PAIRING(10, 15, 20, 25, 15, 26, 27, 28, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #575 -PAIRING(10, 15, 20, 25, 16, 17, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #576 -PAIRING(10, 15, 20, 25, 16, 17, 17, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #577 -PAIRING(10, 15, 20, 25, 16, 17, 17, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #578 -PAIRING(10, 15, 20, 25, 16, 17, 17, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #579 -PAIRING(10, 15, 20, 25, 16, 17, 17, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #580 -PAIRING(10, 15, 20, 25, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #581 -PAIRING(10, 15, 20, 25, 16, 17, 18, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #582 -PAIRING(10, 15, 20, 25, 16, 17, 18, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #583 -PAIRING(10, 15, 20, 25, 16, 17, 18, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #584 -PAIRING(10, 15, 20, 25, 16, 17, 18, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #585 -PAIRING(10, 15, 20, 25, 16, 17, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #586 -PAIRING(10, 15, 20, 25, 16, 17, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #587 -PAIRING(10, 15, 20, 25, 16, 17, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #588 -PAIRING(10, 15, 20, 25, 16, 17, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #589 -PAIRING(10, 15, 20, 25, 16, 17, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #590 -PAIRING(10, 15, 20, 25, 16, 17, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #591 -PAIRING(10, 15, 20, 25, 16, 17, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #592 -PAIRING(10, 15, 20, 25, 16, 17, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #593 -PAIRING(10, 15, 20, 25, 16, 20, 20, 21, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #594 -PAIRING(10, 15, 20, 25, 16, 20, 20, 25, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #595 -PAIRING(10, 15, 20, 25, 16, 20, 20, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #596 -PAIRING(10, 15, 20, 25, 16, 20, 21, 22, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #597 -PAIRING(10, 15, 20, 25, 16, 20, 21, 25, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #598 -PAIRING(10, 15, 20, 25, 16, 20, 21, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #599 -PAIRING(10, 15, 20, 25, 16, 20, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #600 -PAIRING(10, 15, 20, 25, 16, 20, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #601 -PAIRING(10, 15, 20, 25, 16, 21, 21, 22, 0, 2, 0, 0, 0, 0, 20, 21, 21, 22, 2, 1) // #602 -PAIRING(10, 15, 20, 25, 16, 21, 21, 25, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 1) // #603 -PAIRING(10, 15, 20, 25, 16, 21, 21, 26, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 2) // #604 -PAIRING(10, 15, 20, 25, 16, 21, 22, 23, 0, 2, 0, 0, 0, 0, 20, 21, 22, 23, 2, 1) // #605 -PAIRING(10, 15, 20, 25, 16, 21, 22, 25, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 1) // #606 -PAIRING(10, 15, 20, 25, 16, 21, 22, 26, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 2) // #607 -PAIRING(10, 15, 20, 25, 16, 21, 25, 26, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #608 -PAIRING(10, 15, 20, 25, 16, 21, 26, 27, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 2) // #609 -PAIRING(10, 15, 20, 25, 16, 25, 25, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #610 -PAIRING(10, 15, 20, 25, 16, 25, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #611 -PAIRING(10, 15, 20, 25, 16, 26, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #612 -PAIRING(10, 15, 20, 25, 16, 26, 27, 28, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #613 -PAIRING(10, 15, 20, 25, 20, 21, 21, 22, 0, 2, 0, 0, 0, 0, 20, 21, 21, 22, 2, 0) // #614 -PAIRING(10, 15, 20, 25, 20, 21, 21, 25, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 0) // #615 -PAIRING(10, 15, 20, 25, 20, 21, 21, 26, 0, 2, 0, 0, 0, 0, 20, 21, 21, 25, 1, 1) // #616 -PAIRING(10, 15, 20, 25, 20, 21, 22, 23, 0, 2, 0, 0, 0, 0, 20, 21, 22, 23, 2, 0) // #617 -PAIRING(10, 15, 20, 25, 20, 21, 22, 25, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 0) // #618 -PAIRING(10, 15, 20, 25, 20, 21, 22, 26, 0, 2, 0, 0, 0, 0, 20, 21, 22, 25, 2, 1) // #619 -PAIRING(10, 15, 20, 25, 20, 21, 25, 26, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #620 -PAIRING(10, 15, 20, 25, 20, 21, 26, 27, 0, 1, 0, 0, 0, 0, 20, 21, 0, 0, 2, 1) // #621 -PAIRING(10, 15, 20, 25, 20, 25, 25, 26, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #622 -PAIRING(10, 15, 20, 25, 20, 25, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 1) // #623 -PAIRING(10, 15, 20, 25, 20, 26, 26, 27, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #624 -PAIRING(10, 15, 20, 25, 20, 26, 27, 28, 0, 1, 0, 0, 0, 0, 20, 25, 0, 0, 1, 2) // #625 -PAIRING(10, 15, 20, 25, 21, 22, 22, 23, 0, 2, 0, 0, 0, 0, 21, 22, 22, 23, 2, 0) // #626 -PAIRING(10, 15, 20, 25, 21, 22, 22, 25, 0, 2, 0, 0, 0, 0, 21, 22, 22, 25, 2, 0) // #627 -PAIRING(10, 15, 20, 25, 21, 22, 22, 26, 0, 2, 0, 0, 0, 0, 21, 22, 22, 25, 2, 1) // #628 -PAIRING(10, 15, 20, 25, 21, 22, 23, 24, 0, 2, 0, 0, 0, 0, 21, 22, 23, 24, 2, 0) // #629 -PAIRING(10, 15, 20, 25, 21, 22, 23, 25, 0, 2, 0, 0, 0, 0, 21, 22, 23, 25, 2, 0) // #630 -PAIRING(10, 15, 20, 25, 21, 22, 23, 26, 0, 2, 0, 0, 0, 0, 21, 22, 23, 25, 2, 1) // #631 -PAIRING(10, 15, 20, 25, 21, 22, 25, 26, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #632 -PAIRING(10, 15, 20, 25, 21, 22, 26, 27, 0, 1, 0, 0, 0, 0, 21, 22, 0, 0, 2, 1) // #633 -PAIRING(10, 15, 20, 25, 21, 25, 25, 26, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #634 -PAIRING(10, 15, 20, 25, 21, 25, 26, 27, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 1) // #635 -PAIRING(10, 15, 20, 25, 21, 26, 26, 27, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #636 -PAIRING(10, 15, 20, 25, 21, 26, 27, 28, 0, 1, 0, 0, 0, 0, 21, 25, 0, 0, 2, 2) // #637 -PAIRING(10, 15, 20, 25, 25, 26, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #638 -PAIRING(10, 15, 20, 25, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #639 -PAIRING(10, 15, 20, 25, 26, 27, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #640 -PAIRING(10, 15, 20, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2) // #641 diff --git a/toolkit/crashreporter/google-breakpad/src/common/tests/auto_tempdir.h b/toolkit/crashreporter/google-breakpad/src/common/tests/auto_tempdir.h deleted file mode 100644 index 1df88db8b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/tests/auto_tempdir.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utility class for creating a temporary directory for unit tests -// that is deleted in the destructor. -#ifndef GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR -#define GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR - -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" - -#if !defined(__ANDROID__) -#define TEMPDIR "/tmp" -#else -#define TEMPDIR "/data/local/tmp" -#include "common/android/testing/mkdtemp.h" -#endif - -namespace google_breakpad { - -class AutoTempDir { - public: - AutoTempDir() { - char temp_dir[] = TEMPDIR "/breakpad.XXXXXX"; - EXPECT_TRUE(mkdtemp(temp_dir) != NULL); - path_.assign(temp_dir); - } - - ~AutoTempDir() { - DeleteRecursively(path_); - } - - const string& path() const { - return path_; - } - - private: - void DeleteRecursively(const string& path) { - // First remove any files in the dir - DIR* dir = opendir(path.c_str()); - if (!dir) - return; - - dirent* entry; - while ((entry = readdir(dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - string entry_path = path + "/" + entry->d_name; - struct stat stats; - EXPECT_TRUE(lstat(entry_path.c_str(), &stats) == 0); - if (S_ISDIR(stats.st_mode)) - DeleteRecursively(entry_path); - else - EXPECT_TRUE(unlink(entry_path.c_str()) == 0); - } - EXPECT_TRUE(closedir(dir) == 0); - EXPECT_TRUE(rmdir(path.c_str()) == 0); - } - - // prevent copy construction and assignment - AutoTempDir(const AutoTempDir&); - AutoTempDir& operator=(const AutoTempDir&); - - string path_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_COMMON_TESTS_AUTO_TEMPDIR diff --git a/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.cc b/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.cc deleted file mode 100644 index 1c041777c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.cc +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_utils.cc: Implement utility functions for file manipulation. -// See file_utils.h for details. - -#include -#include -#include -#include -#include - -#include "common/linux/eintr_wrapper.h" -#include "common/tests/file_utils.h" - -namespace google_breakpad { - -bool CopyFile(const char* from_path, const char* to_path) { - int infile = HANDLE_EINTR(open(from_path, O_RDONLY)); - if (infile < 0) { - perror("open"); - return false; - } - - int outfile = HANDLE_EINTR(creat(to_path, 0666)); - if (outfile < 0) { - perror("creat"); - if (IGNORE_EINTR(close(infile)) < 0) { - perror("close"); - } - return false; - } - - char buffer[1024]; - bool result = true; - - while (result) { - ssize_t bytes_read = HANDLE_EINTR(read(infile, buffer, sizeof(buffer))); - if (bytes_read < 0) { - perror("read"); - result = false; - break; - } - if (bytes_read == 0) - break; - ssize_t bytes_written_per_read = 0; - do { - ssize_t bytes_written_partial = HANDLE_EINTR(write( - outfile, - &buffer[bytes_written_per_read], - bytes_read - bytes_written_per_read)); - if (bytes_written_partial < 0) { - perror("write"); - result = false; - break; - } - bytes_written_per_read += bytes_written_partial; - } while (bytes_written_per_read < bytes_read); - } - - if (IGNORE_EINTR(close(infile)) == -1) { - perror("close"); - result = false; - } - if (IGNORE_EINTR(close(outfile)) == -1) { - perror("close"); - result = false; - } - - return result; -} - -bool ReadFile(const char* path, void* buffer, ssize_t* buffer_size) { - int fd = HANDLE_EINTR(open(path, O_RDONLY)); - if (fd == -1) { - perror("open"); - return false; - } - - bool ok = true; - if (buffer && buffer_size && *buffer_size > 0) { - memset(buffer, 0, sizeof(*buffer_size)); - *buffer_size = HANDLE_EINTR(read(fd, buffer, *buffer_size)); - if (*buffer_size == -1) { - perror("read"); - ok = false; - } - } - if (IGNORE_EINTR(close(fd)) == -1) { - perror("close"); - ok = false; - } - return ok; -} - -bool WriteFile(const char* path, const void* buffer, size_t buffer_size) { - int fd = HANDLE_EINTR(open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU)); - if (fd == -1) { - perror("open"); - return false; - } - - bool ok = true; - if (buffer) { - size_t bytes_written_total = 0; - ssize_t bytes_written_partial = 0; - const char* data = reinterpret_cast(buffer); - while (bytes_written_total < buffer_size) { - bytes_written_partial = - HANDLE_EINTR(write(fd, data + bytes_written_total, - buffer_size - bytes_written_total)); - if (bytes_written_partial < 0) { - perror("write"); - ok = false; - break; - } - bytes_written_total += bytes_written_partial; - } - } - if (IGNORE_EINTR(close(fd)) == -1) { - perror("close"); - ok = false; - } - return ok; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.h b/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.h deleted file mode 100644 index c98a9bfa8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/tests/file_utils.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// file_utils.h: Define utility functions for file manipulation, which -// are used for testing. - -#ifndef COMMON_TESTS_FILE_UTILS_H_ -#define COMMON_TESTS_FILE_UTILS_H_ - -namespace google_breakpad { - -// Copies a file from |from_path| to |to_path|. Returns true on success. -bool CopyFile(const char* from_path, const char* to_path); - -// Reads the content of a file at |path| into |buffer|. |buffer_size| specifies -// the size of |buffer| in bytes and returns the number of bytes read from the -// file on success. Returns true on success. -bool ReadFile(const char* path, void* buffer, ssize_t* buffer_size); - -// Writes |buffer_size| bytes of the content in |buffer| to a file at |path|. -// Returns true on success. -bool WriteFile(const char* path, const void* buffer, size_t buffer_size); - -} // namespace google_breakpad - -#endif // COMMON_TESTS_FILE_UTILS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/unordered.h b/toolkit/crashreporter/google-breakpad/src/common/unordered.h deleted file mode 100644 index ec665cc02..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/unordered.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Include this file to use unordered_map and unordered_set. If tr1 -// or C++11 is not available, you can switch to using hash_set and -// hash_map by defining BP_USE_HASH_SET. - -#ifndef COMMON_UNORDERED_H_ -#define COMMON_UNORDERED_H_ - -#if defined(BP_USE_HASH_SET) -#include -#include - -// For hash. -#include "util/hash/hash.h" - -template > -struct unordered_map : public hash_map {}; -template > -struct unordered_set : public hash_set {}; - -#elif defined(_LIBCPP_VERSION) // c++11 -#include -#include -using std::unordered_map; -using std::unordered_set; - -#else // Fallback to tr1::unordered -#include -#include -using std::tr1::unordered_map; -using std::tr1::unordered_set; -#endif - -#endif // COMMON_UNORDERED_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/using_std_string.h b/toolkit/crashreporter/google-breakpad/src/common/using_std_string.h deleted file mode 100644 index 13c1da59c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/using_std_string.h +++ /dev/null @@ -1,65 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Ivan Penkov - -// using_std_string.h: Allows building this code in environments where -// global string (::string) exists. -// -// The problem: -// ------------- -// Let's say you want to build this code in an environment where a global -// string type is defined (i.e. ::string). Now, let's suppose that ::string -// is different that std::string and you'd like to have the option to easily -// choose between the two string types. Ideally you'd like to control which -// string type is chosen by simply #defining an identifier. -// -// The solution: -// ------------- -// #define HAS_GLOBAL_STRING somewhere in a global header file and then -// globally replace std::string with string. Then include this header -// file everywhere where string is used. If you want to revert back to -// using std::string, simply remove the #define (HAS_GLOBAL_STRING). - -#ifndef THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_ -#define THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_ - -#ifdef HAS_GLOBAL_STRING - typedef ::string google_breakpad_string; -#else - using std::string; - typedef std::string google_breakpad_string; -#endif - -// Inicates that type google_breakpad_string is defined -#define HAS_GOOGLE_BREAKPAD_STRING - -#endif // THIRD_PARTY_BREAKPAD_SRC_COMMON_USING_STD_STRING_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/common_windows.gyp b/toolkit/crashreporter/google-breakpad/src/common/windows/common_windows.gyp deleted file mode 100644 index c98333a34..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/common_windows.gyp +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2013 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'dia_sdk', - 'type': 'none', - 'all_dependent_settings': { - 'include_dirs': [ - '<(DEPTH)', - '$(VSInstallDir)/DIA SDK/include', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalDependencies': [ - 'diaguids.lib', - 'imagehlp.lib', - ], - }, - }, - 'configurations': { - 'x86_Base': { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalLibraryDirectories': - ['$(VSInstallDir)/DIA SDK/lib'], - }, - }, - }, - 'x64_Base': { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalLibraryDirectories': - ['$(VSInstallDir)/DIA SDK/lib/amd64'], - }, - }, - }, - }, - }, - }, - { - 'target_name': 'common_windows_lib', - 'type': 'static_library', - 'sources': [ - 'dia_util.cc', - 'dia_util.h', - 'guid_string.cc', - 'guid_string.h', - 'http_upload.cc', - 'http_upload.h', - 'omap.cc', - 'omap.h', - 'omap_internal.h', - 'pdb_source_line_writer.cc', - 'pdb_source_line_writer.h', - 'string_utils.cc', - 'string_utils-inl.h', - ], - 'dependencies': [ - 'dia_sdk', - ], - }, - { - 'target_name': 'common_windows_unittests', - 'type': 'executable', - 'sources': [ - 'omap_unittest.cc', - ], - 'dependencies': [ - '<(DEPTH)/client/windows/unittests/testing.gyp:gmock', - '<(DEPTH)/client/windows/unittests/testing.gyp:gtest', - 'common_windows_lib', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.cc deleted file mode 100644 index ed8cb5b65..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/windows/dia_util.h" - -#include - -namespace google_breakpad { - -bool FindDebugStream(const wchar_t* name, - IDiaSession* session, - IDiaEnumDebugStreamData** debug_stream) { - CComPtr enum_debug_streams; - if (FAILED(session->getEnumDebugStreams(&enum_debug_streams))) { - fprintf(stderr, "IDiaSession::getEnumDebugStreams failed\n"); - return false; - } - - CComPtr temp_debug_stream; - ULONG fetched = 0; - while (SUCCEEDED(enum_debug_streams->Next(1, &temp_debug_stream, &fetched)) && - fetched == 1) { - CComBSTR stream_name; - if (FAILED(temp_debug_stream->get_name(&stream_name))) { - fprintf(stderr, "IDiaEnumDebugStreamData::get_name failed\n"); - return false; - } - - // Found the stream? - if (wcsncmp((LPWSTR)stream_name, name, stream_name.Length()) == 0) { - *debug_stream = temp_debug_stream.Detach(); - return true; - } - - temp_debug_stream.Release(); - } - - // No table was found. - return false; -} - -bool FindTable(REFIID iid, IDiaSession* session, void** table) { - // Get the table enumerator. - CComPtr enum_tables; - if (FAILED(session->getEnumTables(&enum_tables))) { - fprintf(stderr, "IDiaSession::getEnumTables failed\n"); - return false; - } - - // Iterate through the tables. - CComPtr temp_table; - ULONG fetched = 0; - while (SUCCEEDED(enum_tables->Next(1, &temp_table, &fetched)) && - fetched == 1) { - void* temp = NULL; - if (SUCCEEDED(temp_table->QueryInterface(iid, &temp))) { - *table = temp; - return true; - } - temp_table.Release(); - } - - // The table was not found. - return false; -} - -} // namespace google_breakpad \ No newline at end of file diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.h b/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.h deleted file mode 100644 index b9e0df2d5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/dia_util.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utilities for loading debug streams and tables from a PDB file. - -#ifndef COMMON_WINDOWS_DIA_UTIL_H_ -#define COMMON_WINDOWS_DIA_UTIL_H_ - -#include -#include - -namespace google_breakpad { - -// Find the debug stream of the given |name| in the given |session|. Returns -// true on success, false on error of if the stream does not exist. On success -// the stream will be returned via |debug_stream|. -bool FindDebugStream(const wchar_t* name, - IDiaSession* session, - IDiaEnumDebugStreamData** debug_stream); - -// Finds the first table implementing the COM interface with ID |iid| in the -// given |session|. Returns true on success, false on error or if no such -// table is found. On success the table will be returned via |table|. -bool FindTable(REFIID iid, IDiaSession* session, void** table); - -// A templated version of FindTable. Finds the first table implementing type -// |InterfaceType| in the given |session|. Returns true on success, false on -// error or if no such table is found. On success the table will be returned via -// |table|. -template -bool FindTable(IDiaSession* session, InterfaceType** table) { - return FindTable(__uuidof(InterfaceType), - session, - reinterpret_cast(table)); -} - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_DIA_UTIL_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.cc deleted file mode 100644 index b7f877e66..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// guid_string.cc: Convert GUIDs to strings. -// -// See guid_string.h for documentation. - -#include - -#include "common/windows/string_utils-inl.h" - -#include "common/windows/guid_string.h" - -namespace google_breakpad { - -// static -wstring GUIDString::GUIDToWString(GUID *guid) { - wchar_t guid_string[37]; - swprintf( - guid_string, sizeof(guid_string) / sizeof(guid_string[0]), - L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], - guid->Data4[3], guid->Data4[4], guid->Data4[5], - guid->Data4[6], guid->Data4[7]); - - // remove when VC++7.1 is no longer supported - guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0'; - - return wstring(guid_string); -} - -// static -wstring GUIDString::GUIDToSymbolServerWString(GUID *guid) { - wchar_t guid_string[33]; - swprintf( - guid_string, sizeof(guid_string) / sizeof(guid_string[0]), - L"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], - guid->Data4[3], guid->Data4[4], guid->Data4[5], - guid->Data4[6], guid->Data4[7]); - - // remove when VC++7.1 is no longer supported - guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0'; - - return wstring(guid_string); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.h b/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.h deleted file mode 100644 index 48a5c1d37..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// guid_string.cc: Convert GUIDs to strings. - -#ifndef COMMON_WINDOWS_GUID_STRING_H_ -#define COMMON_WINDOWS_GUID_STRING_H_ - -#include - -#include - -namespace google_breakpad { - -using std::wstring; - -class GUIDString { - public: - // Converts guid to a string in the format recommended by RFC 4122 and - // returns the string. - static wstring GUIDToWString(GUID *guid); - - // Converts guid to a string formatted as uppercase hexadecimal, with - // no separators, and returns the string. This is the format used for - // symbol server identifiers, although identifiers have an age tacked - // on to the string. - static wstring GUIDToSymbolServerWString(GUID *guid); -}; - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_GUID_STRING_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.cc deleted file mode 100644 index 7676bdc5a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.cc +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -// Disable exception handler warnings. -#pragma warning(disable:4530) - -#include - -#include "common/windows/string_utils-inl.h" - -#include "common/windows/http_upload.h" - -namespace google_breakpad { - -using std::ifstream; -using std::ios; - -static const wchar_t kUserAgent[] = L"Breakpad/1.0 (Windows)"; - -// Helper class which closes an internet handle when it goes away -class HTTPUpload::AutoInternetHandle { - public: - explicit AutoInternetHandle(HINTERNET handle) : handle_(handle) {} - ~AutoInternetHandle() { - if (handle_) { - InternetCloseHandle(handle_); - } - } - - HINTERNET get() { return handle_; } - - private: - HINTERNET handle_; -}; - -// static -bool HTTPUpload::SendRequest(const wstring &url, - const map ¶meters, - const map &files, - int *timeout, - wstring *response_body, - int *response_code) { - if (response_code) { - *response_code = 0; - } - - // TODO(bryner): support non-ASCII parameter names - if (!CheckParameters(parameters)) { - return false; - } - - // Break up the URL and make sure we can handle it - wchar_t scheme[16], host[256], path[256]; - URL_COMPONENTS components; - memset(&components, 0, sizeof(components)); - components.dwStructSize = sizeof(components); - components.lpszScheme = scheme; - components.dwSchemeLength = sizeof(scheme) / sizeof(scheme[0]); - components.lpszHostName = host; - components.dwHostNameLength = sizeof(host) / sizeof(host[0]); - components.lpszUrlPath = path; - components.dwUrlPathLength = sizeof(path) / sizeof(path[0]); - if (!InternetCrackUrl(url.c_str(), static_cast(url.size()), - 0, &components)) { - return false; - } - bool secure = false; - if (wcscmp(scheme, L"https") == 0) { - secure = true; - } else if (wcscmp(scheme, L"http") != 0) { - return false; - } - - AutoInternetHandle internet(InternetOpen(kUserAgent, - INTERNET_OPEN_TYPE_PRECONFIG, - NULL, // proxy name - NULL, // proxy bypass - 0)); // flags - if (!internet.get()) { - return false; - } - - AutoInternetHandle connection(InternetConnect(internet.get(), - host, - components.nPort, - NULL, // user name - NULL, // password - INTERNET_SERVICE_HTTP, - 0, // flags - NULL)); // context - if (!connection.get()) { - return false; - } - - DWORD http_open_flags = secure ? INTERNET_FLAG_SECURE : 0; - http_open_flags |= INTERNET_FLAG_NO_COOKIES; - AutoInternetHandle request(HttpOpenRequest(connection.get(), - L"POST", - path, - NULL, // version - NULL, // referer - NULL, // agent type - http_open_flags, - NULL)); // context - if (!request.get()) { - return false; - } - - wstring boundary = GenerateMultipartBoundary(); - wstring content_type_header = GenerateRequestHeader(boundary); - HttpAddRequestHeaders(request.get(), - content_type_header.c_str(), - static_cast(-1), - HTTP_ADDREQ_FLAG_ADD); - - string request_body; - if (!GenerateRequestBody(parameters, files, boundary, &request_body)) { - return false; - } - - if (timeout) { - if (!InternetSetOption(request.get(), - INTERNET_OPTION_SEND_TIMEOUT, - timeout, - sizeof(*timeout))) { - fwprintf(stderr, L"Could not unset send timeout, continuing...\n"); - } - - if (!InternetSetOption(request.get(), - INTERNET_OPTION_RECEIVE_TIMEOUT, - timeout, - sizeof(*timeout))) { - fwprintf(stderr, L"Could not unset receive timeout, continuing...\n"); - } - } - - if (!HttpSendRequest(request.get(), NULL, 0, - const_cast(request_body.data()), - static_cast(request_body.size()))) { - return false; - } - - // The server indicates a successful upload with HTTP status 200. - wchar_t http_status[4]; - DWORD http_status_size = sizeof(http_status); - if (!HttpQueryInfo(request.get(), HTTP_QUERY_STATUS_CODE, - static_cast(&http_status), &http_status_size, - 0)) { - return false; - } - - int http_response = wcstol(http_status, NULL, 10); - if (response_code) { - *response_code = http_response; - } - - bool result = (http_response == 200); - - if (result) { - result = ReadResponse(request.get(), response_body); - } - - return result; -} - -// static -bool HTTPUpload::ReadResponse(HINTERNET request, wstring *response) { - bool has_content_length_header = false; - wchar_t content_length[32]; - DWORD content_length_size = sizeof(content_length); - DWORD claimed_size = 0; - string response_body; - - if (HttpQueryInfo(request, HTTP_QUERY_CONTENT_LENGTH, - static_cast(&content_length), - &content_length_size, 0)) { - has_content_length_header = true; - claimed_size = wcstol(content_length, NULL, 10); - response_body.reserve(claimed_size); - } - - - DWORD bytes_available; - DWORD total_read = 0; - BOOL return_code; - - while (((return_code = InternetQueryDataAvailable(request, &bytes_available, - 0, 0)) != 0) && bytes_available > 0) { - vector response_buffer(bytes_available); - DWORD size_read; - - return_code = InternetReadFile(request, - &response_buffer[0], - bytes_available, &size_read); - - if (return_code && size_read > 0) { - total_read += size_read; - response_body.append(&response_buffer[0], size_read); - } else { - break; - } - } - - bool succeeded = return_code && (!has_content_length_header || - (total_read == claimed_size)); - if (succeeded && response) { - *response = UTF8ToWide(response_body); - } - - return succeeded; -} - -// static -wstring HTTPUpload::GenerateMultipartBoundary() { - // The boundary has 27 '-' characters followed by 16 hex digits - static const wchar_t kBoundaryPrefix[] = L"---------------------------"; - static const int kBoundaryLength = 27 + 16 + 1; - - // Generate some random numbers to fill out the boundary - int r0 = rand(); - int r1 = rand(); - - wchar_t temp[kBoundaryLength]; - swprintf(temp, kBoundaryLength, L"%s%08X%08X", kBoundaryPrefix, r0, r1); - - // remove when VC++7.1 is no longer supported - temp[kBoundaryLength - 1] = L'\0'; - - return wstring(temp); -} - -// static -wstring HTTPUpload::GenerateRequestHeader(const wstring &boundary) { - wstring header = L"Content-Type: multipart/form-data; boundary="; - header += boundary; - return header; -} - -// static -bool HTTPUpload::GenerateRequestBody(const map ¶meters, - const map &files, - const wstring &boundary, - string *request_body) { - string boundary_str = WideToUTF8(boundary); - if (boundary_str.empty()) { - return false; - } - - request_body->clear(); - - // Append each of the parameter pairs as a form-data part - for (map::const_iterator pos = parameters.begin(); - pos != parameters.end(); ++pos) { - request_body->append("--" + boundary_str + "\r\n"); - request_body->append("Content-Disposition: form-data; name=\"" + - WideToUTF8(pos->first) + "\"\r\n\r\n" + - WideToUTF8(pos->second) + "\r\n"); - } - - for (map::const_iterator pos = files.begin(); - pos != files.end(); ++pos) { - vector contents; - if (!GetFileContents(pos->second, &contents)) { - return false; - } - - // Now append the upload files as a binary (octet-stream) part - string filename_utf8 = WideToUTF8(pos->second); - if (filename_utf8.empty()) { - return false; - } - - string file_part_name_utf8 = WideToUTF8(pos->first); - if (file_part_name_utf8.empty()) { - return false; - } - - request_body->append("--" + boundary_str + "\r\n"); - request_body->append("Content-Disposition: form-data; " - "name=\"" + file_part_name_utf8 + "\"; " - "filename=\"" + filename_utf8 + "\"\r\n"); - request_body->append("Content-Type: application/octet-stream\r\n"); - request_body->append("\r\n"); - - if (!contents.empty()) { - request_body->append(&(contents[0]), contents.size()); - } - request_body->append("\r\n"); - } - request_body->append("--" + boundary_str + "--\r\n"); - return true; -} - -// static -bool HTTPUpload::GetFileContents(const wstring &filename, - vector *contents) { - bool rv = false; - // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a - // wchar_t* filename, so use _wfopen directly in that case. For VC8 and - // later, _wfopen has been deprecated in favor of _wfopen_s, which does - // not exist in earlier versions, so let the ifstream open the file itself. - // GCC doesn't support wide file name and opening on FILE* requires ugly - // hacks, so fallback to multi byte file. -#ifdef _MSC_VER - ifstream file; - file.open(filename.c_str(), ios::binary); -#else // GCC - ifstream file(WideToMBCP(filename, CP_ACP).c_str(), ios::binary); -#endif // _MSC_VER >= 1400 - if (file.is_open()) { - file.seekg(0, ios::end); - std::streamoff length = file.tellg(); - // Check for loss of data when converting lenght from std::streamoff into - // std::vector::size_type - std::vector::size_type vector_size = - static_cast::size_type>(length); - if (static_cast(vector_size) == length) { - contents->resize(vector_size); - if (length != 0) { - file.seekg(0, ios::beg); - file.read(&((*contents)[0]), length); - } - rv = true; - } - file.close(); - } - return rv; -} - -// static -wstring HTTPUpload::UTF8ToWide(const string &utf8) { - if (utf8.length() == 0) { - return wstring(); - } - - // compute the length of the buffer we'll need - int charcount = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0); - - if (charcount == 0) { - return wstring(); - } - - // convert - wchar_t* buf = new wchar_t[charcount]; - MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, buf, charcount); - wstring result(buf); - delete[] buf; - return result; -} - -// static -string HTTPUpload::WideToMBCP(const wstring &wide, unsigned int cp) { - if (wide.length() == 0) { - return string(); - } - - // compute the length of the buffer we'll need - int charcount = WideCharToMultiByte(cp, 0, wide.c_str(), -1, - NULL, 0, NULL, NULL); - if (charcount == 0) { - return string(); - } - - // convert - char *buf = new char[charcount]; - WideCharToMultiByte(cp, 0, wide.c_str(), -1, buf, charcount, - NULL, NULL); - - string result(buf); - delete[] buf; - return result; -} - -// static -bool HTTPUpload::CheckParameters(const map ¶meters) { - for (map::const_iterator pos = parameters.begin(); - pos != parameters.end(); ++pos) { - const wstring &str = pos->first; - if (str.size() == 0) { - return false; // disallow empty parameter names - } - for (unsigned int i = 0; i < str.size(); ++i) { - wchar_t c = str[i]; - if (c < 32 || c == '"' || c > 127) { - return false; - } - } - } - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.h b/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.h deleted file mode 100644 index f8d48cb1b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST -// request using wininet. It currently supports requests that contain -// a set of string parameters (key/value pairs), and a file to upload. - -#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_ -#define COMMON_WINDOWS_HTTP_UPLOAD_H_ - -#pragma warning(push) -// Disable exception handler warnings. -#pragma warning(disable : 4530) - -#include -#include - -#include -#include -#include - -namespace google_breakpad { - -using std::string; -using std::wstring; -using std::map; -using std::vector; - -class HTTPUpload { - public: - // Sends the given sets of parameters and files as a multipart POST - // request to the given URL. - // Each key in |files| is the name of the file part of the request - // (i.e. it corresponds to the name= attribute on an . - // Parameter names must contain only printable ASCII characters, - // and may not contain a quote (") character. - // Only HTTP(S) URLs are currently supported. Returns true on success. - // If the request is successful and response_body is non-NULL, - // the response body will be returned in response_body. - // If response_code is non-NULL, it will be set to the HTTP response code - // received (or 0 if the request failed before getting an HTTP response). - static bool SendRequest(const wstring &url, - const map ¶meters, - const map &files, - int *timeout, - wstring *response_body, - int *response_code); - - private: - class AutoInternetHandle; - - // Retrieves the HTTP response. If NULL is passed in for response, - // this merely checks (via the return value) that we were successfully - // able to retrieve exactly as many bytes of content in the response as - // were specified in the Content-Length header. - static bool ReadResponse(HINTERNET request, wstring* response); - - // Generates a new multipart boundary for a POST request - static wstring GenerateMultipartBoundary(); - - // Generates a HTTP request header for a multipart form submit. - static wstring GenerateRequestHeader(const wstring &boundary); - - // Given a set of parameters, a set of upload files, and a file part name, - // generates a multipart request body string with these parameters - // and minidump contents. Returns true on success. - static bool GenerateRequestBody(const map ¶meters, - const map &files, - const wstring &boundary, - string *request_body); - - // Fills the supplied vector with the contents of filename. - static bool GetFileContents(const wstring &filename, vector *contents); - - // Converts a UTF8 string to UTF16. - static wstring UTF8ToWide(const string &utf8); - - // Converts a UTF16 string to UTF8. - static string WideToUTF8(const wstring &wide) { - return WideToMBCP(wide, CP_UTF8); - } - - // Converts a UTF16 string to specified code page. - static string WideToMBCP(const wstring &wide, unsigned int cp); - - // Checks that the given list of parameters has only printable - // ASCII characters in the parameter name, and does not contain - // any quote (") characters. Returns true if so. - static bool CheckParameters(const map ¶meters); - - // No instances of this class should be created. - // Disallow all constructors, destructors, and operator=. - HTTPUpload(); - explicit HTTPUpload(const HTTPUpload &); - void operator=(const HTTPUpload &); - ~HTTPUpload(); -}; - -} // namespace google_breakpad - -#pragma warning(pop) - -#endif // COMMON_WINDOWS_HTTP_UPLOAD_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild b/toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild deleted file mode 100644 index 5fcdae5a3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild +++ /dev/null @@ -1,15 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -lobjs_common = [ - 'guid_string.cc', - 'string_utils.cc', -] - -subdir = 'toolkit/crashreporter/google-breakpad/src/common/windows' -objs_common = [ - '/%s/%s' % (subdir, s) for s in lobjs_common -] diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/omap.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/omap.cc deleted file mode 100644 index 554a57c2d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/omap.cc +++ /dev/null @@ -1,694 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This contains a suite of tools for transforming symbol information when -// when that information has been extracted from a PDB containing OMAP -// information. - -// OMAP information is a lightweight description of a mapping between two -// address spaces. It consists of two streams, each of them a vector 2-tuples. -// The OMAPTO stream contains tuples of the form -// -// (RVA in transformed image, RVA in original image) -// -// while the OMAPFROM stream contains tuples of the form -// -// (RVA in original image, RVA in transformed image) -// -// The entries in each vector are sorted by the first value of the tuple, and -// the lengths associated with a mapping are implicit as the distance between -// two successive addresses in the vector. - -// Consider a trivial 10-byte function described by the following symbol: -// -// Function: RVA 0x00001000, length 10, "foo" -// -// Now consider the same function, but with 5-bytes of instrumentation injected -// at offset 5. The OMAP streams describing this would look like: -// -// OMAPTO : [ [0x00001000, 0x00001000], -// [0x00001005, 0xFFFFFFFF], -// [0x0000100a, 0x00001005] ] -// OMAPFROM: [ [0x00001000, 0x00001000], -// [0x00001005, 0x0000100a] ] -// -// In this case the injected code has been marked as not originating in the -// source image, and thus it will have no symbol information at all. However, -// the injected code may also be associated with an original address range; -// for example, when prepending instrumentation to a basic block the -// instrumentation can be labelled as originating from the same source BB such -// that symbol resolution will still find the appropriate source code line -// number. In this case the OMAP stream would look like: -// -// OMAPTO : [ [0x00001000, 0x00001000], -// [0x00001005, 0x00001005], -// [0x0000100a, 0x00001005] ] -// OMAPFROM: [ [0x00001000, 0x00001000], -// [0x00001005, 0x0000100a] ] -// -// Suppose we asked DIA to lookup the symbol at location 0x0000100a of the -// instrumented image. It would first run this through the OMAPTO table and -// translate that address to 0x00001005. It would then lookup the symbol -// at that address and return the symbol for the function "foo". This is the -// correct result. -// -// However, if we query DIA for the length and address of the symbol it will -// tell us that it has length 10 and is at RVA 0x00001000. The location is -// correct, but the length doesn't take into account the 5-bytes of injected -// code. Symbol resolution works (starting from an instrumented address, -// mapping to an original address, and looking up a symbol), but the symbol -// metadata is incorrect. -// -// If we dump the symbols using DIA they will have their addresses -// appropriately transformed and reflect positions in the instrumented image. -// However, if we try to do a lookup using those symbols resolution can fail. -// For example, the address 0x0000100a will not map to the symbol for "foo", -// because DIA tells us it is at location 0x00001000 (correct) with length -// 10 (incorrect). The problem is one of order of operations: in this case -// we're attempting symbol resolution by looking up an instrumented address -// in the table of translated symbols. -// -// One way to handle this is to dump the OMAP information as part of the -// breakpad symbols. This requires the rest of the toolchain to be aware of -// OMAP information and to use it when present prior to performing lookup. The -// other option is to properly transform the symbols (updating length as well as -// position) so that resolution will work as expected for translated addresses. -// This is transparent to the rest of the toolchain. - -#include "common/windows/omap.h" - -#include - -#include -#include -#include - -#include "common/windows/dia_util.h" - -namespace google_breakpad { - -namespace { - -static const wchar_t kOmapToDebugStreamName[] = L"OMAPTO"; -static const wchar_t kOmapFromDebugStreamName[] = L"OMAPFROM"; - -// Dependending on where this is used in breakpad we sometimes get min/max from -// windef, and other times from algorithm. To get around this we simply -// define our own min/max functions. -template -const T& Min(const T& t1, const T& t2) { return t1 < t2 ? t1 : t2; } -template -const T& Max(const T& t1, const T& t2) { return t1 > t2 ? t1 : t2; } - -// It makes things more readable to have two different OMAP types. We cast -// normal OMAPs into these. They must be the same size as the OMAP structure -// for this to work, hence the static asserts. -struct OmapOrigToTran { - DWORD rva_original; - DWORD rva_transformed; -}; -struct OmapTranToOrig { - DWORD rva_transformed; - DWORD rva_original; -}; -static_assert(sizeof(OmapOrigToTran) == sizeof(OMAP), - "OmapOrigToTran must have same size as OMAP."); -static_assert(sizeof(OmapTranToOrig) == sizeof(OMAP), - "OmapTranToOrig must have same size as OMAP."); -typedef std::vector OmapFromTable; -typedef std::vector OmapToTable; - -// Used for sorting and searching through a Mapping. -bool MappedRangeOriginalLess(const MappedRange& lhs, const MappedRange& rhs) { - if (lhs.rva_original < rhs.rva_original) - return true; - if (lhs.rva_original > rhs.rva_original) - return false; - return lhs.length < rhs.length; -} -bool MappedRangeMappedLess(const MappedRange& lhs, const MappedRange& rhs) { - if (lhs.rva_transformed < rhs.rva_transformed) - return true; - if (lhs.rva_transformed > rhs.rva_transformed) - return false; - return lhs.length < rhs.length; -} - -// Used for searching through the EndpointIndexMap. -bool EndpointIndexLess(const EndpointIndex& ei1, const EndpointIndex& ei2) { - return ei1.endpoint < ei2.endpoint; -} - -// Finds the debug stream with the given |name| in the given |session|, and -// populates |table| with its contents. Casts the data directly into OMAP -// structs. -bool FindAndLoadOmapTable(const wchar_t* name, - IDiaSession* session, - OmapTable* table) { - assert(name != NULL); - assert(session != NULL); - assert(table != NULL); - - CComPtr stream; - if (!FindDebugStream(name, session, &stream)) - return false; - assert(stream.p != NULL); - - LONG count = 0; - if (FAILED(stream->get_Count(&count))) { - fprintf(stderr, "IDiaEnumDebugStreamData::get_Count failed for stream " - "\"%ws\"\n", name); - return false; - } - - // Get the length of the stream in bytes. - DWORD bytes_read = 0; - ULONG count_read = 0; - if (FAILED(stream->Next(count, 0, &bytes_read, NULL, &count_read))) { - fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " - "length of stream \"%ws\"\n", name); - return false; - } - - // Ensure it's consistent with the OMAP data type. - DWORD bytes_expected = count * sizeof(OmapTable::value_type); - if (count * sizeof(OmapTable::value_type) != bytes_read) { - fprintf(stderr, "DIA debug stream \"%ws\" has an unexpected length", name); - return false; - } - - // Read the table. - table->resize(count); - bytes_read = 0; - count_read = 0; - if (FAILED(stream->Next(count, bytes_expected, &bytes_read, - reinterpret_cast(&table->at(0)), - &count_read))) { - fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " - "data from stream \"%ws\"\n", name); - return false; - } - - return true; -} - -// This determines the original image length by looking through the segment -// table. -bool GetOriginalImageLength(IDiaSession* session, DWORD* image_length) { - assert(session != NULL); - assert(image_length != NULL); - - CComPtr enum_segments; - if (!FindTable(session, &enum_segments)) - return false; - assert(enum_segments.p != NULL); - - DWORD temp_image_length = 0; - CComPtr segment; - ULONG fetched = 0; - while (SUCCEEDED(enum_segments->Next(1, &segment, &fetched)) && - fetched == 1) { - assert(segment.p != NULL); - - DWORD rva = 0; - DWORD length = 0; - DWORD frame = 0; - if (FAILED(segment->get_relativeVirtualAddress(&rva)) || - FAILED(segment->get_length(&length)) || - FAILED(segment->get_frame(&frame))) { - fprintf(stderr, "Failed to get basic properties for IDiaSegment\n"); - return false; - } - - if (frame > 0) { - DWORD segment_end = rva + length; - if (segment_end > temp_image_length) - temp_image_length = segment_end; - } - segment.Release(); - } - - *image_length = temp_image_length; - return true; -} - -// Detects regions of the original image that have been removed in the -// transformed image, and sets the 'removed' property on all mapped ranges -// immediately preceding a gap. The mapped ranges must be sorted by -// 'rva_original'. -void FillInRemovedLengths(Mapping* mapping) { - assert(mapping != NULL); - - // Find and fill gaps. We do this with two sweeps. We first sweep forward - // looking for gaps. When we identify a gap we then sweep forward with a - // second scan and set the 'removed' property for any intervals that - // immediately precede the gap. - // - // Gaps are typically between two successive intervals, but not always: - // - // Range 1: --------------- - // Range 2: ------- - // Range 3: ------------- - // Gap : ****** - // - // In the above example the gap is between range 1 and range 3. A forward - // sweep finds the gap, and a second forward sweep identifies that range 1 - // immediately precedes the gap and sets its 'removed' property. - - size_t fill = 0; - DWORD rva_front = 0; - for (size_t find = 0; find < mapping->size(); ++find) { -#ifndef NDEBUG - // We expect the mapped ranges to be sorted by 'rva_original'. - if (find > 0) { - assert(mapping->at(find - 1).rva_original <= - mapping->at(find).rva_original); - } -#endif - - if (rva_front < mapping->at(find).rva_original) { - // We've found a gap. Fill it in by setting the 'removed' property for - // any affected intervals. - DWORD removed = mapping->at(find).rva_original - rva_front; - for (; fill < find; ++fill) { - if (mapping->at(fill).rva_original + mapping->at(fill).length != - rva_front) { - continue; - } - - // This interval ends right where the gap starts. It needs to have its - // 'removed' information filled in. - mapping->at(fill).removed = removed; - } - } - - // Advance the front that indicates the covered portion of the image. - rva_front = mapping->at(find).rva_original + mapping->at(find).length; - } -} - -// Builds a unified view of the mapping between the original and transformed -// image space by merging OMAPTO and OMAPFROM data. -void BuildMapping(const OmapData& omap_data, Mapping* mapping) { - assert(mapping != NULL); - - mapping->clear(); - - if (omap_data.omap_from.empty() || omap_data.omap_to.empty()) - return; - - // The names 'omap_to' and 'omap_from' are awfully confusing, so we make - // ourselves more explicit here. This cast is only safe because the underlying - // types have the exact same size. - const OmapToTable& tran2orig = - reinterpret_cast(omap_data.omap_to); - const OmapFromTable& orig2tran = reinterpret_cast( - omap_data.omap_from); - - // Handle the range of data at the beginning of the image. This is not usually - // specified by the OMAP data. - if (tran2orig[0].rva_transformed > 0 && orig2tran[0].rva_original > 0) { - DWORD header_transformed = tran2orig[0].rva_transformed; - DWORD header_original = orig2tran[0].rva_original; - DWORD header = Min(header_transformed, header_original); - - MappedRange mr = {}; - mr.length = header; - mr.injected = header_transformed - header; - mr.removed = header_original - header; - mapping->push_back(mr); - } - - // Convert the implied lengths to explicit lengths, and infer which content - // has been injected into the transformed image. Injected content is inferred - // as regions of the transformed address space that does not map back to - // known valid content in the original image. - for (size_t i = 0; i < tran2orig.size(); ++i) { - const OmapTranToOrig& o1 = tran2orig[i]; - - // This maps to content that is outside the original image, thus it - // describes injected content. We can skip this entry. - if (o1.rva_original >= omap_data.length_original) - continue; - - // Calculate the length of the current OMAP entry. This is implicit as the - // distance between successive |rva| values, capped at the end of the - // original image. - DWORD length = 0; - if (i + 1 < tran2orig.size()) { - const OmapTranToOrig& o2 = tran2orig[i + 1]; - - // We expect the table to be sorted by rva_transformed. - assert(o1.rva_transformed <= o2.rva_transformed); - - length = o2.rva_transformed - o1.rva_transformed; - if (o1.rva_original + length > omap_data.length_original) { - length = omap_data.length_original - o1.rva_original; - } - } else { - length = omap_data.length_original - o1.rva_original; - } - - // Zero-length entries don't describe anything and can be ignored. - if (length == 0) - continue; - - // Any gaps in the transformed address-space are due to injected content. - if (!mapping->empty()) { - MappedRange& prev_mr = mapping->back(); - prev_mr.injected += o1.rva_transformed - - (prev_mr.rva_transformed + prev_mr.length); - } - - MappedRange mr = {}; - mr.rva_original = o1.rva_original; - mr.rva_transformed = o1.rva_transformed; - mr.length = length; - mapping->push_back(mr); - } - - // Sort based on the original image addresses. - std::sort(mapping->begin(), mapping->end(), MappedRangeOriginalLess); - - // Fill in the 'removed' lengths by looking for gaps in the coverage of the - // original address space. - FillInRemovedLengths(mapping); - - return; -} - -void BuildEndpointIndexMap(ImageMap* image_map) { - assert(image_map != NULL); - - if (image_map->mapping.size() == 0) - return; - - const Mapping& mapping = image_map->mapping; - EndpointIndexMap& eim = image_map->endpoint_index_map; - - // Get the unique set of interval endpoints. - std::set endpoints; - for (size_t i = 0; i < mapping.size(); ++i) { - endpoints.insert(mapping[i].rva_original); - endpoints.insert(mapping[i].rva_original + - mapping[i].length + - mapping[i].removed); - } - - // Use the endpoints to initialize the secondary search structure for the - // mapping. - eim.resize(endpoints.size()); - std::set::const_iterator it = endpoints.begin(); - for (size_t i = 0; it != endpoints.end(); ++it, ++i) { - eim[i].endpoint = *it; - eim[i].index = mapping.size(); - } - - // For each endpoint we want the smallest index of any interval containing - // it. We iterate over the intervals and update the indices associated with - // each interval endpoint contained in the current interval. In the general - // case of an arbitrary set of intervals this is O(n^2), but the structure of - // OMAP data makes this O(n). - for (size_t i = 0; i < mapping.size(); ++i) { - EndpointIndex ei1 = { mapping[i].rva_original, 0 }; - EndpointIndexMap::iterator it1 = std::lower_bound( - eim.begin(), eim.end(), ei1, EndpointIndexLess); - - EndpointIndex ei2 = { mapping[i].rva_original + mapping[i].length + - mapping[i].removed, 0 }; - EndpointIndexMap::iterator it2 = std::lower_bound( - eim.begin(), eim.end(), ei2, EndpointIndexLess); - - for (; it1 != it2; ++it1) - it1->index = Min(i, it1->index); - } -} - -// Clips the given mapped range. -void ClipMappedRangeOriginal(const AddressRange& clip_range, - MappedRange* mapped_range) { - assert(mapped_range != NULL); - - // The clipping range is entirely outside of the mapped range. - if (clip_range.end() <= mapped_range->rva_original || - mapped_range->rva_original + mapped_range->length + - mapped_range->removed <= clip_range.rva) { - mapped_range->length = 0; - mapped_range->injected = 0; - mapped_range->removed = 0; - return; - } - - // Clip the left side. - if (mapped_range->rva_original < clip_range.rva) { - DWORD clip_left = clip_range.rva - mapped_range->rva_original; - mapped_range->rva_original += clip_left; - mapped_range->rva_transformed += clip_left; - - if (clip_left > mapped_range->length) { - // The left clipping boundary entirely erases the content section of the - // range. - DWORD trim = clip_left - mapped_range->length; - mapped_range->length = 0; - mapped_range->injected -= Min(trim, mapped_range->injected); - // We know that trim <= mapped_range->remove. - mapped_range->removed -= trim; - } else { - // The left clipping boundary removes some, but not all, of the content. - // As such it leaves the removed/injected component intact. - mapped_range->length -= clip_left; - } - } - - // Clip the right side. - DWORD end_original = mapped_range->rva_original + mapped_range->length; - if (clip_range.end() < end_original) { - // The right clipping boundary lands in the 'content' section of the range, - // entirely clearing the injected/removed portion. - DWORD clip_right = end_original - clip_range.end(); - mapped_range->length -= clip_right; - mapped_range->injected = 0; - mapped_range->removed = 0; - return; - } else { - // The right clipping boundary is outside of the content, but may affect - // the removed/injected portion of the range. - DWORD end_removed = end_original + mapped_range->removed; - if (clip_range.end() < end_removed) - mapped_range->removed = clip_range.end() - end_original; - - DWORD end_injected = end_original + mapped_range->injected; - if (clip_range.end() < end_injected) - mapped_range->injected = clip_range.end() - end_original; - } - - return; -} - -} // namespace - -int AddressRange::Compare(const AddressRange& rhs) const { - if (end() <= rhs.rva) - return -1; - if (rhs.end() <= rva) - return 1; - return 0; -} - -bool GetOmapDataAndDisableTranslation(IDiaSession* session, - OmapData* omap_data) { - assert(session != NULL); - assert(omap_data != NULL); - - CComPtr address_map; - if (FAILED(session->QueryInterface(&address_map))) { - fprintf(stderr, "IDiaSession::QueryInterface(IDiaAddressMap) failed\n"); - return false; - } - assert(address_map.p != NULL); - - BOOL omap_enabled = FALSE; - if (FAILED(address_map->get_addressMapEnabled(&omap_enabled))) { - fprintf(stderr, "IDiaAddressMap::get_addressMapEnabled failed\n"); - return false; - } - - if (!omap_enabled) { - // We indicate the non-presence of OMAP data by returning empty tables. - omap_data->omap_from.clear(); - omap_data->omap_to.clear(); - omap_data->length_original = 0; - return true; - } - - // OMAP data is present. Disable translation. - if (FAILED(address_map->put_addressMapEnabled(FALSE))) { - fprintf(stderr, "IDiaAddressMap::put_addressMapEnabled failed\n"); - return false; - } - - // Read the OMAP streams. - if (!FindAndLoadOmapTable(kOmapFromDebugStreamName, - session, - &omap_data->omap_from)) { - return false; - } - if (!FindAndLoadOmapTable(kOmapToDebugStreamName, - session, - &omap_data->omap_to)) { - return false; - } - - // Get the lengths of the address spaces. - if (!GetOriginalImageLength(session, &omap_data->length_original)) - return false; - - return true; -} - -void BuildImageMap(const OmapData& omap_data, ImageMap* image_map) { - assert(image_map != NULL); - - BuildMapping(omap_data, &image_map->mapping); - BuildEndpointIndexMap(image_map); -} - -void MapAddressRange(const ImageMap& image_map, - const AddressRange& original_range, - AddressRangeVector* mapped_ranges) { - assert(mapped_ranges != NULL); - - const Mapping& map = image_map.mapping; - - // Handle the trivial case of an empty image_map. This means that there is - // no transformation to be applied, and we can simply return the original - // range. - if (map.empty()) { - mapped_ranges->push_back(original_range); - return; - } - - // If we get a query of length 0 we need to handle it by using a non-zero - // query length. - AddressRange query_range(original_range); - if (query_range.length == 0) - query_range.length = 1; - - // Find the range of intervals that can potentially intersect our query range. - size_t imin = 0; - size_t imax = 0; - { - // The index of the earliest possible range that can affect is us done by - // searching through the secondary indexing structure. - const EndpointIndexMap& eim = image_map.endpoint_index_map; - EndpointIndex q1 = { query_range.rva, 0 }; - EndpointIndexMap::const_iterator it1 = std::lower_bound( - eim.begin(), eim.end(), q1, EndpointIndexLess); - if (it1 == eim.end()) { - imin = map.size(); - } else { - // Backup to find the interval that contains our query point. - if (it1 != eim.begin() && query_range.rva < it1->endpoint) - --it1; - imin = it1->index; - } - - // The first range that can't possibly intersect us is found by searching - // through the image map directly as it is already sorted by interval start - // point. - MappedRange q2 = { query_range.end(), 0 }; - Mapping::const_iterator it2 = std::lower_bound( - map.begin(), map.end(), q2, MappedRangeOriginalLess); - imax = it2 - map.begin(); - } - - // Find all intervals that intersect the query range. - Mapping temp_map; - for (size_t i = imin; i < imax; ++i) { - MappedRange mr = map[i]; - ClipMappedRangeOriginal(query_range, &mr); - if (mr.length + mr.injected > 0) - temp_map.push_back(mr); - } - - // If there are no intersecting ranges then the query range has been removed - // from the image in question. - if (temp_map.empty()) - return; - - // Sort based on transformed addresses. - std::sort(temp_map.begin(), temp_map.end(), MappedRangeMappedLess); - - // Zero-length queries can't actually be merged. We simply output the set of - // unique RVAs that correspond to the query RVA. - if (original_range.length == 0) { - mapped_ranges->push_back(AddressRange(temp_map[0].rva_transformed, 0)); - for (size_t i = 1; i < temp_map.size(); ++i) { - if (temp_map[i].rva_transformed > mapped_ranges->back().rva) - mapped_ranges->push_back(AddressRange(temp_map[i].rva_transformed, 0)); - } - return; - } - - // Merge any ranges that are consecutive in the mapped image. We merge over - // injected content if it makes ranges contiguous, but we ignore any injected - // content at the tail end of a range. This allows us to detect symbols that - // have been lengthened by injecting content in the middle. However, it - // misses the case where content has been injected at the head or the tail. - // The problem is that it doesn't know whether to attribute it to the - // preceding or following symbol. It is up to the author of the transform to - // output explicit OMAP info in these cases to ensure full coverage of the - // transformed address space. - DWORD rva_begin = temp_map[0].rva_transformed; - DWORD rva_cur_content = rva_begin + temp_map[0].length; - DWORD rva_cur_injected = rva_cur_content + temp_map[0].injected; - for (size_t i = 1; i < temp_map.size(); ++i) { - if (rva_cur_injected < temp_map[i].rva_transformed) { - // This marks the end of a continuous range in the image. Output the - // current range and start a new one. - if (rva_begin < rva_cur_content) { - mapped_ranges->push_back( - AddressRange(rva_begin, rva_cur_content - rva_begin)); - } - rva_begin = temp_map[i].rva_transformed; - } - - rva_cur_content = temp_map[i].rva_transformed + temp_map[i].length; - rva_cur_injected = rva_cur_content + temp_map[i].injected; - } - - // Output the range in progress. - if (rva_begin < rva_cur_content) { - mapped_ranges->push_back( - AddressRange(rva_begin, rva_cur_content - rva_begin)); - } - - return; -} - -} // namespace google_breakpad \ No newline at end of file diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/omap.h b/toolkit/crashreporter/google-breakpad/src/common/windows/omap.h deleted file mode 100644 index bc293afb5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/omap.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Provides an API for mapping symbols through OMAP information, if a PDB file -// is augmented with it. This allows breakpad to work with addresses in -// transformed images by transforming the symbols themselves, rather than -// transforming addresses prior to querying symbols (the way it is typically -// done by Windows-native tools, including the DIA). - -#ifndef COMMON_WINDOWS_OMAP_H_ -#define COMMON_WINDOWS_OMAP_H_ - -#include "common/windows/omap_internal.h" - -namespace google_breakpad { - -// If the given session contains OMAP data this extracts it, populating -// |omap_data|, and then disabling automatic translation for the session. -// OMAP data is present in the PDB if |omap_data| is not empty. This returns -// true on success, false otherwise. -bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session, - OmapData* omap_data); - -// Given raw OMAP data builds an ImageMap. This can be used to query individual -// image ranges using MapAddressRange. -// |omap_data|| is the OMAP data extracted from the PDB. -// |image_map| will be populated with a description of the image mapping. If -// |omap_data| is empty then this will also be empty. -void BuildImageMap(const OmapData& omap_data, ImageMap* image_map); - -// Given an address range in the original image space determines how exactly it -// has been tranformed. -// |omap_data| is the OMAP data extracted from the PDB, which must not be -// empty. -// |original_range| is the address range in the original image being queried. -// |mapped_ranges| will be populated with a full description of the mapping. -// They may be disjoint in the transformed image so a vector is needed to -// fully represent the mapping. This will be appended to if it is not -// empty. If |omap_data| is empty then |mapped_ranges| will simply be -// populated with a copy of |original_range| (the identity transform). -void MapAddressRange(const ImageMap& image_map, - const AddressRange& original_range, - AddressRangeVector* mapped_ranges); - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_OMAP_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/omap_internal.h b/toolkit/crashreporter/google-breakpad/src/common/windows/omap_internal.h deleted file mode 100644 index 3f904d7a7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/omap_internal.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Declares internal implementation details for functionality in omap.h and -// omap.cc. - -#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H_ -#define COMMON_WINDOWS_OMAP_INTERNAL_H_ - -#include -#include - -#include - -namespace google_breakpad { - -// The OMAP struct is defined by debughlp.h, which doesn't play nicely with -// imagehlp.h. We simply redefine it. -struct OMAP { - DWORD rva; - DWORD rvaTo; -}; -static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure."); -typedef std::vector OmapTable; - -// This contains the OMAP data extracted from an image. -struct OmapData { - // The table of OMAP entries describing the transformation from the - // original image to the transformed image. - OmapTable omap_from; - // The table of OMAP entries describing the transformation from the - // instrumented image to the original image. - OmapTable omap_to; - // The length of the original untransformed image. - DWORD length_original; - - OmapData() : length_original(0) { } -}; - -// This represents a range of addresses in an image. -struct AddressRange { - DWORD rva; - DWORD length; - - AddressRange() : rva(0), length(0) { } - AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { } - - // Returns the end address of this range. - DWORD end() const { return rva + length; } - - // Addreses only compare as less-than or greater-than if they are not - // overlapping. Otherwise, they compare equal. - int Compare(const AddressRange& rhs) const; - bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; } - bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; } - - // Equality operators compare exact values. - bool operator==(const AddressRange& rhs) const { - return rva == rhs.rva && length == rhs.length; - } - bool operator!=(const AddressRange& rhs) const { return !((*this) == rhs); } -}; - -typedef std::vector AddressRangeVector; - -// This represents an address range in an original image, and its corresponding -// range in the transformed image. -struct MappedRange { - // An address in the original image. - DWORD rva_original; - // The corresponding addresses in the transformed image. - DWORD rva_transformed; - // The length of the address range. - DWORD length; - // It is possible for code to be injected into a transformed image, for which - // there is no corresponding code in the original image. If this range of - // transformed image is immediately followed by such injected code we maintain - // a record of its length here. - DWORD injected; - // It is possible for code to be removed from the original image. This happens - // for things like padding between blocks. There is no actual content lost, - // but the spacing between items may be lost. This keeps track of any removed - // content immediately following the |original| range. - DWORD removed; -}; -// A vector of mapped ranges is used as a more useful representation of -// OMAP data. -typedef std::vector Mapping; - -// Used as a secondary search structure accompanying a Mapping. -struct EndpointIndex { - DWORD endpoint; - size_t index; -}; -typedef std::vector EndpointIndexMap; - -// An ImageMap is vector of mapped ranges, plus a secondary index into it for -// doing interval searches. (An interval tree would also work, but is overkill -// because we don't need insertion and deletion.) -struct ImageMap { - // This is a description of the mapping between original and transformed - // image, sorted by addresses in the original image. - Mapping mapping; - // For all interval endpoints in |mapping| this stores the minimum index of - // an interval in |mapping| that contains the endpoint. Useful for doing - // interval intersection queries. - EndpointIndexMap endpoint_index_map; -}; - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_OMAP_INTERNAL_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/omap_unittest.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/omap_unittest.cc deleted file mode 100644 index 960a33f46..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/omap_unittest.cc +++ /dev/null @@ -1,330 +0,0 @@ -// Copyright 2013 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unittests for OMAP related functions. - -#include "common/windows/omap.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace google_breakpad { - -// Equality operators for ContainerEq. These must be outside of the anonymous -// namespace in order for them to be found. -bool operator==(const MappedRange& mr1, const MappedRange& mr2) { - return mr1.rva_original == mr2.rva_original && - mr1.rva_transformed == mr2.rva_transformed && - mr1.length == mr2.length && - mr1.injected == mr2.injected && - mr1.removed == mr2.removed; -} -bool operator==(const EndpointIndex& ei1, const EndpointIndex& ei2) { - return ei1.endpoint == ei2.endpoint && ei1.index == ei2.index; -} - -// Pretty printers for more meaningful error messages. Also need to be outside -// the anonymous namespace. -std::ostream& operator<<(std::ostream& os, const MappedRange& mr) { - os << "MappedRange(rva_original=" << mr.rva_original - << ", rva_transformed=" << mr.rva_transformed - << ", length=" << mr.length - << ", injected=" << mr.injected - << ", removed=" << mr.removed << ")"; - return os; -} -std::ostream& operator<<(std::ostream& os, const EndpointIndex& ei) { - os << "EndpointIndex(endpoint=" << ei.endpoint - << ", index=" << ei.index << ")"; - return os; -} -std::ostream& operator<<(std::ostream& os, const AddressRange& ar) { - os << "AddressRange(rva=" << ar.rva << ", length=" << ar.length << ")"; - return os; -} - -namespace { - -OMAP CreateOmap(DWORD rva, DWORD rvaTo) { - OMAP o = { rva, rvaTo }; - return o; -} - -MappedRange CreateMappedRange(DWORD rva_original, - DWORD rva_transformed, - DWORD length, - DWORD injected, - DWORD removed) { - MappedRange mr = { rva_original, rva_transformed, length, injected, removed }; - return mr; -} - -EndpointIndex CreateEndpointIndex(DWORD endpoint, size_t index) { - EndpointIndex ei = { endpoint, index }; - return ei; -} - -// (C is removed) -// Original : A B C D E F G H -// Transformed: A B D F E * H1 G1 G2 H2 -// (* is injected, G is copied, H is split) -// A is implied. - -// Layout of the original image. -const AddressRange B(100, 15); -const AddressRange C(B.end(), 10); -const AddressRange D(C.end(), 25); -const AddressRange E(D.end(), 10); -const AddressRange F(E.end(), 40); -const AddressRange G(F.end(), 3); -const AddressRange H(G.end(), 7); - -// Layout of the transformed image. -const AddressRange Bt(100, 15); -const AddressRange Dt(Bt.end(), 20); // D is shortened. -const AddressRange Ft(Dt.end(), F.length); -const AddressRange Et(Ft.end(), E.length); -const AddressRange injected(Et.end(), 5); -const AddressRange H1t(injected.end(), 4); // H is split. -const AddressRange G1t(H1t.end(), G.length); // G is copied. -const AddressRange G2t(G1t.end(), G.length); // G is copied. -const AddressRange H2t(G2t.end(), 3); // H is split. - -class BuildImageMapTest : public testing::Test { - public: - static const DWORD kInvalidAddress = 0xFFFFFFFF; - - void InitOmapData() { - omap_data.length_original = H.end(); - - // Build the OMAPTO vector (from transformed to original). - omap_data.omap_to.push_back(CreateOmap(Bt.rva, B.rva)); - omap_data.omap_to.push_back(CreateOmap(Dt.rva, D.rva)); - omap_data.omap_to.push_back(CreateOmap(Ft.rva, F.rva)); - omap_data.omap_to.push_back(CreateOmap(Et.rva, E.rva)); - omap_data.omap_to.push_back(CreateOmap(injected.rva, kInvalidAddress)); - omap_data.omap_to.push_back(CreateOmap(H1t.rva, H.rva)); - omap_data.omap_to.push_back(CreateOmap(G1t.rva, G.rva)); - omap_data.omap_to.push_back(CreateOmap(G2t.rva, G.rva)); - omap_data.omap_to.push_back(CreateOmap(H2t.rva, H.rva + H1t.length)); - omap_data.omap_to.push_back(CreateOmap(H2t.end(), kInvalidAddress)); - - // Build the OMAPFROM vector (from original to transformed). - omap_data.omap_from.push_back(CreateOmap(B.rva, Bt.rva)); - omap_data.omap_from.push_back(CreateOmap(C.rva, kInvalidAddress)); - omap_data.omap_from.push_back(CreateOmap(D.rva, Dt.rva)); - omap_data.omap_from.push_back(CreateOmap(E.rva, Et.rva)); - omap_data.omap_from.push_back(CreateOmap(F.rva, Ft.rva)); - omap_data.omap_from.push_back(CreateOmap(G.rva, G1t.rva)); - omap_data.omap_from.push_back(CreateOmap(H.rva, H1t.rva)); - omap_data.omap_from.push_back(CreateOmap(H.rva + H1t.length, H2t.rva)); - omap_data.omap_from.push_back(CreateOmap(H.end(), kInvalidAddress)); - } - - OmapData omap_data; -}; - -} // namespace - -TEST_F(BuildImageMapTest, EmptyImageMapOnEmptyOmapData) { - ASSERT_EQ(0u, omap_data.omap_from.size()); - ASSERT_EQ(0u, omap_data.omap_to.size()); - ASSERT_EQ(0u, omap_data.length_original); - - ImageMap image_map; - BuildImageMap(omap_data, &image_map); - EXPECT_EQ(0u, image_map.mapping.size()); - EXPECT_EQ(0u, image_map.endpoint_index_map.size()); -} - -TEST_F(BuildImageMapTest, ImageMapIsCorrect) { - InitOmapData(); - ASSERT_LE(0u, omap_data.omap_from.size()); - ASSERT_LE(0u, omap_data.omap_to.size()); - ASSERT_LE(0u, omap_data.length_original); - - ImageMap image_map; - BuildImageMap(omap_data, &image_map); - EXPECT_LE(9u, image_map.mapping.size()); - EXPECT_LE(9u, image_map.endpoint_index_map.size()); - - Mapping mapping; - mapping.push_back(CreateMappedRange(0, 0, B.rva, 0, 0)); - // C is removed, and it originally comes immediately after B. - mapping.push_back(CreateMappedRange(B.rva, Bt.rva, B.length, 0, C.length)); - // D is shortened by a length of 5. - mapping.push_back(CreateMappedRange(D.rva, Dt.rva, Dt.length, 0, 5)); - // The injected content comes immediately after E in the transformed image. - mapping.push_back(CreateMappedRange(E.rva, Et.rva, E.length, injected.length, - 0)); - mapping.push_back(CreateMappedRange(F.rva, Ft.rva, F.length, 0, 0)); - // G is copied so creates two entries. - mapping.push_back(CreateMappedRange(G.rva, G1t.rva, G.length, 0, 0)); - mapping.push_back(CreateMappedRange(G.rva, G2t.rva, G.length, 0, 0)); - // H is split, so create two entries. - mapping.push_back(CreateMappedRange(H.rva, H1t.rva, H1t.length, 0, 0)); - mapping.push_back(CreateMappedRange(H.rva + H1t.length, H2t.rva, H2t.length, - 0, 0)); - EXPECT_THAT(mapping, - testing::ContainerEq(image_map.mapping)); - - EndpointIndexMap endpoint_index_map; - endpoint_index_map.push_back(CreateEndpointIndex(0, 0)); - endpoint_index_map.push_back(CreateEndpointIndex(B.rva, 1)); - endpoint_index_map.push_back(CreateEndpointIndex(D.rva, 2)); - endpoint_index_map.push_back(CreateEndpointIndex(E.rva, 3)); - endpoint_index_map.push_back(CreateEndpointIndex(F.rva, 4)); - // G is duplicated so 2 ranges map back to it, hence the skip from 5 to 7. - endpoint_index_map.push_back(CreateEndpointIndex(G.rva, 5)); - // H is split so we expect 2 endpoints to show up attributed to it. - endpoint_index_map.push_back(CreateEndpointIndex(H.rva, 7)); - endpoint_index_map.push_back(CreateEndpointIndex(H.rva + H1t.length, 8)); - endpoint_index_map.push_back(CreateEndpointIndex(H.end(), 9)); - EXPECT_THAT(endpoint_index_map, - testing::ContainerEq(image_map.endpoint_index_map)); -} - -namespace { - -class MapAddressRangeTest : public BuildImageMapTest { - public: - typedef BuildImageMapTest Super; - virtual void SetUp() { - Super::SetUp(); - InitOmapData(); - BuildImageMap(omap_data, &image_map); - } - - ImageMap image_map; - - private: - using BuildImageMapTest::InitOmapData; - using BuildImageMapTest::omap_data; -}; - -} // namespace - -TEST_F(MapAddressRangeTest, EmptyImageMapReturnsIdentity) { - ImageMap im; - AddressRangeVector mapped_ranges; - AddressRange ar(0, 1024); - MapAddressRange(im, ar, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - EXPECT_EQ(ar, mapped_ranges[0]); -} - -TEST_F(MapAddressRangeTest, MapOutOfImage) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, AddressRange(H.end() + 10, 10), &mapped_ranges); - EXPECT_EQ(0u, mapped_ranges.size()); -} - -TEST_F(MapAddressRangeTest, MapIdentity) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, B, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(B)); -} - -TEST_F(MapAddressRangeTest, MapReorderedContiguous) { - AddressRangeVector mapped_ranges; - - AddressRange DEF(D.rva, F.end() - D.rva); - MapAddressRange(image_map, DEF, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - - AddressRange DFEt(Dt.rva, Et.end() - Dt.rva); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(DFEt)); -} - -TEST_F(MapAddressRangeTest, MapEmptySingle) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, AddressRange(D.rva, 0), &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(AddressRange(Dt.rva, 0))); -} - -TEST_F(MapAddressRangeTest, MapEmptyCopied) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, AddressRange(G.rva, 0), &mapped_ranges); - EXPECT_EQ(2u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(AddressRange(G1t.rva, 0), - AddressRange(G2t.rva, 0))); -} - -TEST_F(MapAddressRangeTest, MapCopiedContiguous) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, G, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre( - AddressRange(G1t.rva, G2t.end() - G1t.rva))); -} - -TEST_F(MapAddressRangeTest, MapSplitDiscontiguous) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, H, &mapped_ranges); - EXPECT_EQ(2u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(H1t, H2t)); -} - -TEST_F(MapAddressRangeTest, MapInjected) { - AddressRangeVector mapped_ranges; - - AddressRange EFGH(E.rva, H.end() - E.rva); - MapAddressRange(image_map, EFGH, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - - AddressRange FEHGGHt(Ft.rva, H2t.end() - Ft.rva); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(FEHGGHt)); -} - -TEST_F(MapAddressRangeTest, MapRemovedEntirely) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, C, &mapped_ranges); - EXPECT_EQ(0u, mapped_ranges.size()); -} - -TEST_F(MapAddressRangeTest, MapRemovedPartly) { - AddressRangeVector mapped_ranges; - MapAddressRange(image_map, D, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(Dt)); -} - -TEST_F(MapAddressRangeTest, MapFull) { - AddressRangeVector mapped_ranges; - - AddressRange AH(0, H.end()); - MapAddressRange(image_map, AH, &mapped_ranges); - EXPECT_EQ(1u, mapped_ranges.size()); - - AddressRange AHt(0, H2t.end()); - EXPECT_THAT(mapped_ranges, testing::ElementsAre(AHt)); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.cc deleted file mode 100644 index 01f4ce3b7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.cc +++ /dev/null @@ -1,1369 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/windows/pdb_source_line_writer.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common/windows/dia_util.h" -#include "common/windows/guid_string.h" -#include "common/windows/string_utils-inl.h" - -// This constant may be missing from DbgHelp.h. See the documentation for -// IDiaSymbol::get_undecoratedNameEx. -#ifndef UNDNAME_NO_ECSU -#define UNDNAME_NO_ECSU 0x8000 // Suppresses enum/class/struct/union. -#endif // UNDNAME_NO_ECSU - -/* - * Not defined in WinNT.h for some reason. Definitions taken from: - * http://uninformed.org/index.cgi?v=4&a=1&p=13 - * - */ -typedef unsigned char UBYTE; - -#if !defined(_WIN64) -#define UNW_FLAG_EHANDLER 0x01 -#define UNW_FLAG_UHANDLER 0x02 -#define UNW_FLAG_CHAININFO 0x04 -#endif - -union UnwindCode { - struct { - UBYTE offset_in_prolog; - UBYTE unwind_operation_code : 4; - UBYTE operation_info : 4; - }; - USHORT frame_offset; -}; - -enum UnwindOperationCodes { - UWOP_PUSH_NONVOL = 0, /* info == register number */ - UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */ - UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */ - UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */ - UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */ - UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */ - // XXX: these are missing from MSDN! - // See: http://www.osronline.com/ddkx/kmarch/64bitamd_4rs7.htm - UWOP_SAVE_XMM, - UWOP_SAVE_XMM_FAR, - UWOP_SAVE_XMM128, /* info == XMM reg number, offset in next slot */ - UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */ - UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */ -}; - -// See: http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx -// Note: some fields removed as we don't use them. -struct UnwindInfo { - UBYTE version : 3; - UBYTE flags : 5; - UBYTE size_of_prolog; - UBYTE count_of_codes; - UBYTE frame_register : 4; - UBYTE frame_offset : 4; - UnwindCode unwind_code[1]; -}; - -namespace google_breakpad { - -namespace { - -using std::vector; - -// A helper class to scope a PLOADED_IMAGE. -class AutoImage { - public: - explicit AutoImage(PLOADED_IMAGE img) : img_(img) {} - ~AutoImage() { - if (img_) - ImageUnload(img_); - } - - operator PLOADED_IMAGE() { return img_; } - PLOADED_IMAGE operator->() { return img_; } - - private: - PLOADED_IMAGE img_; -}; - -bool CreateDiaDataSourceInstance(CComPtr &data_source) { - if (SUCCEEDED(data_source.CoCreateInstance(CLSID_DiaSource))) { - return true; - } - - class DECLSPEC_UUID("B86AE24D-BF2F-4ac9-B5A2-34B14E4CE11D") DiaSource100; - class DECLSPEC_UUID("761D3BCD-1304-41D5-94E8-EAC54E4AC172") DiaSource110; - class DECLSPEC_UUID("3BFCEA48-620F-4B6B-81F7-B9AF75454C7D") DiaSource120; - class DECLSPEC_UUID("E6756135-1E65-4D17-8576-610761398C3C") DiaSource140; - - // If the CoCreateInstance call above failed, msdia*.dll is not registered. - // We can try loading the DLL corresponding to the #included DIA SDK, but - // the DIA headers don't provide a version. Lets try to figure out which DIA - // version we're compiling against by comparing CLSIDs. - const wchar_t *msdia_dll = nullptr; - if (CLSID_DiaSource == _uuidof(DiaSource100)) { - msdia_dll = L"msdia100.dll"; - } else if (CLSID_DiaSource == _uuidof(DiaSource110)) { - msdia_dll = L"msdia110.dll"; - } else if (CLSID_DiaSource == _uuidof(DiaSource120)) { - msdia_dll = L"msdia120.dll"; - } else if (CLSID_DiaSource == _uuidof(DiaSource140)) { - msdia_dll = L"msdia140.dll"; - } - - if (msdia_dll && - SUCCEEDED(NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource, - reinterpret_cast(&data_source)))) { - return true; - } - - return false; -} - -} // namespace - -PDBSourceLineWriter::PDBSourceLineWriter() : output_(NULL) { -} - -PDBSourceLineWriter::~PDBSourceLineWriter() { -} - -bool PDBSourceLineWriter::SetCodeFile(const wstring &exe_file) { - if (code_file_.empty()) { - code_file_ = exe_file; - return true; - } - // Setting a different code file path is an error. It is success only if the - // file paths are the same. - return exe_file == code_file_; -} - -bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) { - Close(); - code_file_.clear(); - - if (FAILED(CoInitialize(NULL))) { - fprintf(stderr, "CoInitialize failed\n"); - return false; - } - - CComPtr data_source; - if (!CreateDiaDataSourceInstance(data_source)) { - const int kGuidSize = 64; - wchar_t classid[kGuidSize] = {0}; - StringFromGUID2(CLSID_DiaSource, classid, kGuidSize); - fprintf(stderr, "CoCreateInstance CLSID_DiaSource %S failed " - "(msdia*.dll unregistered?)\n", classid); - return false; - } - - switch (format) { - case PDB_FILE: - if (FAILED(data_source->loadDataFromPdb(file.c_str()))) { - fprintf(stderr, "loadDataFromPdb failed for %ws\n", file.c_str()); - return false; - } - break; - case EXE_FILE: - if (FAILED(data_source->loadDataForExe(file.c_str(), NULL, NULL))) { - fprintf(stderr, "loadDataForExe failed for %ws\n", file.c_str()); - return false; - } - code_file_ = file; - break; - case ANY_FILE: - if (FAILED(data_source->loadDataFromPdb(file.c_str()))) { - if (FAILED(data_source->loadDataForExe(file.c_str(), NULL, NULL))) { - fprintf(stderr, "loadDataForPdb and loadDataFromExe failed for %ws\n", - file.c_str()); - return false; - } - code_file_ = file; - } - break; - default: - fprintf(stderr, "Unknown file format\n"); - return false; - } - - if (FAILED(data_source->openSession(&session_))) { - fprintf(stderr, "openSession failed\n"); - } - - return true; -} - -bool PDBSourceLineWriter::PrintLines(IDiaEnumLineNumbers *lines) { - // The line number format is: - // - CComPtr line; - ULONG count; - - while (SUCCEEDED(lines->Next(1, &line, &count)) && count == 1) { - DWORD rva; - if (FAILED(line->get_relativeVirtualAddress(&rva))) { - fprintf(stderr, "failed to get line rva\n"); - return false; - } - - DWORD length; - if (FAILED(line->get_length(&length))) { - fprintf(stderr, "failed to get line code length\n"); - return false; - } - - DWORD dia_source_id; - if (FAILED(line->get_sourceFileId(&dia_source_id))) { - fprintf(stderr, "failed to get line source file id\n"); - return false; - } - // duplicate file names are coalesced to share one ID - DWORD source_id = GetRealFileID(dia_source_id); - - DWORD line_num; - if (FAILED(line->get_lineNumber(&line_num))) { - fprintf(stderr, "failed to get line number\n"); - return false; - } - - AddressRangeVector ranges; - MapAddressRange(image_map_, AddressRange(rva, length), &ranges); - for (size_t i = 0; i < ranges.size(); ++i) { - fprintf(output_, "%x %x %d %d\n", ranges[i].rva, ranges[i].length, - line_num, source_id); - } - line.Release(); - } - return true; -} - -bool PDBSourceLineWriter::PrintFunction(IDiaSymbol *function, - IDiaSymbol *block) { - // The function format is: - // FUNC
- DWORD rva; - if (FAILED(block->get_relativeVirtualAddress(&rva))) { - fprintf(stderr, "couldn't get rva\n"); - return false; - } - - ULONGLONG length; - if (FAILED(block->get_length(&length))) { - fprintf(stderr, "failed to get function length\n"); - return false; - } - - if (length == 0) { - // Silently ignore zero-length functions, which can infrequently pop up. - return true; - } - - CComBSTR name; - int stack_param_size; - if (!GetSymbolFunctionName(function, &name, &stack_param_size)) { - return false; - } - - // If the decorated name didn't give the parameter size, try to - // calculate it. - if (stack_param_size < 0) { - stack_param_size = GetFunctionStackParamSize(function); - } - - AddressRangeVector ranges; - MapAddressRange(image_map_, AddressRange(rva, static_cast(length)), - &ranges); - for (size_t i = 0; i < ranges.size(); ++i) { - fprintf(output_, "FUNC %x %x %x %ws\n", - ranges[i].rva, ranges[i].length, stack_param_size, - name.m_str); - } - - CComPtr lines; - if (FAILED(session_->findLinesByRVA(rva, DWORD(length), &lines))) { - return false; - } - - if (!PrintLines(lines)) { - return false; - } - return true; -} - -bool PDBSourceLineWriter::PrintSourceFiles() { - CComPtr global; - if (FAILED(session_->get_globalScope(&global))) { - fprintf(stderr, "get_globalScope failed\n"); - return false; - } - - CComPtr compilands; - if (FAILED(global->findChildren(SymTagCompiland, NULL, - nsNone, &compilands))) { - fprintf(stderr, "findChildren failed\n"); - return false; - } - - CComPtr compiland; - ULONG count; - while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) { - CComPtr source_files; - if (FAILED(session_->findFile(compiland, NULL, nsNone, &source_files))) { - return false; - } - CComPtr file; - while (SUCCEEDED(source_files->Next(1, &file, &count)) && count == 1) { - DWORD file_id; - if (FAILED(file->get_uniqueId(&file_id))) { - return false; - } - - CComBSTR file_name; - if (FAILED(file->get_fileName(&file_name))) { - return false; - } - - wstring file_name_string(file_name); - if (!FileIDIsCached(file_name_string)) { - // this is a new file name, cache it and output a FILE line. - CacheFileID(file_name_string, file_id); - fwprintf(output_, L"FILE %d %ws\n", file_id, file_name_string.c_str()); - } else { - // this file name has already been seen, just save this - // ID for later lookup. - StoreDuplicateFileID(file_name_string, file_id); - } - file.Release(); - } - compiland.Release(); - } - return true; -} - -bool PDBSourceLineWriter::PrintFunctions() { - ULONG count = 0; - DWORD rva = 0; - CComPtr global; - HRESULT hr; - - if (FAILED(session_->get_globalScope(&global))) { - fprintf(stderr, "get_globalScope failed\n"); - return false; - } - - CComPtr symbols = NULL; - - // Find all function symbols first. - std::set rvas; - hr = global->findChildren(SymTagFunction, NULL, nsNone, &symbols); - - if (SUCCEEDED(hr)) { - CComPtr symbol = NULL; - - while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) { - if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) { - // To maintain existing behavior of one symbol per address, place the - // rva onto a set here to uniquify them. - rvas.insert(rva); - } else { - fprintf(stderr, "get_relativeVirtualAddress failed on the symbol\n"); - return false; - } - - symbol.Release(); - } - - symbols.Release(); - } - - // Find all public symbols. Store public symbols that are not also private - // symbols for later. - std::set public_only_rvas; - hr = global->findChildren(SymTagPublicSymbol, NULL, nsNone, &symbols); - - if (SUCCEEDED(hr)) { - CComPtr symbol = NULL; - - while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) { - if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) { - if (rvas.count(rva) == 0) { - rvas.insert(rva); // Keep symbols in rva order. - public_only_rvas.insert(rva); - } - } else { - fprintf(stderr, "get_relativeVirtualAddress failed on the symbol\n"); - return false; - } - - symbol.Release(); - } - - symbols.Release(); - } - - std::set::iterator it; - - // For each rva, dump the first symbol DIA knows about at the address. - for (it = rvas.begin(); it != rvas.end(); ++it) { - CComPtr symbol = NULL; - // If the symbol is not in the public list, look for SymTagFunction. This is - // a workaround to a bug where DIA will hang if searching for a private - // symbol at an address where only a public symbol exists. - // See http://connect.microsoft.com/VisualStudio/feedback/details/722366 - if (public_only_rvas.count(*it) == 0) { - if (SUCCEEDED(session_->findSymbolByRVA(*it, SymTagFunction, &symbol))) { - // Sometimes findSymbolByRVA returns S_OK, but NULL. - if (symbol) { - if (!PrintFunction(symbol, symbol)) - return false; - symbol.Release(); - } - } else { - fprintf(stderr, "findSymbolByRVA SymTagFunction failed\n"); - return false; - } - } else if (SUCCEEDED(session_->findSymbolByRVA(*it, - SymTagPublicSymbol, - &symbol))) { - // Sometimes findSymbolByRVA returns S_OK, but NULL. - if (symbol) { - if (!PrintCodePublicSymbol(symbol)) - return false; - symbol.Release(); - } - } else { - fprintf(stderr, "findSymbolByRVA SymTagPublicSymbol failed\n"); - return false; - } - } - - // When building with PGO, the compiler can split functions into - // "hot" and "cold" blocks, and move the "cold" blocks out to separate - // pages, so the function can be noncontiguous. To find these blocks, - // we have to iterate over all the compilands, and then find blocks - // that are children of them. We can then find the lexical parents - // of those blocks and print out an extra FUNC line for blocks - // that are not contained in their parent functions. - CComPtr compilands; - if (FAILED(global->findChildren(SymTagCompiland, NULL, - nsNone, &compilands))) { - fprintf(stderr, "findChildren failed on the global\n"); - return false; - } - - CComPtr compiland; - while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) { - CComPtr blocks; - if (FAILED(compiland->findChildren(SymTagBlock, NULL, - nsNone, &blocks))) { - fprintf(stderr, "findChildren failed on a compiland\n"); - return false; - } - - CComPtr block; - while (SUCCEEDED(blocks->Next(1, &block, &count)) && count == 1) { - // find this block's lexical parent function - CComPtr parent; - DWORD tag; - if (SUCCEEDED(block->get_lexicalParent(&parent)) && - SUCCEEDED(parent->get_symTag(&tag)) && - tag == SymTagFunction) { - // now get the block's offset and the function's offset and size, - // and determine if the block is outside of the function - DWORD func_rva, block_rva; - ULONGLONG func_length; - if (SUCCEEDED(block->get_relativeVirtualAddress(&block_rva)) && - SUCCEEDED(parent->get_relativeVirtualAddress(&func_rva)) && - SUCCEEDED(parent->get_length(&func_length))) { - if (block_rva < func_rva || block_rva > (func_rva + func_length)) { - if (!PrintFunction(parent, block)) { - return false; - } - } - } - } - parent.Release(); - block.Release(); - } - blocks.Release(); - compiland.Release(); - } - - global.Release(); - return true; -} - -#undef max - -bool PDBSourceLineWriter::PrintFrameDataUsingPDB() { - // It would be nice if it were possible to output frame data alongside the - // associated function, as is done with line numbers, but the DIA API - // doesn't make it possible to get the frame data in that way. - - CComPtr frame_data_enum; - if (!FindTable(session_, &frame_data_enum)) - return false; - - DWORD last_type = std::numeric_limits::max(); - DWORD last_rva = std::numeric_limits::max(); - DWORD last_code_size = 0; - DWORD last_prolog_size = std::numeric_limits::max(); - - CComPtr frame_data; - ULONG count = 0; - while (SUCCEEDED(frame_data_enum->Next(1, &frame_data, &count)) && - count == 1) { - DWORD type; - if (FAILED(frame_data->get_type(&type))) - return false; - - DWORD rva; - if (FAILED(frame_data->get_relativeVirtualAddress(&rva))) - return false; - - DWORD code_size; - if (FAILED(frame_data->get_lengthBlock(&code_size))) - return false; - - DWORD prolog_size; - if (FAILED(frame_data->get_lengthProlog(&prolog_size))) - return false; - - // parameter_size is the size of parameters passed on the stack. If any - // parameters are not passed on the stack (such as in registers), their - // sizes will not be included in parameter_size. - DWORD parameter_size; - if (FAILED(frame_data->get_lengthParams(¶meter_size))) - return false; - - DWORD saved_register_size; - if (FAILED(frame_data->get_lengthSavedRegisters(&saved_register_size))) - return false; - - DWORD local_size; - if (FAILED(frame_data->get_lengthLocals(&local_size))) - return false; - - // get_maxStack can return S_FALSE, just use 0 in that case. - DWORD max_stack_size = 0; - if (FAILED(frame_data->get_maxStack(&max_stack_size))) - return false; - - // get_programString can return S_FALSE, indicating that there is no - // program string. In that case, check whether %ebp is used. - HRESULT program_string_result; - CComBSTR program_string; - if (FAILED(program_string_result = frame_data->get_program( - &program_string))) { - return false; - } - - // get_allocatesBasePointer can return S_FALSE, treat that as though - // %ebp is not used. - BOOL allocates_base_pointer = FALSE; - if (program_string_result != S_OK) { - if (FAILED(frame_data->get_allocatesBasePointer( - &allocates_base_pointer))) { - return false; - } - } - - // Only print out a line if type, rva, code_size, or prolog_size have - // changed from the last line. It is surprisingly common (especially in - // system library PDBs) for DIA to return a series of identical - // IDiaFrameData objects. For kernel32.pdb from Windows XP SP2 on x86, - // this check reduces the size of the dumped symbol file by a third. - if (type != last_type || rva != last_rva || code_size != last_code_size || - prolog_size != last_prolog_size) { - // The prolog and the code portions of the frame have to be treated - // independently as they may have independently changed in size, or may - // even have been split. - // NOTE: If epilog size is ever non-zero, we have to do something - // similar with it. - - // Figure out where the prolog bytes have landed. - AddressRangeVector prolog_ranges; - if (prolog_size > 0) { - MapAddressRange(image_map_, AddressRange(rva, prolog_size), - &prolog_ranges); - } - - // And figure out where the code bytes have landed. - AddressRangeVector code_ranges; - MapAddressRange(image_map_, - AddressRange(rva + prolog_size, - code_size - prolog_size), - &code_ranges); - - struct FrameInfo { - DWORD rva; - DWORD code_size; - DWORD prolog_size; - }; - std::vector frame_infos; - - // Special case: The prolog and the code bytes remain contiguous. This is - // only done for compactness of the symbol file, and we could actually - // be outputting independent frame info for the prolog and code portions. - if (prolog_ranges.size() == 1 && code_ranges.size() == 1 && - prolog_ranges[0].end() == code_ranges[0].rva) { - FrameInfo fi = { prolog_ranges[0].rva, - prolog_ranges[0].length + code_ranges[0].length, - prolog_ranges[0].length }; - frame_infos.push_back(fi); - } else { - // Otherwise we output the prolog and code frame info independently. - for (size_t i = 0; i < prolog_ranges.size(); ++i) { - FrameInfo fi = { prolog_ranges[i].rva, - prolog_ranges[i].length, - prolog_ranges[i].length }; - frame_infos.push_back(fi); - } - for (size_t i = 0; i < code_ranges.size(); ++i) { - FrameInfo fi = { code_ranges[i].rva, code_ranges[i].length, 0 }; - frame_infos.push_back(fi); - } - } - - for (size_t i = 0; i < frame_infos.size(); ++i) { - const FrameInfo& fi(frame_infos[i]); - fprintf(output_, "STACK WIN %x %x %x %x %x %x %x %x %x %d ", - type, fi.rva, fi.code_size, fi.prolog_size, - 0 /* epilog_size */, parameter_size, saved_register_size, - local_size, max_stack_size, program_string_result == S_OK); - if (program_string_result == S_OK) { - fprintf(output_, "%ws\n", program_string.m_str); - } else { - fprintf(output_, "%d\n", allocates_base_pointer); - } - } - - last_type = type; - last_rva = rva; - last_code_size = code_size; - last_prolog_size = prolog_size; - } - - frame_data.Release(); - } - - return true; -} - -bool PDBSourceLineWriter::PrintFrameDataUsingEXE() { - if (code_file_.empty() && !FindPEFile()) { - fprintf(stderr, "Couldn't locate EXE or DLL file.\n"); - return false; - } - - // Convert wchar to native charset because ImageLoad only takes - // a PSTR as input. - string code_file; - if (!WindowsStringUtils::safe_wcstombs(code_file_, &code_file)) { - return false; - } - - AutoImage img(ImageLoad((PSTR)code_file.c_str(), NULL)); - if (!img) { - fprintf(stderr, "Failed to load %s\n", code_file.c_str()); - return false; - } - PIMAGE_OPTIONAL_HEADER64 optional_header = - &(reinterpret_cast(img->FileHeader))->OptionalHeader; - if (optional_header->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - fprintf(stderr, "Not a PE32+ image\n"); - return false; - } - - // Read Exception Directory - DWORD exception_rva = optional_header-> - DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress; - DWORD exception_size = optional_header-> - DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size; - PIMAGE_RUNTIME_FUNCTION_ENTRY funcs = - static_cast( - ImageRvaToVa(img->FileHeader, - img->MappedAddress, - exception_rva, - &img->LastRvaSection)); - for (DWORD i = 0; i < exception_size / sizeof(*funcs); i++) { - DWORD unwind_rva = funcs[i].UnwindInfoAddress; - // handle chaining - while (unwind_rva & 0x1) { - unwind_rva ^= 0x1; - PIMAGE_RUNTIME_FUNCTION_ENTRY chained_func = - static_cast( - ImageRvaToVa(img->FileHeader, - img->MappedAddress, - unwind_rva, - &img->LastRvaSection)); - unwind_rva = chained_func->UnwindInfoAddress; - } - - UnwindInfo *unwind_info = static_cast( - ImageRvaToVa(img->FileHeader, - img->MappedAddress, - unwind_rva, - &img->LastRvaSection)); - - DWORD stack_size = 8; // minimal stack size is 8 for RIP - DWORD rip_offset = 8; - do { - for (UBYTE c = 0; c < unwind_info->count_of_codes; c++) { - UnwindCode *unwind_code = &unwind_info->unwind_code[c]; - switch (unwind_code->unwind_operation_code) { - case UWOP_PUSH_NONVOL: { - stack_size += 8; - break; - } - case UWOP_ALLOC_LARGE: { - if (unwind_code->operation_info == 0) { - c++; - if (c < unwind_info->count_of_codes) - stack_size += (unwind_code + 1)->frame_offset * 8; - } else { - c += 2; - if (c < unwind_info->count_of_codes) - stack_size += (unwind_code + 1)->frame_offset | - ((unwind_code + 2)->frame_offset << 16); - } - break; - } - case UWOP_ALLOC_SMALL: { - stack_size += unwind_code->operation_info * 8 + 8; - break; - } - case UWOP_SET_FPREG: - case UWOP_SAVE_XMM: - case UWOP_SAVE_XMM_FAR: - break; - case UWOP_SAVE_NONVOL: - case UWOP_SAVE_XMM128: { - c++; // skip slot with offset - break; - } - case UWOP_SAVE_NONVOL_FAR: - case UWOP_SAVE_XMM128_FAR: { - c += 2; // skip 2 slots with offset - break; - } - case UWOP_PUSH_MACHFRAME: { - if (unwind_code->operation_info) { - stack_size += 88; - } else { - stack_size += 80; - } - rip_offset += 80; - break; - } - } - } - if (unwind_info->flags & UNW_FLAG_CHAININFO) { - PIMAGE_RUNTIME_FUNCTION_ENTRY chained_func = - reinterpret_cast( - (unwind_info->unwind_code + - ((unwind_info->count_of_codes + 1) & ~1))); - - unwind_info = static_cast( - ImageRvaToVa(img->FileHeader, - img->MappedAddress, - chained_func->UnwindInfoAddress, - &img->LastRvaSection)); - } else { - unwind_info = NULL; - } - } while (unwind_info); - fprintf(output_, "STACK CFI INIT %x %x .cfa: $rsp .ra: .cfa %d - ^\n", - funcs[i].BeginAddress, - funcs[i].EndAddress - funcs[i].BeginAddress, rip_offset); - fprintf(output_, "STACK CFI %x .cfa: $rsp %d +\n", - funcs[i].BeginAddress, stack_size); - } - - return true; -} - -bool PDBSourceLineWriter::PrintFrameData() { - PDBModuleInfo info; - if (GetModuleInfo(&info) && info.cpu == L"x86_64") { - return PrintFrameDataUsingEXE(); - } else { - return PrintFrameDataUsingPDB(); - } - return false; -} - -bool PDBSourceLineWriter::PrintCodePublicSymbol(IDiaSymbol *symbol) { - BOOL is_code; - if (FAILED(symbol->get_code(&is_code))) { - return false; - } - if (!is_code) { - return true; - } - - DWORD rva; - if (FAILED(symbol->get_relativeVirtualAddress(&rva))) { - return false; - } - - CComBSTR name; - int stack_param_size; - if (!GetSymbolFunctionName(symbol, &name, &stack_param_size)) { - return false; - } - - AddressRangeVector ranges; - MapAddressRange(image_map_, AddressRange(rva, 1), &ranges); - for (size_t i = 0; i < ranges.size(); ++i) { - fprintf(output_, "PUBLIC %x %x %ws\n", ranges[i].rva, - stack_param_size > 0 ? stack_param_size : 0, - name.m_str); - } - return true; -} - -bool PDBSourceLineWriter::PrintPDBInfo() { - PDBModuleInfo info; - if (!GetModuleInfo(&info)) { - return false; - } - - // Hard-code "windows" for the OS because that's the only thing that makes - // sense for PDB files. (This might not be strictly correct for Windows CE - // support, but we don't care about that at the moment.) - fprintf(output_, "MODULE windows %ws %ws %ws\n", - info.cpu.c_str(), info.debug_identifier.c_str(), - info.debug_file.c_str()); - - return true; -} - -bool PDBSourceLineWriter::PrintPEInfo() { - PEModuleInfo info; - if (!GetPEInfo(&info)) { - return false; - } - - fprintf(output_, "INFO CODE_ID %ws %ws\n", - info.code_identifier.c_str(), - info.code_file.c_str()); - return true; -} - -// wcstol_positive_strict is sort of like wcstol, but much stricter. string -// should be a buffer pointing to a null-terminated string containing only -// decimal digits. If the entire string can be converted to an integer -// without overflowing, and there are no non-digit characters before the -// result is set to the value and this function returns true. Otherwise, -// this function returns false. This is an alternative to the strtol, atoi, -// and scanf families, which are not as strict about input and in some cases -// don't provide a good way for the caller to determine if a conversion was -// successful. -static bool wcstol_positive_strict(wchar_t *string, int *result) { - int value = 0; - for (wchar_t *c = string; *c != '\0'; ++c) { - int last_value = value; - value *= 10; - // Detect overflow. - if (value / 10 != last_value || value < 0) { - return false; - } - if (*c < '0' || *c > '9') { - return false; - } - unsigned int c_value = *c - '0'; - last_value = value; - value += c_value; - // Detect overflow. - if (value < last_value) { - return false; - } - // Forbid leading zeroes unless the string is just "0". - if (value == 0 && *(c+1) != '\0') { - return false; - } - } - *result = value; - return true; -} - -bool PDBSourceLineWriter::FindPEFile() { - CComPtr global; - if (FAILED(session_->get_globalScope(&global))) { - fprintf(stderr, "get_globalScope failed\n"); - return false; - } - - CComBSTR symbols_file; - if (SUCCEEDED(global->get_symbolsFileName(&symbols_file))) { - wstring file(symbols_file); - - // Look for an EXE or DLL file. - const wchar_t *extensions[] = { L"exe", L"dll" }; - for (int i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) { - size_t dot_pos = file.find_last_of(L"."); - if (dot_pos != wstring::npos) { - file.replace(dot_pos + 1, wstring::npos, extensions[i]); - // Check if this file exists. - if (GetFileAttributesW(file.c_str()) != INVALID_FILE_ATTRIBUTES) { - code_file_ = file; - return true; - } - } - } - } - - return false; -} - -// static -bool PDBSourceLineWriter::GetSymbolFunctionName(IDiaSymbol *function, - BSTR *name, - int *stack_param_size) { - *stack_param_size = -1; - const DWORD undecorate_options = UNDNAME_NO_MS_KEYWORDS | - UNDNAME_NO_FUNCTION_RETURNS | - UNDNAME_NO_ALLOCATION_MODEL | - UNDNAME_NO_ALLOCATION_LANGUAGE | - UNDNAME_NO_THISTYPE | - UNDNAME_NO_ACCESS_SPECIFIERS | - UNDNAME_NO_THROW_SIGNATURES | - UNDNAME_NO_MEMBER_TYPE | - UNDNAME_NO_RETURN_UDT_MODEL | - UNDNAME_NO_ECSU; - - // Use get_undecoratedNameEx to get readable C++ names with arguments. - if (function->get_undecoratedNameEx(undecorate_options, name) != S_OK) { - if (function->get_name(name) != S_OK) { - fprintf(stderr, "failed to get function name\n"); - return false; - } - - // It's possible for get_name to return an empty string, so - // special-case that. - if (wcscmp(*name, L"") == 0) { - SysFreeString(*name); - // dwarf_cu_to_module.cc uses "", so match that. - *name = SysAllocString(L""); - return true; - } - - // If a name comes from get_name because no undecorated form existed, - // it's already formatted properly to be used as output. Don't do any - // additional processing. - // - // MSVC7's DIA seems to not undecorate names in as many cases as MSVC8's. - // This will result in calling get_name for some C++ symbols, so - // all of the parameter and return type information may not be included in - // the name string. - } else { - // C++ uses a bogus "void" argument for functions and methods that don't - // take any parameters. Take it out of the undecorated name because it's - // ugly and unnecessary. - const wchar_t *replace_string = L"(void)"; - const size_t replace_length = wcslen(replace_string); - const wchar_t *replacement_string = L"()"; - size_t length = wcslen(*name); - if (length >= replace_length) { - wchar_t *name_end = *name + length - replace_length; - if (wcscmp(name_end, replace_string) == 0) { - WindowsStringUtils::safe_wcscpy(name_end, replace_length, - replacement_string); - length = wcslen(*name); - } - } - - // Undecorate names used for stdcall and fastcall. These names prefix - // the identifier with '_' (stdcall) or '@' (fastcall) and suffix it - // with '@' followed by the number of bytes of parameters, in decimal. - // If such a name is found, take note of the size and undecorate it. - // Only do this for names that aren't C++, which is determined based on - // whether the undecorated name contains any ':' or '(' characters. - if (!wcschr(*name, ':') && !wcschr(*name, '(') && - (*name[0] == '_' || *name[0] == '@')) { - wchar_t *last_at = wcsrchr(*name + 1, '@'); - if (last_at && wcstol_positive_strict(last_at + 1, stack_param_size)) { - // If this function adheres to the fastcall convention, it accepts up - // to the first 8 bytes of parameters in registers (%ecx and %edx). - // We're only interested in the stack space used for parameters, so - // so subtract 8 and don't let the size go below 0. - if (*name[0] == '@') { - if (*stack_param_size > 8) { - *stack_param_size -= 8; - } else { - *stack_param_size = 0; - } - } - - // Undecorate the name by moving it one character to the left in its - // buffer, and terminating it where the last '@' had been. - WindowsStringUtils::safe_wcsncpy(*name, length, - *name + 1, last_at - *name - 1); - } else if (*name[0] == '_') { - // This symbol's name is encoded according to the cdecl rules. The - // name doesn't end in a '@' character followed by a decimal positive - // integer, so it's not a stdcall name. Strip off the leading - // underscore. - WindowsStringUtils::safe_wcsncpy(*name, length, *name + 1, length); - } - } - } - - return true; -} - -// static -int PDBSourceLineWriter::GetFunctionStackParamSize(IDiaSymbol *function) { - // This implementation is highly x86-specific. - - // Gather the symbols corresponding to data. - CComPtr data_children; - if (FAILED(function->findChildren(SymTagData, NULL, nsNone, - &data_children))) { - return 0; - } - - // lowest_base is the lowest %ebp-relative byte offset used for a parameter. - // highest_end is one greater than the highest offset (i.e. base + length). - // Stack parameters are assumed to be contiguous, because in reality, they - // are. - int lowest_base = INT_MAX; - int highest_end = INT_MIN; - - CComPtr child; - DWORD count; - while (SUCCEEDED(data_children->Next(1, &child, &count)) && count == 1) { - // If any operation fails at this point, just proceed to the next child. - // Use the next_child label instead of continue because child needs to - // be released before it's reused. Declare constructable/destructable - // types early to avoid gotos that cross initializations. - CComPtr child_type; - - // DataIsObjectPtr is only used for |this|. Because |this| can be passed - // as a stack parameter, look for it in addition to traditional - // parameters. - DWORD child_kind; - if (FAILED(child->get_dataKind(&child_kind)) || - (child_kind != DataIsParam && child_kind != DataIsObjectPtr)) { - goto next_child; - } - - // Only concentrate on register-relative parameters. Parameters may also - // be enregistered (passed directly in a register), but those don't - // consume any stack space, so they're not of interest. - DWORD child_location_type; - if (FAILED(child->get_locationType(&child_location_type)) || - child_location_type != LocIsRegRel) { - goto next_child; - } - - // Of register-relative parameters, the only ones that make any sense are - // %ebp- or %esp-relative. Note that MSVC's debugging information always - // gives parameters as %ebp-relative even when a function doesn't use a - // traditional frame pointer and stack parameters are accessed relative to - // %esp, so just look for %ebp-relative parameters. If you wanted to - // access parameters, you'd probably want to treat these %ebp-relative - // offsets as if they were relative to %esp before a function's prolog - // executed. - DWORD child_register; - if (FAILED(child->get_registerId(&child_register)) || - child_register != CV_REG_EBP) { - goto next_child; - } - - LONG child_register_offset; - if (FAILED(child->get_offset(&child_register_offset))) { - goto next_child; - } - - // IDiaSymbol::get_type can succeed but still pass back a NULL value. - if (FAILED(child->get_type(&child_type)) || !child_type) { - goto next_child; - } - - ULONGLONG child_length; - if (FAILED(child_type->get_length(&child_length))) { - goto next_child; - } - - int child_end = child_register_offset + static_cast(child_length); - if (child_register_offset < lowest_base) { - lowest_base = child_register_offset; - } - if (child_end > highest_end) { - highest_end = child_end; - } - -next_child: - child.Release(); - } - - int param_size = 0; - // Make sure lowest_base isn't less than 4, because [%esp+4] is the lowest - // possible address to find a stack parameter before executing a function's - // prolog (see above). Some optimizations cause parameter offsets to be - // lower than 4, but we're not concerned with those because we're only - // looking for parameters contained in addresses higher than where the - // return address is stored. - if (lowest_base < 4) { - lowest_base = 4; - } - if (highest_end > lowest_base) { - // All stack parameters are pushed as at least 4-byte quantities. If the - // last type was narrower than 4 bytes, promote it. This assumes that all - // parameters' offsets are 4-byte-aligned, which is always the case. Only - // worry about the last type, because we're not summing the type sizes, - // just looking at the lowest and highest offsets. - int remainder = highest_end % 4; - if (remainder) { - highest_end += 4 - remainder; - } - - param_size = highest_end - lowest_base; - } - - return param_size; -} - -bool PDBSourceLineWriter::WriteMap(FILE *map_file) { - output_ = map_file; - - // Load the OMAP information, and disable auto-translation of addresses in - // preference of doing it ourselves. - OmapData omap_data; - if (!GetOmapDataAndDisableTranslation(session_, &omap_data)) - return false; - BuildImageMap(omap_data, &image_map_); - - bool ret = PrintPDBInfo(); - // This is not a critical piece of the symbol file. - PrintPEInfo(); - ret = ret && - PrintSourceFiles() && - PrintFunctions() && - PrintFrameData(); - - output_ = NULL; - return ret; -} - -void PDBSourceLineWriter::Close() { - session_.Release(); -} - -bool PDBSourceLineWriter::GetModuleInfo(PDBModuleInfo *info) { - if (!info) { - return false; - } - - info->debug_file.clear(); - info->debug_identifier.clear(); - info->cpu.clear(); - - CComPtr global; - if (FAILED(session_->get_globalScope(&global))) { - return false; - } - - DWORD machine_type; - // get_machineType can return S_FALSE. - if (global->get_machineType(&machine_type) == S_OK) { - // The documentation claims that get_machineType returns a value from - // the CV_CPU_TYPE_e enumeration, but that's not the case. - // Instead, it returns one of the IMAGE_FILE_MACHINE values as - // defined here: - // http://msdn.microsoft.com/en-us/library/ms680313%28VS.85%29.aspx - switch (machine_type) { - case IMAGE_FILE_MACHINE_I386: - info->cpu = L"x86"; - break; - case IMAGE_FILE_MACHINE_AMD64: - info->cpu = L"x86_64"; - break; - default: - info->cpu = L"unknown"; - break; - } - } else { - // Unexpected, but handle gracefully. - info->cpu = L"unknown"; - } - - // DWORD* and int* are not compatible. This is clean and avoids a cast. - DWORD age; - if (FAILED(global->get_age(&age))) { - return false; - } - - bool uses_guid; - if (!UsesGUID(&uses_guid)) { - return false; - } - - if (uses_guid) { - GUID guid; - if (FAILED(global->get_guid(&guid))) { - return false; - } - - // Use the same format that the MS symbol server uses in filesystem - // hierarchies. - wchar_t age_string[9]; - swprintf(age_string, sizeof(age_string) / sizeof(age_string[0]), - L"%x", age); - - // remove when VC++7.1 is no longer supported - age_string[sizeof(age_string) / sizeof(age_string[0]) - 1] = L'\0'; - - info->debug_identifier = GUIDString::GUIDToSymbolServerWString(&guid); - info->debug_identifier.append(age_string); - } else { - DWORD signature; - if (FAILED(global->get_signature(&signature))) { - return false; - } - - // Use the same format that the MS symbol server uses in filesystem - // hierarchies. - wchar_t identifier_string[17]; - swprintf(identifier_string, - sizeof(identifier_string) / sizeof(identifier_string[0]), - L"%08X%x", signature, age); - - // remove when VC++7.1 is no longer supported - identifier_string[sizeof(identifier_string) / - sizeof(identifier_string[0]) - 1] = L'\0'; - - info->debug_identifier = identifier_string; - } - - CComBSTR debug_file_string; - if (FAILED(global->get_symbolsFileName(&debug_file_string))) { - return false; - } - info->debug_file = - WindowsStringUtils::GetBaseName(wstring(debug_file_string)); - - return true; -} - -bool PDBSourceLineWriter::GetPEInfo(PEModuleInfo *info) { - if (!info) { - return false; - } - - if (code_file_.empty() && !FindPEFile()) { - fprintf(stderr, "Couldn't locate EXE or DLL file.\n"); - return false; - } - - // Convert wchar to native charset because ImageLoad only takes - // a PSTR as input. - string code_file; - if (!WindowsStringUtils::safe_wcstombs(code_file_, &code_file)) { - return false; - } - - AutoImage img(ImageLoad((PSTR)code_file.c_str(), NULL)); - if (!img) { - fprintf(stderr, "Failed to open PE file: %s\n", code_file.c_str()); - return false; - } - - info->code_file = WindowsStringUtils::GetBaseName(code_file_); - - // The date and time that the file was created by the linker. - DWORD TimeDateStamp = img->FileHeader->FileHeader.TimeDateStamp; - // The size of the file in bytes, including all headers. - DWORD SizeOfImage = 0; - PIMAGE_OPTIONAL_HEADER64 opt = - &((PIMAGE_NT_HEADERS64)img->FileHeader)->OptionalHeader; - if (opt->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // 64-bit PE file. - SizeOfImage = opt->SizeOfImage; - } else { - // 32-bit PE file. - SizeOfImage = img->FileHeader->OptionalHeader.SizeOfImage; - } - wchar_t code_identifier[32]; - swprintf(code_identifier, - sizeof(code_identifier) / sizeof(code_identifier[0]), - L"%08X%X", TimeDateStamp, SizeOfImage); - info->code_identifier = code_identifier; - - return true; -} - -bool PDBSourceLineWriter::UsesGUID(bool *uses_guid) { - if (!uses_guid) - return false; - - CComPtr global; - if (FAILED(session_->get_globalScope(&global))) - return false; - - GUID guid; - if (FAILED(global->get_guid(&guid))) - return false; - - DWORD signature; - if (FAILED(global->get_signature(&signature))) - return false; - - // There are two possibilities for guid: either it's a real 128-bit GUID - // as identified in a code module by a new-style CodeView record, or it's - // a 32-bit signature (timestamp) as identified by an old-style record. - // See MDCVInfoPDB70 and MDCVInfoPDB20 in minidump_format.h. - // - // Because DIA doesn't provide a way to directly determine whether a module - // uses a GUID or a 32-bit signature, this code checks whether the first 32 - // bits of guid are the same as the signature, and if the rest of guid is - // zero. If so, then with a pretty high degree of certainty, there's an - // old-style CodeView record in use. This method will only falsely find an - // an old-style CodeView record if a real 128-bit GUID has its first 32 - // bits set the same as the module's signature (timestamp) and the rest of - // the GUID is set to 0. This is highly unlikely. - - GUID signature_guid = {signature}; // 0-initializes other members - *uses_guid = !IsEqualGUID(guid, signature_guid); - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.h b/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.h deleted file mode 100644 index e9e89bb27..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.h +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output -// a line/address map for use with BasicSourceLineResolver. - -#ifndef COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ -#define COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ - -#include - -#include -#include - -#include "common/windows/omap.h" - -struct IDiaEnumLineNumbers; -struct IDiaSession; -struct IDiaSymbol; - -namespace google_breakpad { - -using std::wstring; -using std::unordered_map; - -// A structure that carries information that identifies a pdb file. -struct PDBModuleInfo { - public: - // The basename of the pdb file from which information was loaded. - wstring debug_file; - - // The pdb's identifier. For recent pdb files, the identifier consists - // of the pdb's guid, in uppercase hexadecimal form without any dashes - // or separators, followed immediately by the pdb's age, also in - // uppercase hexadecimal form. For older pdb files which have no guid, - // the identifier is the pdb's 32-bit signature value, in zero-padded - // hexadecimal form, followed immediately by the pdb's age, in lowercase - // hexadecimal form. - wstring debug_identifier; - - // A string identifying the cpu that the pdb is associated with. - // Currently, this may be "x86" or "unknown". - wstring cpu; -}; - -// A structure that carries information that identifies a PE file, -// either an EXE or a DLL. -struct PEModuleInfo { - // The basename of the PE file. - wstring code_file; - - // The PE file's code identifier, which consists of its timestamp - // and file size concatenated together into a single hex string. - // (The fields IMAGE_OPTIONAL_HEADER::SizeOfImage and - // IMAGE_FILE_HEADER::TimeDateStamp, as defined in the ImageHlp - // documentation.) This is not well documented, if it's documented - // at all, but it's what symstore does and what DbgHelp supports. - wstring code_identifier; -}; - -class PDBSourceLineWriter { - public: - enum FileFormat { - PDB_FILE, // a .pdb file containing debug symbols - EXE_FILE, // a .exe or .dll file - ANY_FILE // try PDB_FILE and then EXE_FILE - }; - - explicit PDBSourceLineWriter(); - ~PDBSourceLineWriter(); - - // Opens the given file. For executable files, the corresponding pdb - // file must be available; Open will be if it is not. - // If there is already a pdb file open, it is automatically closed. - // Returns true on success. - bool Open(const wstring &file, FileFormat format); - - // Sets the code file full path. This is optional for 32-bit modules. It is - // also optional for 64-bit modules when there is an executable file stored - // in the same directory as the PDB file. It is only required for 64-bit - // modules when the executable file is not in the same location as the PDB - // file and it must be called after Open() and before WriteMap(). - // If Open() was called for an executable file, then it is an error to call - // SetCodeFile() with a different file path and it will return false. - bool SetCodeFile(const wstring &exe_file); - - // Writes a map file from the current pdb file to the given file stream. - // Returns true on success. - bool WriteMap(FILE *map_file); - - // Closes the current pdb file and its associated resources. - void Close(); - - // Retrieves information about the module's debugging file. Returns - // true on success and false on failure. - bool GetModuleInfo(PDBModuleInfo *info); - - // Retrieves information about the module's PE file. Returns - // true on success and false on failure. - bool GetPEInfo(PEModuleInfo *info); - - // Sets uses_guid to true if the opened file uses a new-style CodeView - // record with a 128-bit GUID, or false if the opened file uses an old-style - // CodeView record. When no GUID is available, a 32-bit signature should be - // used to identify the module instead. If the information cannot be - // determined, this method returns false. - bool UsesGUID(bool *uses_guid); - - private: - // Outputs the line/address pairs for each line in the enumerator. - // Returns true on success. - bool PrintLines(IDiaEnumLineNumbers *lines); - - // Outputs a function address and name, followed by its source line list. - // block can be the same object as function, or it can be a reference - // to a code block that is lexically part of this function, but - // resides at a separate address. - // Returns true on success. - bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block); - - // Outputs all functions as described above. Returns true on success. - bool PrintFunctions(); - - // Outputs all of the source files in the session's pdb file. - // Returns true on success. - bool PrintSourceFiles(); - - // Outputs all of the frame information necessary to construct stack - // backtraces in the absence of frame pointers. For x86 data stored in - // .pdb files. Returns true on success. - bool PrintFrameDataUsingPDB(); - - // Outputs all of the frame information necessary to construct stack - // backtraces in the absence of frame pointers. For x64 data stored in - // .exe, .dll files. Returns true on success. - bool PrintFrameDataUsingEXE(); - - // Outputs all of the frame information necessary to construct stack - // backtraces in the absence of frame pointers. Returns true on success. - bool PrintFrameData(); - - // Outputs a single public symbol address and name, if the symbol corresponds - // to a code address. Returns true on success. If symbol is does not - // correspond to code, returns true without outputting anything. - bool PrintCodePublicSymbol(IDiaSymbol *symbol); - - // Outputs a line identifying the PDB file that is being dumped, along with - // its uuid and age. - bool PrintPDBInfo(); - - // Outputs a line identifying the PE file corresponding to the PDB - // file that is being dumped, along with its code identifier, - // which consists of its timestamp and file size. - bool PrintPEInfo(); - - // Returns true if this filename has already been seen, - // and an ID is stored for it, or false if it has not. - bool FileIDIsCached(const wstring &file) { - return unique_files_.find(file) != unique_files_.end(); - } - - // Cache this filename and ID for later reuse. - void CacheFileID(const wstring &file, DWORD id) { - unique_files_[file] = id; - } - - // Store this ID in the cache as a duplicate for this filename. - void StoreDuplicateFileID(const wstring &file, DWORD id) { - unordered_map::iterator iter = unique_files_.find(file); - if (iter != unique_files_.end()) { - // map this id to the previously seen one - file_ids_[id] = iter->second; - } - } - - // Given a file's unique ID, return the ID that should be used to - // reference it. There may be multiple files with identical filenames - // but different unique IDs. The cache attempts to coalesce these into - // one ID per unique filename. - DWORD GetRealFileID(DWORD id) { - unordered_map::iterator iter = file_ids_.find(id); - if (iter == file_ids_.end()) - return id; - return iter->second; - } - - // Find the PE file corresponding to the loaded PDB file, and - // set the code_file_ member. Returns false on failure. - bool FindPEFile(); - - // Returns the function name for a symbol. If possible, the name is - // undecorated. If the symbol's decorated form indicates the size of - // parameters on the stack, this information is returned in stack_param_size. - // Returns true on success. If the symbol doesn't encode parameter size - // information, stack_param_size is set to -1. - static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name, - int *stack_param_size); - - // Returns the number of bytes of stack space used for a function's - // parameters. function must have the tag SymTagFunction. In the event of - // a failure, returns 0, which is also a valid number of bytes. - static int GetFunctionStackParamSize(IDiaSymbol *function); - - // The filename of the PE file corresponding to the currently-open - // pdb file. - wstring code_file_; - - // The session for the currently-open pdb file. - CComPtr session_; - - // The current output file for this WriteMap invocation. - FILE *output_; - - // There may be many duplicate filenames with different IDs. - // This maps from the DIA "unique ID" to a single ID per unique - // filename. - unordered_map file_ids_; - // This maps unique filenames to file IDs. - unordered_map unique_files_; - - // This is used for calculating post-transform symbol addresses and lengths. - ImageMap image_map_; - - // Disallow copy ctor and operator= - PDBSourceLineWriter(const PDBSourceLineWriter&); - void operator=(const PDBSourceLineWriter&); -}; - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils-inl.h b/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils-inl.h deleted file mode 100644 index 9b6360726..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils-inl.h +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// string_utils-inl.h: Safer string manipulation on Windows, supporting -// pre-MSVC8 environments. - -#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H_ -#define COMMON_WINDOWS_STRING_UTILS_INL_H_ - -#include -#include - -#include - -// The "ll" printf format size specifier corresponding to |long long| was -// intrudced in MSVC8. Earlier versions did not provide this size specifier, -// but "I64" can be used to print 64-bit types. Don't use "I64" where "ll" -// is available, in the event of oddball systems where |long long| is not -// 64 bits wide. -#if _MSC_VER >= 1400 // MSVC 2005/8 -#define WIN_STRING_FORMAT_LL "ll" -#else // MSC_VER >= 1400 -#define WIN_STRING_FORMAT_LL "I64" -#endif // MSC_VER >= 1400 - -// A nonconforming version of swprintf, without the length argument, was -// included with the CRT prior to MSVC8. Although a conforming version was -// also available via an overload, it is not reliably chosen. _snwprintf -// behaves as a standards-confirming swprintf should, so force the use of -// _snwprintf when using older CRTs. -#if _MSC_VER < 1400 // MSVC 2005/8 -#define swprintf _snwprintf -#else -// For MSVC8 and newer, swprintf_s is the recommended method. Conveniently, -// it takes the same argument list as swprintf. -#define swprintf swprintf_s -#endif // MSC_VER < 1400 - -namespace google_breakpad { - -using std::string; -using std::wstring; - -class WindowsStringUtils { - public: - // Roughly equivalent to MSVC8's wcscpy_s, except pre-MSVC8, this does - // not fail if source is longer than destination_size. The destination - // buffer is always 0-terminated. - static void safe_wcscpy(wchar_t *destination, size_t destination_size, - const wchar_t *source); - - // Roughly equivalent to MSVC8's wcsncpy_s, except that _TRUNCATE cannot - // be passed directly, and pre-MSVC8, this will not fail if source or count - // are longer than destination_size. The destination buffer is always - // 0-terminated. - static void safe_wcsncpy(wchar_t *destination, size_t destination_size, - const wchar_t *source, size_t count); - - // Performs multi-byte to wide character conversion on C++ strings, using - // mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8). Returns false on failure, - // without setting wcs. - static bool safe_mbstowcs(const string &mbs, wstring *wcs); - - // The inverse of safe_mbstowcs. - static bool safe_wcstombs(const wstring &wcs, string *mbs); - - // Returns the base name of a file, e.g. strips off the path. - static wstring GetBaseName(const wstring &filename); - - private: - // Disallow instantiation and other object-based operations. - WindowsStringUtils(); - WindowsStringUtils(const WindowsStringUtils&); - ~WindowsStringUtils(); - void operator=(const WindowsStringUtils&); -}; - -// static -inline void WindowsStringUtils::safe_wcscpy(wchar_t *destination, - size_t destination_size, - const wchar_t *source) { -#if _MSC_VER >= 1400 // MSVC 2005/8 - wcscpy_s(destination, destination_size, source); -#else // _MSC_VER >= 1400 - // Pre-MSVC 2005/8 doesn't have wcscpy_s. Simulate it with wcsncpy. - // wcsncpy doesn't 0-terminate the destination buffer if the source string - // is longer than size. Ensure that the destination is 0-terminated. - wcsncpy(destination, source, destination_size); - if (destination && destination_size) - destination[destination_size - 1] = 0; -#endif // _MSC_VER >= 1400 -} - -// static -inline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination, - size_t destination_size, - const wchar_t *source, - size_t count) { -#if _MSC_VER >= 1400 // MSVC 2005/8 - wcsncpy_s(destination, destination_size, source, count); -#else // _MSC_VER >= 1400 - // Pre-MSVC 2005/8 doesn't have wcsncpy_s. Simulate it with wcsncpy. - // wcsncpy doesn't 0-terminate the destination buffer if the source string - // is longer than size. Ensure that the destination is 0-terminated. - if (destination_size < count) - count = destination_size; - - wcsncpy(destination, source, count); - if (destination && count) - destination[count - 1] = 0; -#endif // _MSC_VER >= 1400 -} - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_STRING_UTILS_INL_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils.cc b/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils.cc deleted file mode 100644 index 272800035..000000000 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/string_utils.cc +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include - -#include "common/windows/string_utils-inl.h" - -namespace google_breakpad { - -// static -wstring WindowsStringUtils::GetBaseName(const wstring &filename) { - wstring base_name(filename); - size_t slash_pos = base_name.find_last_of(L"/\\"); - if (slash_pos != wstring::npos) { - base_name.erase(0, slash_pos + 1); - } - return base_name; -} - -// static -bool WindowsStringUtils::safe_mbstowcs(const string &mbs, wstring *wcs) { - assert(wcs); - - // First, determine the length of the destination buffer. - size_t wcs_length; - -#if _MSC_VER >= 1400 // MSVC 2005/8 - errno_t err; - if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) { - return false; - } - assert(wcs_length > 0); -#else // _MSC_VER >= 1400 - if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) { - return false; - } - - // Leave space for the 0-terminator. - ++wcs_length; -#endif // _MSC_VER >= 1400 - - std::vector wcs_v(wcs_length); - - // Now, convert. -#if _MSC_VER >= 1400 // MSVC 2005/8 - if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(), - _TRUNCATE)) != 0) { - return false; - } -#else // _MSC_VER >= 1400 - if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) == (size_t)-1) { - return false; - } - - // Ensure presence of 0-terminator. - wcs_v[wcs_length - 1] = '\0'; -#endif // _MSC_VER >= 1400 - - *wcs = &wcs_v[0]; - return true; -} - -// static -bool WindowsStringUtils::safe_wcstombs(const wstring &wcs, string *mbs) { - assert(mbs); - - // First, determine the length of the destination buffer. - size_t mbs_length; - -#if _MSC_VER >= 1400 // MSVC 2005/8 - errno_t err; - if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) { - return false; - } - assert(mbs_length > 0); -#else // _MSC_VER >= 1400 - if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) { - return false; - } - - // Leave space for the 0-terminator. - ++mbs_length; -#endif // _MSC_VER >= 1400 - - std::vector mbs_v(mbs_length); - - // Now, convert. -#if _MSC_VER >= 1400 // MSVC 2005/8 - if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(), - _TRUNCATE)) != 0) { - return false; - } -#else // _MSC_VER >= 1400 - if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) == (size_t)-1) { - return false; - } - - // Ensure presence of 0-terminator. - mbs_v[mbs_length - 1] = '\0'; -#endif // _MSC_VER >= 1400 - - *mbs = &mbs_v[0]; - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/config.h.in b/toolkit/crashreporter/google-breakpad/src/config.h.in deleted file mode 100644 index ee6a67ad9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/config.h.in +++ /dev/null @@ -1,79 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_A_OUT_H - -/* define if the compiler supports basic C++11 syntax */ -#undef HAVE_CXX11 - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/breakpad_types.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/breakpad_types.h deleted file mode 100644 index d8828043f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/breakpad_types.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* breakpad_types.h: Precise-width types - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file ensures that types uintN_t are defined for N = 8, 16, 32, and - * 64. Types of precise widths are crucial to the task of writing data - * structures on one platform and reading them on another. - * - * Author: Mark Mentovai */ - -#ifndef GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__ -#define GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__ - -#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && \ - !defined(__STDC_FORMAT_MACROS) -#error "inttypes.h has already been included before this header file, but " -#error "without __STDC_FORMAT_MACROS defined." -#endif - -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif /* __STDC_FORMAT_MACROS */ -#include - -typedef struct { - uint64_t high; - uint64_t low; -} uint128_struct; - -typedef uint64_t breakpad_time_t; - -/* Try to get PRIx64 from inttypes.h, but if it's not defined, fall back to - * llx, which is the format string for "long long" - this is a 64-bit - * integral type on many systems. */ -#ifndef PRIx64 -#define PRIx64 "llx" -#endif /* !PRIx64 */ - -#endif /* GOOGLE_BREAKPAD_COMMON_BREAKPAD_TYPES_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_amd64.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_amd64.h deleted file mode 100644 index 4256706d7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_amd64.h +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on amd64. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by ensuring - * ensuring that all members are aligned on their natural boundaries. In - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Mark Mentovai - * Change to split into its own file: Neal Sidhwaney */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__ - - -/* - * AMD64 support, see WINNT.H - */ - -typedef struct { - uint16_t control_word; - uint16_t status_word; - uint8_t tag_word; - uint8_t reserved1; - uint16_t error_opcode; - uint32_t error_offset; - uint16_t error_selector; - uint16_t reserved2; - uint32_t data_offset; - uint16_t data_selector; - uint16_t reserved3; - uint32_t mx_csr; - uint32_t mx_csr_mask; - uint128_struct float_registers[8]; - uint128_struct xmm_registers[16]; - uint8_t reserved4[96]; -} MDXmmSaveArea32AMD64; /* XMM_SAVE_AREA32 */ - -#define MD_CONTEXT_AMD64_VR_COUNT 26 - -typedef struct { - /* - * Register parameter home addresses. - */ - uint64_t p1_home; - uint64_t p2_home; - uint64_t p3_home; - uint64_t p4_home; - uint64_t p5_home; - uint64_t p6_home; - - /* The next field determines the layout of the structure, and which parts - * of it are populated */ - uint32_t context_flags; - uint32_t mx_csr; - - /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ - uint16_t cs; - - /* The next 4 registers are included with MD_CONTEXT_AMD64_SEGMENTS */ - uint16_t ds; - uint16_t es; - uint16_t fs; - uint16_t gs; - - /* The next 2 registers are included with MD_CONTEXT_AMD64_CONTROL */ - uint16_t ss; - uint32_t eflags; - - /* The next 6 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */ - uint64_t dr0; - uint64_t dr1; - uint64_t dr2; - uint64_t dr3; - uint64_t dr6; - uint64_t dr7; - - /* The next 4 registers are included with MD_CONTEXT_AMD64_INTEGER */ - uint64_t rax; - uint64_t rcx; - uint64_t rdx; - uint64_t rbx; - - /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ - uint64_t rsp; - - /* The next 11 registers are included with MD_CONTEXT_AMD64_INTEGER */ - uint64_t rbp; - uint64_t rsi; - uint64_t rdi; - uint64_t r8; - uint64_t r9; - uint64_t r10; - uint64_t r11; - uint64_t r12; - uint64_t r13; - uint64_t r14; - uint64_t r15; - - /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ - uint64_t rip; - - /* The next set of registers are included with - * MD_CONTEXT_AMD64_FLOATING_POINT - */ - union { - MDXmmSaveArea32AMD64 flt_save; - struct { - uint128_struct header[2]; - uint128_struct legacy[8]; - uint128_struct xmm0; - uint128_struct xmm1; - uint128_struct xmm2; - uint128_struct xmm3; - uint128_struct xmm4; - uint128_struct xmm5; - uint128_struct xmm6; - uint128_struct xmm7; - uint128_struct xmm8; - uint128_struct xmm9; - uint128_struct xmm10; - uint128_struct xmm11; - uint128_struct xmm12; - uint128_struct xmm13; - uint128_struct xmm14; - uint128_struct xmm15; - } sse_registers; - }; - - uint128_struct vector_register[MD_CONTEXT_AMD64_VR_COUNT]; - uint64_t vector_control; - - /* The next 5 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */ - uint64_t debug_control; - uint64_t last_branch_to_rip; - uint64_t last_branch_from_rip; - uint64_t last_exception_to_rip; - uint64_t last_exception_from_rip; - -} MDRawContextAMD64; /* CONTEXT */ - -/* For (MDRawContextAMD64).context_flags. These values indicate the type of - * context stored in the structure. The high 24 bits identify the CPU, the - * low 8 bits identify the type of context saved. */ -#define MD_CONTEXT_AMD64 0x00100000 /* CONTEXT_AMD64 */ -#define MD_CONTEXT_AMD64_CONTROL (MD_CONTEXT_AMD64 | 0x00000001) - /* CONTEXT_CONTROL */ -#define MD_CONTEXT_AMD64_INTEGER (MD_CONTEXT_AMD64 | 0x00000002) - /* CONTEXT_INTEGER */ -#define MD_CONTEXT_AMD64_SEGMENTS (MD_CONTEXT_AMD64 | 0x00000004) - /* CONTEXT_SEGMENTS */ -#define MD_CONTEXT_AMD64_FLOATING_POINT (MD_CONTEXT_AMD64 | 0x00000008) - /* CONTEXT_FLOATING_POINT */ -#define MD_CONTEXT_AMD64_DEBUG_REGISTERS (MD_CONTEXT_AMD64 | 0x00000010) - /* CONTEXT_DEBUG_REGISTERS */ -#define MD_CONTEXT_AMD64_XSTATE (MD_CONTEXT_AMD64 | 0x00000040) - /* CONTEXT_XSTATE */ - -/* WinNT.h refers to CONTEXT_MMX_REGISTERS but doesn't appear to define it - * I think it really means CONTEXT_FLOATING_POINT. - */ - -#define MD_CONTEXT_AMD64_FULL (MD_CONTEXT_AMD64_CONTROL | \ - MD_CONTEXT_AMD64_INTEGER | \ - MD_CONTEXT_AMD64_FLOATING_POINT) - /* CONTEXT_FULL */ - -#define MD_CONTEXT_AMD64_ALL (MD_CONTEXT_AMD64_FULL | \ - MD_CONTEXT_AMD64_SEGMENTS | \ - MD_CONTEXT_X86_DEBUG_REGISTERS) - /* CONTEXT_ALL */ - - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_AMD64_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm.h deleted file mode 100644 index 6a7113833..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (c) 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on ARM. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by - * ensuring that all members are aligned on their natural boundaries. - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. - * - * Author: Julian Seward - */ - -/* - * ARM support - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__ - -#define MD_FLOATINGSAVEAREA_ARM_FPR_COUNT 32 -#define MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT 8 - -/* - * Note that these structures *do not* map directly to the CONTEXT - * structure defined in WinNT.h in the Windows Mobile SDK. That structure - * does not accomodate VFPv3, and I'm unsure if it was ever used in the - * wild anyway, as Windows CE only seems to produce "cedumps" which - * are not exactly minidumps. - */ -typedef struct { - uint64_t fpscr; /* FPU status register */ - - /* 32 64-bit floating point registers, d0 .. d31. */ - uint64_t regs[MD_FLOATINGSAVEAREA_ARM_FPR_COUNT]; - - /* Miscellaneous control words */ - uint32_t extra[MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT]; -} MDFloatingSaveAreaARM; - -#define MD_CONTEXT_ARM_GPR_COUNT 16 - -typedef struct { - /* The next field determines the layout of the structure, and which parts - * of it are populated - */ - uint32_t context_flags; - - /* 16 32-bit integer registers, r0 .. r15 - * Note the following fixed uses: - * r13 is the stack pointer - * r14 is the link register - * r15 is the program counter - */ - uint32_t iregs[MD_CONTEXT_ARM_GPR_COUNT]; - - /* CPSR (flags, basically): 32 bits: - bit 31 - N (negative) - bit 30 - Z (zero) - bit 29 - C (carry) - bit 28 - V (overflow) - bit 27 - Q (saturation flag, sticky) - All other fields -- ignore */ - uint32_t cpsr; - - /* The next field is included with MD_CONTEXT_ARM_FLOATING_POINT */ - MDFloatingSaveAreaARM float_save; - -} MDRawContextARM; - -/* Indices into iregs for registers with a dedicated or conventional - * purpose. - */ -enum MDARMRegisterNumbers { - MD_CONTEXT_ARM_REG_IOS_FP = 7, - MD_CONTEXT_ARM_REG_FP = 11, - MD_CONTEXT_ARM_REG_SP = 13, - MD_CONTEXT_ARM_REG_LR = 14, - MD_CONTEXT_ARM_REG_PC = 15 -}; - -/* For (MDRawContextARM).context_flags. These values indicate the type of - * context stored in the structure. */ -/* CONTEXT_ARM from the Windows CE 5.0 SDK. This value isn't correct - * because this bit can be used for flags. Presumably this value was - * never actually used in minidumps, but only in "CEDumps" which - * are a whole parallel minidump file format for Windows CE. - * Therefore, Breakpad defines its own value for ARM CPUs. - */ -#define MD_CONTEXT_ARM_OLD 0x00000040 -/* This value was chosen to avoid likely conflicts with MD_CONTEXT_* - * for other CPUs. */ -#define MD_CONTEXT_ARM 0x40000000 -#define MD_CONTEXT_ARM_INTEGER (MD_CONTEXT_ARM | 0x00000002) -#define MD_CONTEXT_ARM_FLOATING_POINT (MD_CONTEXT_ARM | 0x00000004) - -#define MD_CONTEXT_ARM_FULL (MD_CONTEXT_ARM_INTEGER | \ - MD_CONTEXT_ARM_FLOATING_POINT) - -#define MD_CONTEXT_ARM_ALL (MD_CONTEXT_ARM_INTEGER | \ - MD_CONTEXT_ARM_FLOATING_POINT) - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm64.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm64.h deleted file mode 100644 index 5ace0d9de..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_arm64.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright 2013 Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on ARM. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by - * ensuring that all members are aligned on their natural boundaries. - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. - * - * Author: Colin Blundell - */ - -/* - * ARM64 support - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM64_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM64_H__ - -#define MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT 32 - -typedef struct { - uint32_t fpsr; /* FPU status register */ - uint32_t fpcr; /* FPU control register */ - - /* 32 128-bit floating point registers, d0 .. d31. */ - uint128_struct regs[MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT]; -} MDFloatingSaveAreaARM64; - -#define MD_CONTEXT_ARM64_GPR_COUNT 33 - -/* Use the same 32-bit alignment when accessing this structure from 64-bit code - * as is used natively in 32-bit code. */ -#pragma pack(push, 4) - -typedef struct { - /* The next field determines the layout of the structure, and which parts - * of it are populated - */ - uint64_t context_flags; - - /* 33 64-bit integer registers, x0 .. x31 + the PC - * Note the following fixed uses: - * x29 is the frame pointer - * x30 is the link register - * x31 is the stack pointer - * The PC is effectively x32. - */ - uint64_t iregs[MD_CONTEXT_ARM64_GPR_COUNT]; - - /* CPSR (flags, basically): 32 bits: - bit 31 - N (negative) - bit 30 - Z (zero) - bit 29 - C (carry) - bit 28 - V (overflow) - bit 27 - Q (saturation flag, sticky) - All other fields -- ignore */ - uint32_t cpsr; - - /* The next field is included with MD_CONTEXT64_ARM_FLOATING_POINT */ - MDFloatingSaveAreaARM64 float_save; - -} MDRawContextARM64; - -#pragma pack(pop) - -/* Indices into iregs for registers with a dedicated or conventional - * purpose. - */ -enum MDARM64RegisterNumbers { - MD_CONTEXT_ARM64_REG_FP = 29, - MD_CONTEXT_ARM64_REG_LR = 30, - MD_CONTEXT_ARM64_REG_SP = 31, - MD_CONTEXT_ARM64_REG_PC = 32 -}; - -/* For (MDRawContextARM64).context_flags. These values indicate the type of - * context stored in the structure. MD_CONTEXT_ARM64 is Breakpad-defined. - * This value was chosen to avoid likely conflicts with MD_CONTEXT_* - * for other CPUs. */ -#define MD_CONTEXT_ARM64 0x80000000 -#define MD_CONTEXT_ARM64_INTEGER (MD_CONTEXT_ARM64 | 0x00000002) -#define MD_CONTEXT_ARM64_FLOATING_POINT (MD_CONTEXT_ARM64 | 0x00000004) - -#define MD_CONTEXT_ARM64_FULL (MD_CONTEXT_ARM64_INTEGER | \ - MD_CONTEXT_ARM64_FLOATING_POINT) - -#define MD_CONTEXT_ARM64_ALL (MD_CONTEXT_ARM64_INTEGER | \ - MD_CONTEXT_ARM64_FLOATING_POINT) - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_ARM64_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_mips.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_mips.h deleted file mode 100644 index f4e2b5891..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_mips.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (c) 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on MIPS. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by - * ensuring that all members are aligned on their natural boundaries. - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. - * - * Author: Chris Dearman - */ - -/* - * MIPS support - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__ - -#define MD_CONTEXT_MIPS_GPR_COUNT 32 -#define MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT 32 -#define MD_CONTEXT_MIPS_DSP_COUNT 3 - -/* - * Note that these structures *do not* map directly to the CONTEXT - * structure defined in WinNT.h in the Windows Mobile SDK. That structure - * does not accomodate VFPv3, and I'm unsure if it was ever used in the - * wild anyway, as Windows CE only seems to produce "cedumps" which - * are not exactly minidumps. - */ -typedef struct { - /* 32 64-bit floating point registers, f0..f31 */ - uint64_t regs[MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT]; - - uint32_t fpcsr; /* FPU status register. */ - uint32_t fir; /* FPU implementation register. */ -} MDFloatingSaveAreaMIPS; - -typedef struct { - /* The next field determines the layout of the structure, and which parts - * of it are populated. - */ - uint32_t context_flags; - uint32_t _pad0; - - /* 32 64-bit integer registers, r0..r31. - * Note the following fixed uses: - * r29 is the stack pointer. - * r31 is the return address. - */ - uint64_t iregs[MD_CONTEXT_MIPS_GPR_COUNT]; - - /* multiply/divide result. */ - uint64_t mdhi, mdlo; - - /* DSP accumulators. */ - uint32_t hi[MD_CONTEXT_MIPS_DSP_COUNT]; - uint32_t lo[MD_CONTEXT_MIPS_DSP_COUNT]; - uint32_t dsp_control; - uint32_t _pad1; - - uint64_t epc; - uint64_t badvaddr; - uint32_t status; - uint32_t cause; - - /* The next field is included with MD_CONTEXT_MIPS_FLOATING_POINT. */ - MDFloatingSaveAreaMIPS float_save; - -} MDRawContextMIPS; - -/* Indices into iregs for registers with a dedicated or conventional - * purpose. - */ -enum MDMIPSRegisterNumbers { - MD_CONTEXT_MIPS_REG_S0 = 16, - MD_CONTEXT_MIPS_REG_S1 = 17, - MD_CONTEXT_MIPS_REG_S2 = 18, - MD_CONTEXT_MIPS_REG_S3 = 19, - MD_CONTEXT_MIPS_REG_S4 = 20, - MD_CONTEXT_MIPS_REG_S5 = 21, - MD_CONTEXT_MIPS_REG_S6 = 22, - MD_CONTEXT_MIPS_REG_S7 = 23, - MD_CONTEXT_MIPS_REG_GP = 28, - MD_CONTEXT_MIPS_REG_SP = 29, - MD_CONTEXT_MIPS_REG_FP = 30, - MD_CONTEXT_MIPS_REG_RA = 31, -}; - -/* For (MDRawContextMIPS).context_flags. These values indicate the type of - * context stored in the structure. */ -/* CONTEXT_MIPS from the Windows CE 5.0 SDK. This value isn't correct - * because this bit can be used for flags. Presumably this value was - * never actually used in minidumps, but only in "CEDumps" which - * are a whole parallel minidump file format for Windows CE. - * Therefore, Breakpad defines its own value for MIPS CPUs. - */ -#define MD_CONTEXT_MIPS 0x00040000 -#define MD_CONTEXT_MIPS_INTEGER (MD_CONTEXT_MIPS | 0x00000002) -#define MD_CONTEXT_MIPS_FLOATING_POINT (MD_CONTEXT_MIPS | 0x00000004) -#define MD_CONTEXT_MIPS_DSP (MD_CONTEXT_MIPS | 0x00000008) - -#define MD_CONTEXT_MIPS_FULL (MD_CONTEXT_MIPS_INTEGER | \ - MD_CONTEXT_MIPS_FLOATING_POINT | \ - MD_CONTEXT_MIPS_DSP) - -#define MD_CONTEXT_MIPS_ALL (MD_CONTEXT_MIPS_INTEGER | \ - MD_CONTEXT_MIPS_FLOATING_POINT \ - MD_CONTEXT_MIPS_DSP) - -/** - * Breakpad defines for MIPS64 - */ -#define MD_CONTEXT_MIPS64 0x00080000 -#define MD_CONTEXT_MIPS64_INTEGER (MD_CONTEXT_MIPS64 | 0x00000002) -#define MD_CONTEXT_MIPS64_FLOATING_POINT (MD_CONTEXT_MIPS64 | 0x00000004) -#define MD_CONTEXT_MIPS64_DSP (MD_CONTEXT_MIPS64 | 0x00000008) - -#define MD_CONTEXT_MIPS64_FULL (MD_CONTEXT_MIPS64_INTEGER | \ - MD_CONTEXT_MIPS64_FLOATING_POINT | \ - MD_CONTEXT_MIPS64_DSP) - -#define MD_CONTEXT_MIPS64_ALL (MD_CONTEXT_MIPS64_INTEGER | \ - MD_CONTEXT_MIPS64_FLOATING_POINT \ - MD_CONTEXT_MIPS64_DSP) - -#endif // GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_MIPS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc.h deleted file mode 100644 index b24cc4243..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on ppc. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by ensuring - * ensuring that all members are aligned on their natural boundaries. In - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Mark Mentovai - * Change to split into its own file: Neal Sidhwaney */ - -/* - * Breakpad minidump extension for PowerPC support. Based on Darwin/Mac OS X' - * mach/ppc/_types.h - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__ - -#define MD_FLOATINGSAVEAREA_PPC_FPR_COUNT 32 - -typedef struct { - /* fpregs is a double[32] in mach/ppc/_types.h, but a uint64_t is used - * here for precise sizing. */ - uint64_t fpregs[MD_FLOATINGSAVEAREA_PPC_FPR_COUNT]; - uint32_t fpscr_pad; - uint32_t fpscr; /* Status/control */ -} MDFloatingSaveAreaPPC; /* Based on ppc_float_state */ - - -#define MD_VECTORSAVEAREA_PPC_VR_COUNT 32 - -typedef struct { - /* Vector registers (including vscr) are 128 bits, but mach/ppc/_types.h - * exposes them as four 32-bit quantities. */ - uint128_struct save_vr[MD_VECTORSAVEAREA_PPC_VR_COUNT]; - uint128_struct save_vscr; /* Status/control */ - uint32_t save_pad5[4]; - uint32_t save_vrvalid; /* Indicates which vector registers are saved */ - uint32_t save_pad6[7]; -} MDVectorSaveAreaPPC; /* ppc_vector_state */ - - -#define MD_CONTEXT_PPC_GPR_COUNT 32 - -/* Use the same 32-bit alignment when accessing this structure from 64-bit code - * as is used natively in 32-bit code. #pragma pack is a MSVC extension - * supported by gcc. */ -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#pragma pack(4) -#else -#pragma pack(push, 4) -#endif - -typedef struct { - /* context_flags is not present in ppc_thread_state, but it aids - * identification of MDRawContextPPC among other raw context types, - * and it guarantees alignment when we get to float_save. */ - uint32_t context_flags; - - uint32_t srr0; /* Machine status save/restore: stores pc - * (instruction) */ - uint32_t srr1; /* Machine status save/restore: stores msr - * (ps, program/machine state) */ - /* ppc_thread_state contains 32 fields, r0 .. r31. Here, an array is - * used for brevity. */ - uint32_t gpr[MD_CONTEXT_PPC_GPR_COUNT]; - uint32_t cr; /* Condition */ - uint32_t xer; /* Integer (fiXed-point) exception */ - uint32_t lr; /* Link */ - uint32_t ctr; /* Count */ - uint32_t mq; /* Multiply/Quotient (PPC 601, POWER only) */ - uint32_t vrsave; /* Vector save */ - - /* float_save and vector_save aren't present in ppc_thread_state, but - * are represented in separate structures that still define a thread's - * context. */ - MDFloatingSaveAreaPPC float_save; - MDVectorSaveAreaPPC vector_save; -} MDRawContextPPC; /* Based on ppc_thread_state */ - -/* Indices into gpr for registers with a dedicated or conventional purpose. */ -enum MDPPCRegisterNumbers { - MD_CONTEXT_PPC_REG_SP = 1 -}; - -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#pragma pack(0) -#else -#pragma pack(pop) -#endif - -/* For (MDRawContextPPC).context_flags. These values indicate the type of - * context stored in the structure. MD_CONTEXT_PPC is Breakpad-defined. Its - * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other - * CPUs. */ -#define MD_CONTEXT_PPC 0x20000000 -#define MD_CONTEXT_PPC_BASE (MD_CONTEXT_PPC | 0x00000001) -#define MD_CONTEXT_PPC_FLOATING_POINT (MD_CONTEXT_PPC | 0x00000008) -#define MD_CONTEXT_PPC_VECTOR (MD_CONTEXT_PPC | 0x00000020) - -#define MD_CONTEXT_PPC_FULL MD_CONTEXT_PPC_BASE -#define MD_CONTEXT_PPC_ALL (MD_CONTEXT_PPC_FULL | \ - MD_CONTEXT_PPC_FLOATING_POINT | \ - MD_CONTEXT_PPC_VECTOR) - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h deleted file mode 100644 index 61f419386..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_ppc64.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (c) 2008, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on ppc64. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by ensuring - * ensuring that all members are aligned on their natural boundaries. In - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Neal Sidhwaney */ - - -/* - * Breakpad minidump extension for PPC64 support. Based on Darwin/Mac OS X' - * mach/ppc/_types.h - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__ - -#include "minidump_cpu_ppc.h" - -// these types are the same in ppc64 & ppc -typedef MDFloatingSaveAreaPPC MDFloatingSaveAreaPPC64; -typedef MDVectorSaveAreaPPC MDVectorSaveAreaPPC64; - -#define MD_CONTEXT_PPC64_GPR_COUNT MD_CONTEXT_PPC_GPR_COUNT - -typedef struct { - /* context_flags is not present in ppc_thread_state, but it aids - * identification of MDRawContextPPC among other raw context types, - * and it guarantees alignment when we get to float_save. */ - uint64_t context_flags; - - uint64_t srr0; /* Machine status save/restore: stores pc - * (instruction) */ - uint64_t srr1; /* Machine status save/restore: stores msr - * (ps, program/machine state) */ - /* ppc_thread_state contains 32 fields, r0 .. r31. Here, an array is - * used for brevity. */ - uint64_t gpr[MD_CONTEXT_PPC64_GPR_COUNT]; - uint64_t cr; /* Condition */ - uint64_t xer; /* Integer (fiXed-point) exception */ - uint64_t lr; /* Link */ - uint64_t ctr; /* Count */ - uint64_t vrsave; /* Vector save */ - - /* float_save and vector_save aren't present in ppc_thread_state, but - * are represented in separate structures that still define a thread's - * context. */ - MDFloatingSaveAreaPPC float_save; - MDVectorSaveAreaPPC vector_save; -} MDRawContextPPC64; /* Based on ppc_thread_state */ - -/* Indices into gpr for registers with a dedicated or conventional purpose. */ -enum MDPPC64RegisterNumbers { - MD_CONTEXT_PPC64_REG_SP = 1 -}; - -/* For (MDRawContextPPC).context_flags. These values indicate the type of - * context stored in the structure. MD_CONTEXT_PPC is Breakpad-defined. Its - * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other - * CPUs. */ -#define MD_CONTEXT_PPC64 0x01000000 -#define MD_CONTEXT_PPC64_BASE (MD_CONTEXT_PPC64 | 0x00000001) -#define MD_CONTEXT_PPC64_FLOATING_POINT (MD_CONTEXT_PPC64 | 0x00000008) -#define MD_CONTEXT_PPC64_VECTOR (MD_CONTEXT_PPC64 | 0x00000020) - -#define MD_CONTEXT_PPC64_FULL MD_CONTEXT_PPC64_BASE -#define MD_CONTEXT_PPC64_ALL (MD_CONTEXT_PPC64_FULL | \ - MD_CONTEXT_PPC64_FLOATING_POINT | \ - MD_CONTEXT_PPC64_VECTOR) - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_PPC64_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_sparc.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_sparc.h deleted file mode 100644 index 95c08b174..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_sparc.h +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on sparc. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by ensuring - * ensuring that all members are aligned on their natural boundaries. In - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Mark Mentovai - * Change to split into its own file: Neal Sidhwaney */ - -/* - * SPARC support, see (solaris)sys/procfs_isa.h also - */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__ - -#define MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT 32 - -typedef struct { - - /* FPU floating point regs */ - uint64_t regs[MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT]; - - uint64_t filler; - uint64_t fsr; /* FPU status register */ -} MDFloatingSaveAreaSPARC; /* FLOATING_SAVE_AREA */ - -#define MD_CONTEXT_SPARC_GPR_COUNT 32 - -typedef struct { - /* The next field determines the layout of the structure, and which parts - * of it are populated - */ - uint32_t context_flags; - uint32_t flag_pad; - /* - * General register access (SPARC). - * Don't confuse definitions here with definitions in . - * Registers are 32 bits for ILP32, 64 bits for LP64. - * SPARC V7/V8 is for 32bit, SPARC V9 is for 64bit - */ - - /* 32 Integer working registers */ - - /* g_r[0-7] global registers(g0-g7) - * g_r[8-15] out registers(o0-o7) - * g_r[16-23] local registers(l0-l7) - * g_r[24-31] in registers(i0-i7) - */ - uint64_t g_r[MD_CONTEXT_SPARC_GPR_COUNT]; - - /* several control registers */ - - /* Processor State register(PSR) for SPARC V7/V8 - * Condition Code register (CCR) for SPARC V9 - */ - uint64_t ccr; - - uint64_t pc; /* Program Counter register (PC) */ - uint64_t npc; /* Next Program Counter register (nPC) */ - uint64_t y; /* Y register (Y) */ - - /* Address Space Identifier register (ASI) for SPARC V9 - * WIM for SPARC V7/V8 - */ - uint64_t asi; - - /* Floating-Point Registers State register (FPRS) for SPARC V9 - * TBR for for SPARC V7/V8 - */ - uint64_t fprs; - - /* The next field is included with MD_CONTEXT_SPARC_FLOATING_POINT */ - MDFloatingSaveAreaSPARC float_save; - -} MDRawContextSPARC; /* CONTEXT_SPARC */ - -/* Indices into g_r for registers with a dedicated or conventional purpose. */ -enum MDSPARCRegisterNumbers { - MD_CONTEXT_SPARC_REG_SP = 14 -}; - -/* For (MDRawContextSPARC).context_flags. These values indicate the type of - * context stored in the structure. MD_CONTEXT_SPARC is Breakpad-defined. Its - * value was chosen to avoid likely conflicts with MD_CONTEXT_* for other - * CPUs. */ -#define MD_CONTEXT_SPARC 0x10000000 -#define MD_CONTEXT_SPARC_CONTROL (MD_CONTEXT_SPARC | 0x00000001) -#define MD_CONTEXT_SPARC_INTEGER (MD_CONTEXT_SPARC | 0x00000002) -#define MD_CONTEXT_SAPARC_FLOATING_POINT (MD_CONTEXT_SPARC | 0x00000004) -#define MD_CONTEXT_SAPARC_EXTRA (MD_CONTEXT_SPARC | 0x00000008) - -#define MD_CONTEXT_SPARC_FULL (MD_CONTEXT_SPARC_CONTROL | \ - MD_CONTEXT_SPARC_INTEGER) - -#define MD_CONTEXT_SPARC_ALL (MD_CONTEXT_SPARC_FULL | \ - MD_CONTEXT_SAPARC_FLOATING_POINT | \ - MD_CONTEXT_SAPARC_EXTRA) - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_SPARC_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_x86.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_x86.h deleted file mode 100644 index e09cb7cb5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_cpu_x86.h +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * This file contains the necessary definitions to read minidump files - * produced on x86. These files may be read on any platform provided - * that the alignments of these structures on the processing system are - * identical to the alignments of these structures on the producing system. - * For this reason, precise-sized types are used. The structures defined - * by this file have been laid out to minimize alignment problems by ensuring - * ensuring that all members are aligned on their natural boundaries. In - * In some cases, tail-padding may be significant when different ABIs specify - * different tail-padding behaviors. To avoid problems when reading or - * writing affected structures, MD_*_SIZE macros are provided where needed, - * containing the useful size of the structures without padding. - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Mark Mentovai */ - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__ - -#define MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE 80 - /* SIZE_OF_80387_REGISTERS */ - -typedef struct { - uint32_t control_word; - uint32_t status_word; - uint32_t tag_word; - uint32_t error_offset; - uint32_t error_selector; - uint32_t data_offset; - uint32_t data_selector; - - /* register_area contains eight 80-bit (x87 "long double") quantities for - * floating-point registers %st0 (%mm0) through %st7 (%mm7). */ - uint8_t register_area[MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE]; - uint32_t cr0_npx_state; -} MDFloatingSaveAreaX86; /* FLOATING_SAVE_AREA */ - - -#define MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE 512 - /* MAXIMUM_SUPPORTED_EXTENSION */ - -typedef struct { - /* The next field determines the layout of the structure, and which parts - * of it are populated */ - uint32_t context_flags; - - /* The next 6 registers are included with MD_CONTEXT_X86_DEBUG_REGISTERS */ - uint32_t dr0; - uint32_t dr1; - uint32_t dr2; - uint32_t dr3; - uint32_t dr6; - uint32_t dr7; - - /* The next field is included with MD_CONTEXT_X86_FLOATING_POINT */ - MDFloatingSaveAreaX86 float_save; - - /* The next 4 registers are included with MD_CONTEXT_X86_SEGMENTS */ - uint32_t gs; - uint32_t fs; - uint32_t es; - uint32_t ds; - /* The next 6 registers are included with MD_CONTEXT_X86_INTEGER */ - uint32_t edi; - uint32_t esi; - uint32_t ebx; - uint32_t edx; - uint32_t ecx; - uint32_t eax; - - /* The next 6 registers are included with MD_CONTEXT_X86_CONTROL */ - uint32_t ebp; - uint32_t eip; - uint32_t cs; /* WinNT.h says "must be sanitized" */ - uint32_t eflags; /* WinNT.h says "must be sanitized" */ - uint32_t esp; - uint32_t ss; - - /* The next field is included with MD_CONTEXT_X86_EXTENDED_REGISTERS. - * It contains vector (MMX/SSE) registers. It it laid out in the - * format used by the fxsave and fsrstor instructions, so it includes - * a copy of the x87 floating-point registers as well. See FXSAVE in - * "Intel Architecture Software Developer's Manual, Volume 2." */ - uint8_t extended_registers[ - MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE]; -} MDRawContextX86; /* CONTEXT */ - -/* For (MDRawContextX86).context_flags. These values indicate the type of - * context stored in the structure. The high 24 bits identify the CPU, the - * low 8 bits identify the type of context saved. */ -#define MD_CONTEXT_X86 0x00010000 - /* CONTEXT_i386, CONTEXT_i486: identifies CPU */ -#define MD_CONTEXT_X86_CONTROL (MD_CONTEXT_X86 | 0x00000001) - /* CONTEXT_CONTROL */ -#define MD_CONTEXT_X86_INTEGER (MD_CONTEXT_X86 | 0x00000002) - /* CONTEXT_INTEGER */ -#define MD_CONTEXT_X86_SEGMENTS (MD_CONTEXT_X86 | 0x00000004) - /* CONTEXT_SEGMENTS */ -#define MD_CONTEXT_X86_FLOATING_POINT (MD_CONTEXT_X86 | 0x00000008) - /* CONTEXT_FLOATING_POINT */ -#define MD_CONTEXT_X86_DEBUG_REGISTERS (MD_CONTEXT_X86 | 0x00000010) - /* CONTEXT_DEBUG_REGISTERS */ -#define MD_CONTEXT_X86_EXTENDED_REGISTERS (MD_CONTEXT_X86 | 0x00000020) - /* CONTEXT_EXTENDED_REGISTERS */ -#define MD_CONTEXT_X86_XSTATE (MD_CONTEXT_X86 | 0x00000040) - /* CONTEXT_XSTATE */ - -#define MD_CONTEXT_X86_FULL (MD_CONTEXT_X86_CONTROL | \ - MD_CONTEXT_X86_INTEGER | \ - MD_CONTEXT_X86_SEGMENTS) - /* CONTEXT_FULL */ - -#define MD_CONTEXT_X86_ALL (MD_CONTEXT_X86_FULL | \ - MD_CONTEXT_X86_FLOATING_POINT | \ - MD_CONTEXT_X86_DEBUG_REGISTERS | \ - MD_CONTEXT_X86_EXTENDED_REGISTERS) - /* CONTEXT_ALL */ - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_X86_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_linux.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_linux.h deleted file mode 100644 index 9e7e4f1e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_linux.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_exception_linux.h: A definition of exception codes for - * Linux - * - * (This is C99 source, please don't corrupt it with C++.) - * - * Author: Mark Mentovai - * Split into its own file: Neal Sidhwaney */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - - -/* For (MDException).exception_code. These values come from bits/signum.h. - */ -typedef enum { - MD_EXCEPTION_CODE_LIN_SIGHUP = 1, /* Hangup (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGINT = 2, /* Interrupt (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGQUIT = 3, /* Quit (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGILL = 4, /* Illegal instruction (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGTRAP = 5, /* Trace trap (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGABRT = 6, /* Abort (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGBUS = 7, /* BUS error (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGFPE = 8, /* Floating-point exception (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGKILL = 9, /* Kill, unblockable (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGUSR1 = 10, /* User-defined signal 1 (POSIX). */ - MD_EXCEPTION_CODE_LIN_SIGSEGV = 11, /* Segmentation violation (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGUSR2 = 12, /* User-defined signal 2 (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGPIPE = 13, /* Broken pipe (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGALRM = 14, /* Alarm clock (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGTERM = 15, /* Termination (ANSI) */ - MD_EXCEPTION_CODE_LIN_SIGSTKFLT = 16, /* Stack faultd */ - MD_EXCEPTION_CODE_LIN_SIGCHLD = 17, /* Child status has changed (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGCONT = 18, /* Continue (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGSTOP = 19, /* Stop, unblockable (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGTSTP = 20, /* Keyboard stop (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGTTIN = 21, /* Background read from tty (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGTTOU = 22, /* Background write to tty (POSIX) */ - MD_EXCEPTION_CODE_LIN_SIGURG = 23, - /* Urgent condition on socket (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGXCPU = 24, /* CPU limit exceeded (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGXFSZ = 25, - /* File size limit exceeded (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGVTALRM = 26, /* Virtual alarm clock (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGPROF = 27, /* Profiling alarm clock (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGWINCH = 28, /* Window size change (4.3 BSD, Sun) */ - MD_EXCEPTION_CODE_LIN_SIGIO = 29, /* I/O now possible (4.2 BSD) */ - MD_EXCEPTION_CODE_LIN_SIGPWR = 30, /* Power failure restart (System V) */ - MD_EXCEPTION_CODE_LIN_SIGSYS = 31, /* Bad system call */ - MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED = 0xFFFFFFFF /* No exception, - dump requested. */ -} MDExceptionCodeLinux; - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_mac.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_mac.h deleted file mode 100644 index 91c1c0974..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_mac.h +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_exception_mac.h: A definition of exception codes for Mac - * OS X - * - * (This is C99 source, please don't corrupt it with C++.) - * - * Author: Mark Mentovai - * Split into its own file: Neal Sidhwaney */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - -/* For (MDException).exception_code. Breakpad minidump extension for Mac OS X - * support. Based on Darwin/Mac OS X' mach/exception_types.h. This is - * what Mac OS X calls an "exception", not a "code". */ -typedef enum { - /* Exception code. The high 16 bits of exception_code contains one of - * these values. */ - MD_EXCEPTION_MAC_BAD_ACCESS = 1, /* code can be a kern_return_t */ - /* EXC_BAD_ACCESS */ - MD_EXCEPTION_MAC_BAD_INSTRUCTION = 2, /* code is CPU-specific */ - /* EXC_BAD_INSTRUCTION */ - MD_EXCEPTION_MAC_ARITHMETIC = 3, /* code is CPU-specific */ - /* EXC_ARITHMETIC */ - MD_EXCEPTION_MAC_EMULATION = 4, /* code is CPU-specific */ - /* EXC_EMULATION */ - MD_EXCEPTION_MAC_SOFTWARE = 5, - /* EXC_SOFTWARE */ - MD_EXCEPTION_MAC_BREAKPOINT = 6, /* code is CPU-specific */ - /* EXC_BREAKPOINT */ - MD_EXCEPTION_MAC_SYSCALL = 7, - /* EXC_SYSCALL */ - MD_EXCEPTION_MAC_MACH_SYSCALL = 8, - /* EXC_MACH_SYSCALL */ - MD_EXCEPTION_MAC_RPC_ALERT = 9 - /* EXC_RPC_ALERT */ -} MDExceptionMac; - -/* For (MDException).exception_flags. Breakpad minidump extension for Mac OS X - * support. Based on Darwin/Mac OS X' mach/ppc/exception.h and - * mach/i386/exception.h. This is what Mac OS X calls a "code". */ -typedef enum { - /* With MD_EXCEPTION_BAD_ACCESS. These are relevant kern_return_t values - * from mach/kern_return.h. */ - MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS = 1, - /* KERN_INVALID_ADDRESS */ - MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE = 2, - /* KERN_PROTECTION_FAILURE */ - MD_EXCEPTION_CODE_MAC_NO_ACCESS = 8, - /* KERN_NO_ACCESS */ - MD_EXCEPTION_CODE_MAC_MEMORY_FAILURE = 9, - /* KERN_MEMORY_FAILURE */ - MD_EXCEPTION_CODE_MAC_MEMORY_ERROR = 10, - /* KERN_MEMORY_ERROR */ - - /* With MD_EXCEPTION_SOFTWARE */ - MD_EXCEPTION_CODE_MAC_BAD_SYSCALL = 0x00010000, /* Mach SIGSYS */ - MD_EXCEPTION_CODE_MAC_BAD_PIPE = 0x00010001, /* Mach SIGPIPE */ - MD_EXCEPTION_CODE_MAC_ABORT = 0x00010002, /* Mach SIGABRT */ - /* Custom values */ - MD_EXCEPTION_CODE_MAC_NS_EXCEPTION = 0xDEADC0DE, /* uncaught NSException */ - - /* With MD_EXCEPTION_MAC_BAD_ACCESS on arm */ - MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN = 0x0101, /* EXC_ARM_DA_ALIGN */ - MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG = 0x0102, /* EXC_ARM_DA_DEBUG */ - - /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on arm */ - MD_EXCEPTION_CODE_MAC_ARM_UNDEFINED = 1, /* EXC_ARM_UNDEFINED */ - - /* With MD_EXCEPTION_MAC_BREAKPOINT on arm */ - MD_EXCEPTION_CODE_MAC_ARM_BREAKPOINT = 1, /* EXC_ARM_BREAKPOINT */ - - /* With MD_EXCEPTION_MAC_BAD_ACCESS on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_VM_PROT_READ = 0x0101, - /* EXC_PPC_VM_PROT_READ */ - MD_EXCEPTION_CODE_MAC_PPC_BADSPACE = 0x0102, - /* EXC_PPC_BADSPACE */ - MD_EXCEPTION_CODE_MAC_PPC_UNALIGNED = 0x0103, - /* EXC_PPC_UNALIGNED */ - - /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_INVALID_SYSCALL = 1, - /* EXC_PPC_INVALID_SYSCALL */ - MD_EXCEPTION_CODE_MAC_PPC_UNIMPLEMENTED_INSTRUCTION = 2, - /* EXC_PPC_UNIPL_INST */ - MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_INSTRUCTION = 3, - /* EXC_PPC_PRIVINST */ - MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_REGISTER = 4, - /* EXC_PPC_PRIVREG */ - MD_EXCEPTION_CODE_MAC_PPC_TRACE = 5, - /* EXC_PPC_TRACE */ - MD_EXCEPTION_CODE_MAC_PPC_PERFORMANCE_MONITOR = 6, - /* EXC_PPC_PERFMON */ - - /* With MD_EXCEPTION_MAC_ARITHMETIC on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_OVERFLOW = 1, - /* EXC_PPC_OVERFLOW */ - MD_EXCEPTION_CODE_MAC_PPC_ZERO_DIVIDE = 2, - /* EXC_PPC_ZERO_DIVIDE */ - MD_EXCEPTION_CODE_MAC_PPC_FLOAT_INEXACT = 3, - /* EXC_FLT_INEXACT */ - MD_EXCEPTION_CODE_MAC_PPC_FLOAT_ZERO_DIVIDE = 4, - /* EXC_PPC_FLT_ZERO_DIVIDE */ - MD_EXCEPTION_CODE_MAC_PPC_FLOAT_UNDERFLOW = 5, - /* EXC_PPC_FLT_UNDERFLOW */ - MD_EXCEPTION_CODE_MAC_PPC_FLOAT_OVERFLOW = 6, - /* EXC_PPC_FLT_OVERFLOW */ - MD_EXCEPTION_CODE_MAC_PPC_FLOAT_NOT_A_NUMBER = 7, - /* EXC_PPC_FLT_NOT_A_NUMBER */ - - /* With MD_EXCEPTION_MAC_EMULATION on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_NO_EMULATION = 8, - /* EXC_PPC_NOEMULATION */ - MD_EXCEPTION_CODE_MAC_PPC_ALTIVEC_ASSIST = 9, - /* EXC_PPC_ALTIVECASSIST */ - - /* With MD_EXCEPTION_MAC_SOFTWARE on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_TRAP = 0x00000001, /* EXC_PPC_TRAP */ - MD_EXCEPTION_CODE_MAC_PPC_MIGRATE = 0x00010100, /* EXC_PPC_MIGRATE */ - - /* With MD_EXCEPTION_MAC_BREAKPOINT on ppc */ - MD_EXCEPTION_CODE_MAC_PPC_BREAKPOINT = 1, /* EXC_PPC_BREAKPOINT */ - - /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on x86, see also x86 interrupt - * values below. */ - MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION = 1, /* EXC_I386_INVOP */ - - /* With MD_EXCEPTION_MAC_ARITHMETIC on x86 */ - MD_EXCEPTION_CODE_MAC_X86_DIV = 1, /* EXC_I386_DIV */ - MD_EXCEPTION_CODE_MAC_X86_INTO = 2, /* EXC_I386_INTO */ - MD_EXCEPTION_CODE_MAC_X86_NOEXT = 3, /* EXC_I386_NOEXT */ - MD_EXCEPTION_CODE_MAC_X86_EXTOVR = 4, /* EXC_I386_EXTOVR */ - MD_EXCEPTION_CODE_MAC_X86_EXTERR = 5, /* EXC_I386_EXTERR */ - MD_EXCEPTION_CODE_MAC_X86_EMERR = 6, /* EXC_I386_EMERR */ - MD_EXCEPTION_CODE_MAC_X86_BOUND = 7, /* EXC_I386_BOUND */ - MD_EXCEPTION_CODE_MAC_X86_SSEEXTERR = 8, /* EXC_I386_SSEEXTERR */ - - /* With MD_EXCEPTION_MAC_BREAKPOINT on x86 */ - MD_EXCEPTION_CODE_MAC_X86_SGL = 1, /* EXC_I386_SGL */ - MD_EXCEPTION_CODE_MAC_X86_BPT = 2, /* EXC_I386_BPT */ - - /* With MD_EXCEPTION_MAC_BAD_INSTRUCTION on x86. These are the raw - * x86 interrupt codes. Most of these are mapped to other Mach - * exceptions and codes, are handled, or should not occur in user space. - * A few of these will do occur with MD_EXCEPTION_MAC_BAD_INSTRUCTION. */ - /* EXC_I386_DIVERR = 0: mapped to EXC_ARITHMETIC/EXC_I386_DIV */ - /* EXC_I386_SGLSTP = 1: mapped to EXC_BREAKPOINT/EXC_I386_SGL */ - /* EXC_I386_NMIFLT = 2: should not occur in user space */ - /* EXC_I386_BPTFLT = 3: mapped to EXC_BREAKPOINT/EXC_I386_BPT */ - /* EXC_I386_INTOFLT = 4: mapped to EXC_ARITHMETIC/EXC_I386_INTO */ - /* EXC_I386_BOUNDFLT = 5: mapped to EXC_ARITHMETIC/EXC_I386_BOUND */ - /* EXC_I386_INVOPFLT = 6: mapped to EXC_BAD_INSTRUCTION/EXC_I386_INVOP */ - /* EXC_I386_NOEXTFLT = 7: should be handled by the kernel */ - /* EXC_I386_DBLFLT = 8: should be handled (if possible) by the kernel */ - /* EXC_I386_EXTOVRFLT = 9: mapped to EXC_BAD_ACCESS/(PROT_READ|PROT_EXEC) */ - MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT = 10, - /* EXC_INVTSSFLT */ - MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT = 11, - /* EXC_SEGNPFLT */ - MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT = 12, - /* EXC_STKFLT */ - MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT = 13, - /* EXC_GPFLT */ - /* EXC_I386_PGFLT = 14: should not occur in user space */ - /* EXC_I386_EXTERRFLT = 16: mapped to EXC_ARITHMETIC/EXC_I386_EXTERR */ - MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT = 17 - /* EXC_ALIGNFLT (for vector operations) */ - /* EXC_I386_ENOEXTFLT = 32: should be handled by the kernel */ - /* EXC_I386_ENDPERR = 33: should not occur */ -} MDExceptionCodeMac; - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_MAC_OSX_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_ps3.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_ps3.h deleted file mode 100644 index adff5a6bb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_ps3.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_exception_ps3.h: A definition of exception codes for - * PS3 */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_PS3_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_PS3_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - -typedef enum { - MD_EXCEPTION_CODE_PS3_UNKNOWN = 0, - MD_EXCEPTION_CODE_PS3_TRAP_EXCEP = 1, - MD_EXCEPTION_CODE_PS3_PRIV_INSTR = 2, - MD_EXCEPTION_CODE_PS3_ILLEGAL_INSTR = 3, - MD_EXCEPTION_CODE_PS3_INSTR_STORAGE = 4, - MD_EXCEPTION_CODE_PS3_INSTR_SEGMENT = 5, - MD_EXCEPTION_CODE_PS3_DATA_STORAGE = 6, - MD_EXCEPTION_CODE_PS3_DATA_SEGMENT = 7, - MD_EXCEPTION_CODE_PS3_FLOAT_POINT = 8, - MD_EXCEPTION_CODE_PS3_DABR_MATCH = 9, - MD_EXCEPTION_CODE_PS3_ALIGN_EXCEP = 10, - MD_EXCEPTION_CODE_PS3_MEMORY_ACCESS = 11, - MD_EXCEPTION_CODE_PS3_COPRO_ALIGN = 12, - MD_EXCEPTION_CODE_PS3_COPRO_INVALID_COM = 13, - MD_EXCEPTION_CODE_PS3_COPRO_ERR = 14, - MD_EXCEPTION_CODE_PS3_COPRO_FIR = 15, - MD_EXCEPTION_CODE_PS3_COPRO_DATA_SEGMENT = 16, - MD_EXCEPTION_CODE_PS3_COPRO_DATA_STORAGE = 17, - MD_EXCEPTION_CODE_PS3_COPRO_STOP_INSTR = 18, - MD_EXCEPTION_CODE_PS3_COPRO_HALT_INSTR = 19, - MD_EXCEPTION_CODE_PS3_COPRO_HALTINST_UNKNOWN = 20, - MD_EXCEPTION_CODE_PS3_COPRO_MEMORY_ACCESS = 21, - MD_EXCEPTION_CODE_PS3_GRAPHIC = 22 -} MDExceptionCodePS3; - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_PS3_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_solaris.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_solaris.h deleted file mode 100644 index f18ddf424..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_solaris.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_exception_solaris.h: A definition of exception codes for - * Solaris - * - * (This is C99 source, please don't corrupt it with C++.) - * - * Author: Mark Mentovai - * Split into its own file: Neal Sidhwaney */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - -/* For (MDException).exception_code. These values come from sys/iso/signal_iso.h - */ -typedef enum { - MD_EXCEPTION_CODE_SOL_SIGHUP = 1, /* Hangup */ - MD_EXCEPTION_CODE_SOL_SIGINT = 2, /* interrupt (rubout) */ - MD_EXCEPTION_CODE_SOL_SIGQUIT = 3, /* quit (ASCII FS) */ - MD_EXCEPTION_CODE_SOL_SIGILL = 4, /* illegal instruction (not reset when caught) */ - MD_EXCEPTION_CODE_SOL_SIGTRAP = 5, /* trace trap (not reset when caught) */ - MD_EXCEPTION_CODE_SOL_SIGIOT = 6, /* IOT instruction */ - MD_EXCEPTION_CODE_SOL_SIGABRT = 6, /* used by abort, replace SIGIOT in the future */ - MD_EXCEPTION_CODE_SOL_SIGEMT = 7, /* EMT instruction */ - MD_EXCEPTION_CODE_SOL_SIGFPE = 8, /* floating point exception */ - MD_EXCEPTION_CODE_SOL_SIGKILL = 9, /* kill (cannot be caught or ignored) */ - MD_EXCEPTION_CODE_SOL_SIGBUS = 10, /* bus error */ - MD_EXCEPTION_CODE_SOL_SIGSEGV = 11, /* segmentation violation */ - MD_EXCEPTION_CODE_SOL_SIGSYS = 12, /* bad argument to system call */ - MD_EXCEPTION_CODE_SOL_SIGPIPE = 13, /* write on a pipe with no one to read it */ - MD_EXCEPTION_CODE_SOL_SIGALRM = 14, /* alarm clock */ - MD_EXCEPTION_CODE_SOL_SIGTERM = 15, /* software termination signal from kill */ - MD_EXCEPTION_CODE_SOL_SIGUSR1 = 16, /* user defined signal 1 */ - MD_EXCEPTION_CODE_SOL_SIGUSR2 = 17, /* user defined signal 2 */ - MD_EXCEPTION_CODE_SOL_SIGCLD = 18, /* child status change */ - MD_EXCEPTION_CODE_SOL_SIGCHLD = 18, /* child status change alias (POSIX) */ - MD_EXCEPTION_CODE_SOL_SIGPWR = 19, /* power-fail restart */ - MD_EXCEPTION_CODE_SOL_SIGWINCH = 20, /* window size change */ - MD_EXCEPTION_CODE_SOL_SIGURG = 21, /* urgent socket condition */ - MD_EXCEPTION_CODE_SOL_SIGPOLL = 22, /* pollable event occurred */ - MD_EXCEPTION_CODE_SOL_SIGIO = 22, /* socket I/O possible (SIGPOLL alias) */ - MD_EXCEPTION_CODE_SOL_SIGSTOP = 23, /* stop (cannot be caught or ignored) */ - MD_EXCEPTION_CODE_SOL_SIGTSTP = 24, /* user stop requested from tty */ - MD_EXCEPTION_CODE_SOL_SIGCONT = 25, /* stopped process has been continued */ - MD_EXCEPTION_CODE_SOL_SIGTTIN = 26, /* background tty read attempted */ - MD_EXCEPTION_CODE_SOL_SIGTTOU = 27, /* background tty write attempted */ - MD_EXCEPTION_CODE_SOL_SIGVTALRM = 28, /* virtual timer expired */ - MD_EXCEPTION_CODE_SOL_SIGPROF = 29, /* profiling timer expired */ - MD_EXCEPTION_CODE_SOL_SIGXCPU = 30, /* exceeded cpu limit */ - MD_EXCEPTION_CODE_SOL_SIGXFSZ = 31, /* exceeded file size limit */ - MD_EXCEPTION_CODE_SOL_SIGWAITING = 32, /* reserved signal no longer used by threading code */ - MD_EXCEPTION_CODE_SOL_SIGLWP = 33, /* reserved signal no longer used by threading code */ - MD_EXCEPTION_CODE_SOL_SIGFREEZE = 34, /* special signal used by CPR */ - MD_EXCEPTION_CODE_SOL_SIGTHAW = 35, /* special signal used by CPR */ - MD_EXCEPTION_CODE_SOL_SIGCANCEL = 36, /* reserved signal for thread cancellation */ - MD_EXCEPTION_CODE_SOL_SIGLOST = 37, /* resource lost (eg, record-lock lost) */ - MD_EXCEPTION_CODE_SOL_SIGXRES = 38, /* resource control exceeded */ - MD_EXCEPTION_CODE_SOL_SIGJVM1 = 39, /* reserved signal for Java Virtual Machine */ - MD_EXCEPTION_CODE_SOL_SIGJVM2 = 40 /* reserved signal for Java Virtual Machine */ -} MDExceptionCodeSolaris; - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_SOLARIS_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_win32.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_win32.h deleted file mode 100644 index 6fa3fba44..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_exception_win32.h +++ /dev/null @@ -1,2264 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_exception_win32.h: Definitions of exception codes for - * Win32 platform - * - * (This is C99 source, please don't corrupt it with C++.) - * - * Author: Mark Mentovai - * Split into its own file: Neal Sidhwaney */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - - -/* For (MDException).exception_code. These values come from WinBase.h - * and WinNT.h (names beginning with EXCEPTION_ are in WinBase.h, - * they are STATUS_ in WinNT.h). */ -typedef enum { - MD_EXCEPTION_CODE_WIN_CONTROL_C = 0x40010005, - /* DBG_CONTROL_C */ - MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION = 0x80000001, - /* EXCEPTION_GUARD_PAGE */ - MD_EXCEPTION_CODE_WIN_DATATYPE_MISALIGNMENT = 0x80000002, - /* EXCEPTION_DATATYPE_MISALIGNMENT */ - MD_EXCEPTION_CODE_WIN_BREAKPOINT = 0x80000003, - /* EXCEPTION_BREAKPOINT */ - MD_EXCEPTION_CODE_WIN_SINGLE_STEP = 0x80000004, - /* EXCEPTION_SINGLE_STEP */ - MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION = 0xc0000005, - /* EXCEPTION_ACCESS_VIOLATION */ - MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR = 0xc0000006, - /* EXCEPTION_IN_PAGE_ERROR */ - MD_EXCEPTION_CODE_WIN_INVALID_HANDLE = 0xc0000008, - /* EXCEPTION_INVALID_HANDLE */ - MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION = 0xc000001d, - /* EXCEPTION_ILLEGAL_INSTRUCTION */ - MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION = 0xc0000025, - /* EXCEPTION_NONCONTINUABLE_EXCEPTION */ - MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION = 0xc0000026, - /* EXCEPTION_INVALID_DISPOSITION */ - MD_EXCEPTION_CODE_WIN_ARRAY_BOUNDS_EXCEEDED = 0xc000008c, - /* EXCEPTION_BOUNDS_EXCEEDED */ - MD_EXCEPTION_CODE_WIN_FLOAT_DENORMAL_OPERAND = 0xc000008d, - /* EXCEPTION_FLT_DENORMAL_OPERAND */ - MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO = 0xc000008e, - /* EXCEPTION_FLT_DIVIDE_BY_ZERO */ - MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT = 0xc000008f, - /* EXCEPTION_FLT_INEXACT_RESULT */ - MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION = 0xc0000090, - /* EXCEPTION_FLT_INVALID_OPERATION */ - MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW = 0xc0000091, - /* EXCEPTION_FLT_OVERFLOW */ - MD_EXCEPTION_CODE_WIN_FLOAT_STACK_CHECK = 0xc0000092, - /* EXCEPTION_FLT_STACK_CHECK */ - MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW = 0xc0000093, - /* EXCEPTION_FLT_UNDERFLOW */ - MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO = 0xc0000094, - /* EXCEPTION_INT_DIVIDE_BY_ZERO */ - MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW = 0xc0000095, - /* EXCEPTION_INT_OVERFLOW */ - MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION = 0xc0000096, - /* EXCEPTION_PRIV_INSTRUCTION */ - MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW = 0xc00000fd, - /* EXCEPTION_STACK_OVERFLOW */ - MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK = 0xc0000194, - /* EXCEPTION_POSSIBLE_DEADLOCK */ - MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN = 0xc0000409, - /* STATUS_STACK_BUFFER_OVERRUN */ - MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION = 0xc0000374, - /* STATUS_HEAP_CORRUPTION */ - MD_EXCEPTION_OUT_OF_MEMORY = 0xe0000008, - /* Exception thrown by Chromium allocators to indicate OOM. - See base/process/memory.h in Chromium for rationale. */ - MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION = 0xe06d7363 - /* Per http://support.microsoft.com/kb/185294, - generated by Visual C++ compiler */ -} MDExceptionCodeWin; - - -/* For (MDException).exception_information[2], when (MDException).exception_code - * is MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR. This describes the underlying reason - * for the error. These values come from ntstatus.h. - * - * The content of this enum was created from ntstatus.h in the 8.1 SDK with - * - * egrep '#define [A-Z_0-9]+\s+\(\(NTSTATUS\)0xC[0-9A-F]+L\)' ntstatus.h - * | tr -d '\r' - * | sed -r 's@#define ([A-Z_0-9]+)\s+\(\(NTSTATUS\)(0xC[0-9A-F]+)L\).*@\2 \1@' - * | sort - * | sed -r 's@(0xC[0-9A-F]+) ([A-Z_0-9]+)@ MD_NTSTATUS_WIN_\2 = \1,@' - * - * With easy copy to clipboard with - * | xclip -selection c # on linux - * | clip # on windows - * | pbcopy # on mac - * - * and then the last comma manually removed. */ -typedef enum { - MD_NTSTATUS_WIN_STATUS_UNSUCCESSFUL = 0xC0000001, - MD_NTSTATUS_WIN_STATUS_NOT_IMPLEMENTED = 0xC0000002, - MD_NTSTATUS_WIN_STATUS_INVALID_INFO_CLASS = 0xC0000003, - MD_NTSTATUS_WIN_STATUS_INFO_LENGTH_MISMATCH = 0xC0000004, - MD_NTSTATUS_WIN_STATUS_ACCESS_VIOLATION = 0xC0000005, - MD_NTSTATUS_WIN_STATUS_IN_PAGE_ERROR = 0xC0000006, - MD_NTSTATUS_WIN_STATUS_PAGEFILE_QUOTA = 0xC0000007, - MD_NTSTATUS_WIN_STATUS_INVALID_HANDLE = 0xC0000008, - MD_NTSTATUS_WIN_STATUS_BAD_INITIAL_STACK = 0xC0000009, - MD_NTSTATUS_WIN_STATUS_BAD_INITIAL_PC = 0xC000000A, - MD_NTSTATUS_WIN_STATUS_INVALID_CID = 0xC000000B, - MD_NTSTATUS_WIN_STATUS_TIMER_NOT_CANCELED = 0xC000000C, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER = 0xC000000D, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_DEVICE = 0xC000000E, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_FILE = 0xC000000F, - MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_REQUEST = 0xC0000010, - MD_NTSTATUS_WIN_STATUS_END_OF_FILE = 0xC0000011, - MD_NTSTATUS_WIN_STATUS_WRONG_VOLUME = 0xC0000012, - MD_NTSTATUS_WIN_STATUS_NO_MEDIA_IN_DEVICE = 0xC0000013, - MD_NTSTATUS_WIN_STATUS_UNRECOGNIZED_MEDIA = 0xC0000014, - MD_NTSTATUS_WIN_STATUS_NONEXISTENT_SECTOR = 0xC0000015, - MD_NTSTATUS_WIN_STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016, - MD_NTSTATUS_WIN_STATUS_NO_MEMORY = 0xC0000017, - MD_NTSTATUS_WIN_STATUS_CONFLICTING_ADDRESSES = 0xC0000018, - MD_NTSTATUS_WIN_STATUS_NOT_MAPPED_VIEW = 0xC0000019, - MD_NTSTATUS_WIN_STATUS_UNABLE_TO_FREE_VM = 0xC000001A, - MD_NTSTATUS_WIN_STATUS_UNABLE_TO_DELETE_SECTION = 0xC000001B, - MD_NTSTATUS_WIN_STATUS_INVALID_SYSTEM_SERVICE = 0xC000001C, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_INSTRUCTION = 0xC000001D, - MD_NTSTATUS_WIN_STATUS_INVALID_LOCK_SEQUENCE = 0xC000001E, - MD_NTSTATUS_WIN_STATUS_INVALID_VIEW_SIZE = 0xC000001F, - MD_NTSTATUS_WIN_STATUS_INVALID_FILE_FOR_SECTION = 0xC0000020, - MD_NTSTATUS_WIN_STATUS_ALREADY_COMMITTED = 0xC0000021, - MD_NTSTATUS_WIN_STATUS_ACCESS_DENIED = 0xC0000022, - MD_NTSTATUS_WIN_STATUS_BUFFER_TOO_SMALL = 0xC0000023, - MD_NTSTATUS_WIN_STATUS_OBJECT_TYPE_MISMATCH = 0xC0000024, - MD_NTSTATUS_WIN_STATUS_NONCONTINUABLE_EXCEPTION = 0xC0000025, - MD_NTSTATUS_WIN_STATUS_INVALID_DISPOSITION = 0xC0000026, - MD_NTSTATUS_WIN_STATUS_UNWIND = 0xC0000027, - MD_NTSTATUS_WIN_STATUS_BAD_STACK = 0xC0000028, - MD_NTSTATUS_WIN_STATUS_INVALID_UNWIND_TARGET = 0xC0000029, - MD_NTSTATUS_WIN_STATUS_NOT_LOCKED = 0xC000002A, - MD_NTSTATUS_WIN_STATUS_PARITY_ERROR = 0xC000002B, - MD_NTSTATUS_WIN_STATUS_UNABLE_TO_DECOMMIT_VM = 0xC000002C, - MD_NTSTATUS_WIN_STATUS_NOT_COMMITTED = 0xC000002D, - MD_NTSTATUS_WIN_STATUS_INVALID_PORT_ATTRIBUTES = 0xC000002E, - MD_NTSTATUS_WIN_STATUS_PORT_MESSAGE_TOO_LONG = 0xC000002F, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_MIX = 0xC0000030, - MD_NTSTATUS_WIN_STATUS_INVALID_QUOTA_LOWER = 0xC0000031, - MD_NTSTATUS_WIN_STATUS_DISK_CORRUPT_ERROR = 0xC0000032, - MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_INVALID = 0xC0000033, - MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034, - MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_COLLISION = 0xC0000035, - MD_NTSTATUS_WIN_STATUS_PORT_DISCONNECTED = 0xC0000037, - MD_NTSTATUS_WIN_STATUS_DEVICE_ALREADY_ATTACHED = 0xC0000038, - MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_INVALID = 0xC0000039, - MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A, - MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003B, - MD_NTSTATUS_WIN_STATUS_DATA_OVERRUN = 0xC000003C, - MD_NTSTATUS_WIN_STATUS_DATA_LATE_ERROR = 0xC000003D, - MD_NTSTATUS_WIN_STATUS_DATA_ERROR = 0xC000003E, - MD_NTSTATUS_WIN_STATUS_CRC_ERROR = 0xC000003F, - MD_NTSTATUS_WIN_STATUS_SECTION_TOO_BIG = 0xC0000040, - MD_NTSTATUS_WIN_STATUS_PORT_CONNECTION_REFUSED = 0xC0000041, - MD_NTSTATUS_WIN_STATUS_INVALID_PORT_HANDLE = 0xC0000042, - MD_NTSTATUS_WIN_STATUS_SHARING_VIOLATION = 0xC0000043, - MD_NTSTATUS_WIN_STATUS_QUOTA_EXCEEDED = 0xC0000044, - MD_NTSTATUS_WIN_STATUS_INVALID_PAGE_PROTECTION = 0xC0000045, - MD_NTSTATUS_WIN_STATUS_MUTANT_NOT_OWNED = 0xC0000046, - MD_NTSTATUS_WIN_STATUS_SEMAPHORE_LIMIT_EXCEEDED = 0xC0000047, - MD_NTSTATUS_WIN_STATUS_PORT_ALREADY_SET = 0xC0000048, - MD_NTSTATUS_WIN_STATUS_SECTION_NOT_IMAGE = 0xC0000049, - MD_NTSTATUS_WIN_STATUS_SUSPEND_COUNT_EXCEEDED = 0xC000004A, - MD_NTSTATUS_WIN_STATUS_THREAD_IS_TERMINATING = 0xC000004B, - MD_NTSTATUS_WIN_STATUS_BAD_WORKING_SET_LIMIT = 0xC000004C, - MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_FILE_MAP = 0xC000004D, - MD_NTSTATUS_WIN_STATUS_SECTION_PROTECTION = 0xC000004E, - MD_NTSTATUS_WIN_STATUS_EAS_NOT_SUPPORTED = 0xC000004F, - MD_NTSTATUS_WIN_STATUS_EA_TOO_LARGE = 0xC0000050, - MD_NTSTATUS_WIN_STATUS_NONEXISTENT_EA_ENTRY = 0xC0000051, - MD_NTSTATUS_WIN_STATUS_NO_EAS_ON_FILE = 0xC0000052, - MD_NTSTATUS_WIN_STATUS_EA_CORRUPT_ERROR = 0xC0000053, - MD_NTSTATUS_WIN_STATUS_FILE_LOCK_CONFLICT = 0xC0000054, - MD_NTSTATUS_WIN_STATUS_LOCK_NOT_GRANTED = 0xC0000055, - MD_NTSTATUS_WIN_STATUS_DELETE_PENDING = 0xC0000056, - MD_NTSTATUS_WIN_STATUS_CTL_FILE_NOT_SUPPORTED = 0xC0000057, - MD_NTSTATUS_WIN_STATUS_UNKNOWN_REVISION = 0xC0000058, - MD_NTSTATUS_WIN_STATUS_REVISION_MISMATCH = 0xC0000059, - MD_NTSTATUS_WIN_STATUS_INVALID_OWNER = 0xC000005A, - MD_NTSTATUS_WIN_STATUS_INVALID_PRIMARY_GROUP = 0xC000005B, - MD_NTSTATUS_WIN_STATUS_NO_IMPERSONATION_TOKEN = 0xC000005C, - MD_NTSTATUS_WIN_STATUS_CANT_DISABLE_MANDATORY = 0xC000005D, - MD_NTSTATUS_WIN_STATUS_NO_LOGON_SERVERS = 0xC000005E, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_LOGON_SESSION = 0xC000005F, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_PRIVILEGE = 0xC0000060, - MD_NTSTATUS_WIN_STATUS_PRIVILEGE_NOT_HELD = 0xC0000061, - MD_NTSTATUS_WIN_STATUS_INVALID_ACCOUNT_NAME = 0xC0000062, - MD_NTSTATUS_WIN_STATUS_USER_EXISTS = 0xC0000063, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_USER = 0xC0000064, - MD_NTSTATUS_WIN_STATUS_GROUP_EXISTS = 0xC0000065, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_GROUP = 0xC0000066, - MD_NTSTATUS_WIN_STATUS_MEMBER_IN_GROUP = 0xC0000067, - MD_NTSTATUS_WIN_STATUS_MEMBER_NOT_IN_GROUP = 0xC0000068, - MD_NTSTATUS_WIN_STATUS_LAST_ADMIN = 0xC0000069, - MD_NTSTATUS_WIN_STATUS_WRONG_PASSWORD = 0xC000006A, - MD_NTSTATUS_WIN_STATUS_ILL_FORMED_PASSWORD = 0xC000006B, - MD_NTSTATUS_WIN_STATUS_PASSWORD_RESTRICTION = 0xC000006C, - MD_NTSTATUS_WIN_STATUS_LOGON_FAILURE = 0xC000006D, - MD_NTSTATUS_WIN_STATUS_ACCOUNT_RESTRICTION = 0xC000006E, - MD_NTSTATUS_WIN_STATUS_INVALID_LOGON_HOURS = 0xC000006F, - MD_NTSTATUS_WIN_STATUS_INVALID_WORKSTATION = 0xC0000070, - MD_NTSTATUS_WIN_STATUS_PASSWORD_EXPIRED = 0xC0000071, - MD_NTSTATUS_WIN_STATUS_ACCOUNT_DISABLED = 0xC0000072, - MD_NTSTATUS_WIN_STATUS_NONE_MAPPED = 0xC0000073, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_LUIDS_REQUESTED = 0xC0000074, - MD_NTSTATUS_WIN_STATUS_LUIDS_EXHAUSTED = 0xC0000075, - MD_NTSTATUS_WIN_STATUS_INVALID_SUB_AUTHORITY = 0xC0000076, - MD_NTSTATUS_WIN_STATUS_INVALID_ACL = 0xC0000077, - MD_NTSTATUS_WIN_STATUS_INVALID_SID = 0xC0000078, - MD_NTSTATUS_WIN_STATUS_INVALID_SECURITY_DESCR = 0xC0000079, - MD_NTSTATUS_WIN_STATUS_PROCEDURE_NOT_FOUND = 0xC000007A, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_FORMAT = 0xC000007B, - MD_NTSTATUS_WIN_STATUS_NO_TOKEN = 0xC000007C, - MD_NTSTATUS_WIN_STATUS_BAD_INHERITANCE_ACL = 0xC000007D, - MD_NTSTATUS_WIN_STATUS_RANGE_NOT_LOCKED = 0xC000007E, - MD_NTSTATUS_WIN_STATUS_DISK_FULL = 0xC000007F, - MD_NTSTATUS_WIN_STATUS_SERVER_DISABLED = 0xC0000080, - MD_NTSTATUS_WIN_STATUS_SERVER_NOT_DISABLED = 0xC0000081, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_GUIDS_REQUESTED = 0xC0000082, - MD_NTSTATUS_WIN_STATUS_GUIDS_EXHAUSTED = 0xC0000083, - MD_NTSTATUS_WIN_STATUS_INVALID_ID_AUTHORITY = 0xC0000084, - MD_NTSTATUS_WIN_STATUS_AGENTS_EXHAUSTED = 0xC0000085, - MD_NTSTATUS_WIN_STATUS_INVALID_VOLUME_LABEL = 0xC0000086, - MD_NTSTATUS_WIN_STATUS_SECTION_NOT_EXTENDED = 0xC0000087, - MD_NTSTATUS_WIN_STATUS_NOT_MAPPED_DATA = 0xC0000088, - MD_NTSTATUS_WIN_STATUS_RESOURCE_DATA_NOT_FOUND = 0xC0000089, - MD_NTSTATUS_WIN_STATUS_RESOURCE_TYPE_NOT_FOUND = 0xC000008A, - MD_NTSTATUS_WIN_STATUS_RESOURCE_NAME_NOT_FOUND = 0xC000008B, - MD_NTSTATUS_WIN_STATUS_ARRAY_BOUNDS_EXCEEDED = 0xC000008C, - MD_NTSTATUS_WIN_STATUS_FLOAT_DENORMAL_OPERAND = 0xC000008D, - MD_NTSTATUS_WIN_STATUS_FLOAT_DIVIDE_BY_ZERO = 0xC000008E, - MD_NTSTATUS_WIN_STATUS_FLOAT_INEXACT_RESULT = 0xC000008F, - MD_NTSTATUS_WIN_STATUS_FLOAT_INVALID_OPERATION = 0xC0000090, - MD_NTSTATUS_WIN_STATUS_FLOAT_OVERFLOW = 0xC0000091, - MD_NTSTATUS_WIN_STATUS_FLOAT_STACK_CHECK = 0xC0000092, - MD_NTSTATUS_WIN_STATUS_FLOAT_UNDERFLOW = 0xC0000093, - MD_NTSTATUS_WIN_STATUS_INTEGER_DIVIDE_BY_ZERO = 0xC0000094, - MD_NTSTATUS_WIN_STATUS_INTEGER_OVERFLOW = 0xC0000095, - MD_NTSTATUS_WIN_STATUS_PRIVILEGED_INSTRUCTION = 0xC0000096, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_PAGING_FILES = 0xC0000097, - MD_NTSTATUS_WIN_STATUS_FILE_INVALID = 0xC0000098, - MD_NTSTATUS_WIN_STATUS_ALLOTTED_SPACE_EXCEEDED = 0xC0000099, - MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_RESOURCES = 0xC000009A, - MD_NTSTATUS_WIN_STATUS_DFS_EXIT_PATH_FOUND = 0xC000009B, - MD_NTSTATUS_WIN_STATUS_DEVICE_DATA_ERROR = 0xC000009C, - MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_CONNECTED = 0xC000009D, - MD_NTSTATUS_WIN_STATUS_DEVICE_POWER_FAILURE = 0xC000009E, - MD_NTSTATUS_WIN_STATUS_FREE_VM_NOT_AT_BASE = 0xC000009F, - MD_NTSTATUS_WIN_STATUS_MEMORY_NOT_ALLOCATED = 0xC00000A0, - MD_NTSTATUS_WIN_STATUS_WORKING_SET_QUOTA = 0xC00000A1, - MD_NTSTATUS_WIN_STATUS_MEDIA_WRITE_PROTECTED = 0xC00000A2, - MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_READY = 0xC00000A3, - MD_NTSTATUS_WIN_STATUS_INVALID_GROUP_ATTRIBUTES = 0xC00000A4, - MD_NTSTATUS_WIN_STATUS_BAD_IMPERSONATION_LEVEL = 0xC00000A5, - MD_NTSTATUS_WIN_STATUS_CANT_OPEN_ANONYMOUS = 0xC00000A6, - MD_NTSTATUS_WIN_STATUS_BAD_VALIDATION_CLASS = 0xC00000A7, - MD_NTSTATUS_WIN_STATUS_BAD_TOKEN_TYPE = 0xC00000A8, - MD_NTSTATUS_WIN_STATUS_BAD_MASTER_BOOT_RECORD = 0xC00000A9, - MD_NTSTATUS_WIN_STATUS_INSTRUCTION_MISALIGNMENT = 0xC00000AA, - MD_NTSTATUS_WIN_STATUS_INSTANCE_NOT_AVAILABLE = 0xC00000AB, - MD_NTSTATUS_WIN_STATUS_PIPE_NOT_AVAILABLE = 0xC00000AC, - MD_NTSTATUS_WIN_STATUS_INVALID_PIPE_STATE = 0xC00000AD, - MD_NTSTATUS_WIN_STATUS_PIPE_BUSY = 0xC00000AE, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_FUNCTION = 0xC00000AF, - MD_NTSTATUS_WIN_STATUS_PIPE_DISCONNECTED = 0xC00000B0, - MD_NTSTATUS_WIN_STATUS_PIPE_CLOSING = 0xC00000B1, - MD_NTSTATUS_WIN_STATUS_PIPE_CONNECTED = 0xC00000B2, - MD_NTSTATUS_WIN_STATUS_PIPE_LISTENING = 0xC00000B3, - MD_NTSTATUS_WIN_STATUS_INVALID_READ_MODE = 0xC00000B4, - MD_NTSTATUS_WIN_STATUS_IO_TIMEOUT = 0xC00000B5, - MD_NTSTATUS_WIN_STATUS_FILE_FORCED_CLOSED = 0xC00000B6, - MD_NTSTATUS_WIN_STATUS_PROFILING_NOT_STARTED = 0xC00000B7, - MD_NTSTATUS_WIN_STATUS_PROFILING_NOT_STOPPED = 0xC00000B8, - MD_NTSTATUS_WIN_STATUS_COULD_NOT_INTERPRET = 0xC00000B9, - MD_NTSTATUS_WIN_STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA, - MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED = 0xC00000BB, - MD_NTSTATUS_WIN_STATUS_REMOTE_NOT_LISTENING = 0xC00000BC, - MD_NTSTATUS_WIN_STATUS_DUPLICATE_NAME = 0xC00000BD, - MD_NTSTATUS_WIN_STATUS_BAD_NETWORK_PATH = 0xC00000BE, - MD_NTSTATUS_WIN_STATUS_NETWORK_BUSY = 0xC00000BF, - MD_NTSTATUS_WIN_STATUS_DEVICE_DOES_NOT_EXIST = 0xC00000C0, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_COMMANDS = 0xC00000C1, - MD_NTSTATUS_WIN_STATUS_ADAPTER_HARDWARE_ERROR = 0xC00000C2, - MD_NTSTATUS_WIN_STATUS_INVALID_NETWORK_RESPONSE = 0xC00000C3, - MD_NTSTATUS_WIN_STATUS_UNEXPECTED_NETWORK_ERROR = 0xC00000C4, - MD_NTSTATUS_WIN_STATUS_BAD_REMOTE_ADAPTER = 0xC00000C5, - MD_NTSTATUS_WIN_STATUS_PRINT_QUEUE_FULL = 0xC00000C6, - MD_NTSTATUS_WIN_STATUS_NO_SPOOL_SPACE = 0xC00000C7, - MD_NTSTATUS_WIN_STATUS_PRINT_CANCELLED = 0xC00000C8, - MD_NTSTATUS_WIN_STATUS_NETWORK_NAME_DELETED = 0xC00000C9, - MD_NTSTATUS_WIN_STATUS_NETWORK_ACCESS_DENIED = 0xC00000CA, - MD_NTSTATUS_WIN_STATUS_BAD_DEVICE_TYPE = 0xC00000CB, - MD_NTSTATUS_WIN_STATUS_BAD_NETWORK_NAME = 0xC00000CC, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_NAMES = 0xC00000CD, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_SESSIONS = 0xC00000CE, - MD_NTSTATUS_WIN_STATUS_SHARING_PAUSED = 0xC00000CF, - MD_NTSTATUS_WIN_STATUS_REQUEST_NOT_ACCEPTED = 0xC00000D0, - MD_NTSTATUS_WIN_STATUS_REDIRECTOR_PAUSED = 0xC00000D1, - MD_NTSTATUS_WIN_STATUS_NET_WRITE_FAULT = 0xC00000D2, - MD_NTSTATUS_WIN_STATUS_PROFILING_AT_LIMIT = 0xC00000D3, - MD_NTSTATUS_WIN_STATUS_NOT_SAME_DEVICE = 0xC00000D4, - MD_NTSTATUS_WIN_STATUS_FILE_RENAMED = 0xC00000D5, - MD_NTSTATUS_WIN_STATUS_VIRTUAL_CIRCUIT_CLOSED = 0xC00000D6, - MD_NTSTATUS_WIN_STATUS_NO_SECURITY_ON_OBJECT = 0xC00000D7, - MD_NTSTATUS_WIN_STATUS_CANT_WAIT = 0xC00000D8, - MD_NTSTATUS_WIN_STATUS_PIPE_EMPTY = 0xC00000D9, - MD_NTSTATUS_WIN_STATUS_CANT_ACCESS_DOMAIN_INFO = 0xC00000DA, - MD_NTSTATUS_WIN_STATUS_CANT_TERMINATE_SELF = 0xC00000DB, - MD_NTSTATUS_WIN_STATUS_INVALID_SERVER_STATE = 0xC00000DC, - MD_NTSTATUS_WIN_STATUS_INVALID_DOMAIN_STATE = 0xC00000DD, - MD_NTSTATUS_WIN_STATUS_INVALID_DOMAIN_ROLE = 0xC00000DE, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_DOMAIN = 0xC00000DF, - MD_NTSTATUS_WIN_STATUS_DOMAIN_EXISTS = 0xC00000E0, - MD_NTSTATUS_WIN_STATUS_DOMAIN_LIMIT_EXCEEDED = 0xC00000E1, - MD_NTSTATUS_WIN_STATUS_OPLOCK_NOT_GRANTED = 0xC00000E2, - MD_NTSTATUS_WIN_STATUS_INVALID_OPLOCK_PROTOCOL = 0xC00000E3, - MD_NTSTATUS_WIN_STATUS_INTERNAL_DB_CORRUPTION = 0xC00000E4, - MD_NTSTATUS_WIN_STATUS_INTERNAL_ERROR = 0xC00000E5, - MD_NTSTATUS_WIN_STATUS_GENERIC_NOT_MAPPED = 0xC00000E6, - MD_NTSTATUS_WIN_STATUS_BAD_DESCRIPTOR_FORMAT = 0xC00000E7, - MD_NTSTATUS_WIN_STATUS_INVALID_USER_BUFFER = 0xC00000E8, - MD_NTSTATUS_WIN_STATUS_UNEXPECTED_IO_ERROR = 0xC00000E9, - MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_CREATE_ERR = 0xC00000EA, - MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_MAP_ERROR = 0xC00000EB, - MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_EXTEND_ERR = 0xC00000EC, - MD_NTSTATUS_WIN_STATUS_NOT_LOGON_PROCESS = 0xC00000ED, - MD_NTSTATUS_WIN_STATUS_LOGON_SESSION_EXISTS = 0xC00000EE, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_1 = 0xC00000EF, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_2 = 0xC00000F0, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_3 = 0xC00000F1, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_4 = 0xC00000F2, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_5 = 0xC00000F3, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_6 = 0xC00000F4, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_7 = 0xC00000F5, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_8 = 0xC00000F6, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_9 = 0xC00000F7, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_10 = 0xC00000F8, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_11 = 0xC00000F9, - MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_12 = 0xC00000FA, - MD_NTSTATUS_WIN_STATUS_REDIRECTOR_NOT_STARTED = 0xC00000FB, - MD_NTSTATUS_WIN_STATUS_REDIRECTOR_STARTED = 0xC00000FC, - MD_NTSTATUS_WIN_STATUS_STACK_OVERFLOW = 0xC00000FD, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_PACKAGE = 0xC00000FE, - MD_NTSTATUS_WIN_STATUS_BAD_FUNCTION_TABLE = 0xC00000FF, - MD_NTSTATUS_WIN_STATUS_VARIABLE_NOT_FOUND = 0xC0000100, - MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_EMPTY = 0xC0000101, - MD_NTSTATUS_WIN_STATUS_FILE_CORRUPT_ERROR = 0xC0000102, - MD_NTSTATUS_WIN_STATUS_NOT_A_DIRECTORY = 0xC0000103, - MD_NTSTATUS_WIN_STATUS_BAD_LOGON_SESSION_STATE = 0xC0000104, - MD_NTSTATUS_WIN_STATUS_LOGON_SESSION_COLLISION = 0xC0000105, - MD_NTSTATUS_WIN_STATUS_NAME_TOO_LONG = 0xC0000106, - MD_NTSTATUS_WIN_STATUS_FILES_OPEN = 0xC0000107, - MD_NTSTATUS_WIN_STATUS_CONNECTION_IN_USE = 0xC0000108, - MD_NTSTATUS_WIN_STATUS_MESSAGE_NOT_FOUND = 0xC0000109, - MD_NTSTATUS_WIN_STATUS_PROCESS_IS_TERMINATING = 0xC000010A, - MD_NTSTATUS_WIN_STATUS_INVALID_LOGON_TYPE = 0xC000010B, - MD_NTSTATUS_WIN_STATUS_NO_GUID_TRANSLATION = 0xC000010C, - MD_NTSTATUS_WIN_STATUS_CANNOT_IMPERSONATE = 0xC000010D, - MD_NTSTATUS_WIN_STATUS_IMAGE_ALREADY_LOADED = 0xC000010E, - MD_NTSTATUS_WIN_STATUS_ABIOS_NOT_PRESENT = 0xC000010F, - MD_NTSTATUS_WIN_STATUS_ABIOS_LID_NOT_EXIST = 0xC0000110, - MD_NTSTATUS_WIN_STATUS_ABIOS_LID_ALREADY_OWNED = 0xC0000111, - MD_NTSTATUS_WIN_STATUS_ABIOS_NOT_LID_OWNER = 0xC0000112, - MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_COMMAND = 0xC0000113, - MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_LID = 0xC0000114, - MD_NTSTATUS_WIN_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE = 0xC0000115, - MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_SELECTOR = 0xC0000116, - MD_NTSTATUS_WIN_STATUS_NO_LDT = 0xC0000117, - MD_NTSTATUS_WIN_STATUS_INVALID_LDT_SIZE = 0xC0000118, - MD_NTSTATUS_WIN_STATUS_INVALID_LDT_OFFSET = 0xC0000119, - MD_NTSTATUS_WIN_STATUS_INVALID_LDT_DESCRIPTOR = 0xC000011A, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_NE_FORMAT = 0xC000011B, - MD_NTSTATUS_WIN_STATUS_RXACT_INVALID_STATE = 0xC000011C, - MD_NTSTATUS_WIN_STATUS_RXACT_COMMIT_FAILURE = 0xC000011D, - MD_NTSTATUS_WIN_STATUS_MAPPED_FILE_SIZE_ZERO = 0xC000011E, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_OPENED_FILES = 0xC000011F, - MD_NTSTATUS_WIN_STATUS_CANCELLED = 0xC0000120, - MD_NTSTATUS_WIN_STATUS_CANNOT_DELETE = 0xC0000121, - MD_NTSTATUS_WIN_STATUS_INVALID_COMPUTER_NAME = 0xC0000122, - MD_NTSTATUS_WIN_STATUS_FILE_DELETED = 0xC0000123, - MD_NTSTATUS_WIN_STATUS_SPECIAL_ACCOUNT = 0xC0000124, - MD_NTSTATUS_WIN_STATUS_SPECIAL_GROUP = 0xC0000125, - MD_NTSTATUS_WIN_STATUS_SPECIAL_USER = 0xC0000126, - MD_NTSTATUS_WIN_STATUS_MEMBERS_PRIMARY_GROUP = 0xC0000127, - MD_NTSTATUS_WIN_STATUS_FILE_CLOSED = 0xC0000128, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_THREADS = 0xC0000129, - MD_NTSTATUS_WIN_STATUS_THREAD_NOT_IN_PROCESS = 0xC000012A, - MD_NTSTATUS_WIN_STATUS_TOKEN_ALREADY_IN_USE = 0xC000012B, - MD_NTSTATUS_WIN_STATUS_PAGEFILE_QUOTA_EXCEEDED = 0xC000012C, - MD_NTSTATUS_WIN_STATUS_COMMITMENT_LIMIT = 0xC000012D, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_LE_FORMAT = 0xC000012E, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_NOT_MZ = 0xC000012F, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_PROTECT = 0xC0000130, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_16 = 0xC0000131, - MD_NTSTATUS_WIN_STATUS_LOGON_SERVER_CONFLICT = 0xC0000132, - MD_NTSTATUS_WIN_STATUS_TIME_DIFFERENCE_AT_DC = 0xC0000133, - MD_NTSTATUS_WIN_STATUS_SYNCHRONIZATION_REQUIRED = 0xC0000134, - MD_NTSTATUS_WIN_STATUS_DLL_NOT_FOUND = 0xC0000135, - MD_NTSTATUS_WIN_STATUS_OPEN_FAILED = 0xC0000136, - MD_NTSTATUS_WIN_STATUS_IO_PRIVILEGE_FAILED = 0xC0000137, - MD_NTSTATUS_WIN_STATUS_ORDINAL_NOT_FOUND = 0xC0000138, - MD_NTSTATUS_WIN_STATUS_ENTRYPOINT_NOT_FOUND = 0xC0000139, - MD_NTSTATUS_WIN_STATUS_CONTROL_C_EXIT = 0xC000013A, - MD_NTSTATUS_WIN_STATUS_LOCAL_DISCONNECT = 0xC000013B, - MD_NTSTATUS_WIN_STATUS_REMOTE_DISCONNECT = 0xC000013C, - MD_NTSTATUS_WIN_STATUS_REMOTE_RESOURCES = 0xC000013D, - MD_NTSTATUS_WIN_STATUS_LINK_FAILED = 0xC000013E, - MD_NTSTATUS_WIN_STATUS_LINK_TIMEOUT = 0xC000013F, - MD_NTSTATUS_WIN_STATUS_INVALID_CONNECTION = 0xC0000140, - MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS = 0xC0000141, - MD_NTSTATUS_WIN_STATUS_DLL_INIT_FAILED = 0xC0000142, - MD_NTSTATUS_WIN_STATUS_MISSING_SYSTEMFILE = 0xC0000143, - MD_NTSTATUS_WIN_STATUS_UNHANDLED_EXCEPTION = 0xC0000144, - MD_NTSTATUS_WIN_STATUS_APP_INIT_FAILURE = 0xC0000145, - MD_NTSTATUS_WIN_STATUS_PAGEFILE_CREATE_FAILED = 0xC0000146, - MD_NTSTATUS_WIN_STATUS_NO_PAGEFILE = 0xC0000147, - MD_NTSTATUS_WIN_STATUS_INVALID_LEVEL = 0xC0000148, - MD_NTSTATUS_WIN_STATUS_WRONG_PASSWORD_CORE = 0xC0000149, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_FLOAT_CONTEXT = 0xC000014A, - MD_NTSTATUS_WIN_STATUS_PIPE_BROKEN = 0xC000014B, - MD_NTSTATUS_WIN_STATUS_REGISTRY_CORRUPT = 0xC000014C, - MD_NTSTATUS_WIN_STATUS_REGISTRY_IO_FAILED = 0xC000014D, - MD_NTSTATUS_WIN_STATUS_NO_EVENT_PAIR = 0xC000014E, - MD_NTSTATUS_WIN_STATUS_UNRECOGNIZED_VOLUME = 0xC000014F, - MD_NTSTATUS_WIN_STATUS_SERIAL_NO_DEVICE_INITED = 0xC0000150, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_ALIAS = 0xC0000151, - MD_NTSTATUS_WIN_STATUS_MEMBER_NOT_IN_ALIAS = 0xC0000152, - MD_NTSTATUS_WIN_STATUS_MEMBER_IN_ALIAS = 0xC0000153, - MD_NTSTATUS_WIN_STATUS_ALIAS_EXISTS = 0xC0000154, - MD_NTSTATUS_WIN_STATUS_LOGON_NOT_GRANTED = 0xC0000155, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_SECRETS = 0xC0000156, - MD_NTSTATUS_WIN_STATUS_SECRET_TOO_LONG = 0xC0000157, - MD_NTSTATUS_WIN_STATUS_INTERNAL_DB_ERROR = 0xC0000158, - MD_NTSTATUS_WIN_STATUS_FULLSCREEN_MODE = 0xC0000159, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_CONTEXT_IDS = 0xC000015A, - MD_NTSTATUS_WIN_STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B, - MD_NTSTATUS_WIN_STATUS_NOT_REGISTRY_FILE = 0xC000015C, - MD_NTSTATUS_WIN_STATUS_NT_CROSS_ENCRYPTION_REQUIRED = 0xC000015D, - MD_NTSTATUS_WIN_STATUS_DOMAIN_CTRLR_CONFIG_ERROR = 0xC000015E, - MD_NTSTATUS_WIN_STATUS_FT_MISSING_MEMBER = 0xC000015F, - MD_NTSTATUS_WIN_STATUS_ILL_FORMED_SERVICE_ENTRY = 0xC0000160, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_CHARACTER = 0xC0000161, - MD_NTSTATUS_WIN_STATUS_UNMAPPABLE_CHARACTER = 0xC0000162, - MD_NTSTATUS_WIN_STATUS_UNDEFINED_CHARACTER = 0xC0000163, - MD_NTSTATUS_WIN_STATUS_FLOPPY_VOLUME = 0xC0000164, - MD_NTSTATUS_WIN_STATUS_FLOPPY_ID_MARK_NOT_FOUND = 0xC0000165, - MD_NTSTATUS_WIN_STATUS_FLOPPY_WRONG_CYLINDER = 0xC0000166, - MD_NTSTATUS_WIN_STATUS_FLOPPY_UNKNOWN_ERROR = 0xC0000167, - MD_NTSTATUS_WIN_STATUS_FLOPPY_BAD_REGISTERS = 0xC0000168, - MD_NTSTATUS_WIN_STATUS_DISK_RECALIBRATE_FAILED = 0xC0000169, - MD_NTSTATUS_WIN_STATUS_DISK_OPERATION_FAILED = 0xC000016A, - MD_NTSTATUS_WIN_STATUS_DISK_RESET_FAILED = 0xC000016B, - MD_NTSTATUS_WIN_STATUS_SHARED_IRQ_BUSY = 0xC000016C, - MD_NTSTATUS_WIN_STATUS_FT_ORPHANING = 0xC000016D, - MD_NTSTATUS_WIN_STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT = 0xC000016E, - MD_NTSTATUS_WIN_STATUS_PARTITION_FAILURE = 0xC0000172, - MD_NTSTATUS_WIN_STATUS_INVALID_BLOCK_LENGTH = 0xC0000173, - MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_PARTITIONED = 0xC0000174, - MD_NTSTATUS_WIN_STATUS_UNABLE_TO_LOCK_MEDIA = 0xC0000175, - MD_NTSTATUS_WIN_STATUS_UNABLE_TO_UNLOAD_MEDIA = 0xC0000176, - MD_NTSTATUS_WIN_STATUS_EOM_OVERFLOW = 0xC0000177, - MD_NTSTATUS_WIN_STATUS_NO_MEDIA = 0xC0000178, - MD_NTSTATUS_WIN_STATUS_NO_SUCH_MEMBER = 0xC000017A, - MD_NTSTATUS_WIN_STATUS_INVALID_MEMBER = 0xC000017B, - MD_NTSTATUS_WIN_STATUS_KEY_DELETED = 0xC000017C, - MD_NTSTATUS_WIN_STATUS_NO_LOG_SPACE = 0xC000017D, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_SIDS = 0xC000017E, - MD_NTSTATUS_WIN_STATUS_LM_CROSS_ENCRYPTION_REQUIRED = 0xC000017F, - MD_NTSTATUS_WIN_STATUS_KEY_HAS_CHILDREN = 0xC0000180, - MD_NTSTATUS_WIN_STATUS_CHILD_MUST_BE_VOLATILE = 0xC0000181, - MD_NTSTATUS_WIN_STATUS_DEVICE_CONFIGURATION_ERROR = 0xC0000182, - MD_NTSTATUS_WIN_STATUS_DRIVER_INTERNAL_ERROR = 0xC0000183, - MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_STATE = 0xC0000184, - MD_NTSTATUS_WIN_STATUS_IO_DEVICE_ERROR = 0xC0000185, - MD_NTSTATUS_WIN_STATUS_DEVICE_PROTOCOL_ERROR = 0xC0000186, - MD_NTSTATUS_WIN_STATUS_BACKUP_CONTROLLER = 0xC0000187, - MD_NTSTATUS_WIN_STATUS_LOG_FILE_FULL = 0xC0000188, - MD_NTSTATUS_WIN_STATUS_TOO_LATE = 0xC0000189, - MD_NTSTATUS_WIN_STATUS_NO_TRUST_LSA_SECRET = 0xC000018A, - MD_NTSTATUS_WIN_STATUS_NO_TRUST_SAM_ACCOUNT = 0xC000018B, - MD_NTSTATUS_WIN_STATUS_TRUSTED_DOMAIN_FAILURE = 0xC000018C, - MD_NTSTATUS_WIN_STATUS_TRUSTED_RELATIONSHIP_FAILURE = 0xC000018D, - MD_NTSTATUS_WIN_STATUS_EVENTLOG_FILE_CORRUPT = 0xC000018E, - MD_NTSTATUS_WIN_STATUS_EVENTLOG_CANT_START = 0xC000018F, - MD_NTSTATUS_WIN_STATUS_TRUST_FAILURE = 0xC0000190, - MD_NTSTATUS_WIN_STATUS_MUTANT_LIMIT_EXCEEDED = 0xC0000191, - MD_NTSTATUS_WIN_STATUS_NETLOGON_NOT_STARTED = 0xC0000192, - MD_NTSTATUS_WIN_STATUS_ACCOUNT_EXPIRED = 0xC0000193, - MD_NTSTATUS_WIN_STATUS_POSSIBLE_DEADLOCK = 0xC0000194, - MD_NTSTATUS_WIN_STATUS_NETWORK_CREDENTIAL_CONFLICT = 0xC0000195, - MD_NTSTATUS_WIN_STATUS_REMOTE_SESSION_LIMIT = 0xC0000196, - MD_NTSTATUS_WIN_STATUS_EVENTLOG_FILE_CHANGED = 0xC0000197, - MD_NTSTATUS_WIN_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 0xC0000198, - MD_NTSTATUS_WIN_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xC0000199, - MD_NTSTATUS_WIN_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT = 0xC000019A, - MD_NTSTATUS_WIN_STATUS_DOMAIN_TRUST_INCONSISTENT = 0xC000019B, - MD_NTSTATUS_WIN_STATUS_FS_DRIVER_REQUIRED = 0xC000019C, - MD_NTSTATUS_WIN_STATUS_IMAGE_ALREADY_LOADED_AS_DLL = 0xC000019D, - MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 0xC000019E, - MD_NTSTATUS_WIN_STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 0xC000019F, - MD_NTSTATUS_WIN_STATUS_SECURITY_STREAM_IS_INCONSISTENT = 0xC00001A0, - MD_NTSTATUS_WIN_STATUS_INVALID_LOCK_RANGE = 0xC00001A1, - MD_NTSTATUS_WIN_STATUS_INVALID_ACE_CONDITION = 0xC00001A2, - MD_NTSTATUS_WIN_STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT = 0xC00001A3, - MD_NTSTATUS_WIN_STATUS_NOTIFICATION_GUID_ALREADY_DEFINED = 0xC00001A4, - MD_NTSTATUS_WIN_STATUS_INVALID_EXCEPTION_HANDLER = 0xC00001A5, - MD_NTSTATUS_WIN_STATUS_DUPLICATE_PRIVILEGES = 0xC00001A6, - MD_NTSTATUS_WIN_STATUS_NOT_ALLOWED_ON_SYSTEM_FILE = 0xC00001A7, - MD_NTSTATUS_WIN_STATUS_REPAIR_NEEDED = 0xC00001A8, - MD_NTSTATUS_WIN_STATUS_QUOTA_NOT_ENABLED = 0xC00001A9, - MD_NTSTATUS_WIN_STATUS_NO_APPLICATION_PACKAGE = 0xC00001AA, - MD_NTSTATUS_WIN_STATUS_NETWORK_OPEN_RESTRICTION = 0xC0000201, - MD_NTSTATUS_WIN_STATUS_NO_USER_SESSION_KEY = 0xC0000202, - MD_NTSTATUS_WIN_STATUS_USER_SESSION_DELETED = 0xC0000203, - MD_NTSTATUS_WIN_STATUS_RESOURCE_LANG_NOT_FOUND = 0xC0000204, - MD_NTSTATUS_WIN_STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205, - MD_NTSTATUS_WIN_STATUS_INVALID_BUFFER_SIZE = 0xC0000206, - MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS_COMPONENT = 0xC0000207, - MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS_WILDCARD = 0xC0000208, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_ADDRESSES = 0xC0000209, - MD_NTSTATUS_WIN_STATUS_ADDRESS_ALREADY_EXISTS = 0xC000020A, - MD_NTSTATUS_WIN_STATUS_ADDRESS_CLOSED = 0xC000020B, - MD_NTSTATUS_WIN_STATUS_CONNECTION_DISCONNECTED = 0xC000020C, - MD_NTSTATUS_WIN_STATUS_CONNECTION_RESET = 0xC000020D, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_NODES = 0xC000020E, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_ABORTED = 0xC000020F, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_TIMED_OUT = 0xC0000210, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_RELEASE = 0xC0000211, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_MATCH = 0xC0000212, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_RESPONDED = 0xC0000213, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_ID = 0xC0000214, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_TYPE = 0xC0000215, - MD_NTSTATUS_WIN_STATUS_NOT_SERVER_SESSION = 0xC0000216, - MD_NTSTATUS_WIN_STATUS_NOT_CLIENT_SESSION = 0xC0000217, - MD_NTSTATUS_WIN_STATUS_CANNOT_LOAD_REGISTRY_FILE = 0xC0000218, - MD_NTSTATUS_WIN_STATUS_DEBUG_ATTACH_FAILED = 0xC0000219, - MD_NTSTATUS_WIN_STATUS_SYSTEM_PROCESS_TERMINATED = 0xC000021A, - MD_NTSTATUS_WIN_STATUS_DATA_NOT_ACCEPTED = 0xC000021B, - MD_NTSTATUS_WIN_STATUS_NO_BROWSER_SERVERS_FOUND = 0xC000021C, - MD_NTSTATUS_WIN_STATUS_VDM_HARD_ERROR = 0xC000021D, - MD_NTSTATUS_WIN_STATUS_DRIVER_CANCEL_TIMEOUT = 0xC000021E, - MD_NTSTATUS_WIN_STATUS_REPLY_MESSAGE_MISMATCH = 0xC000021F, - MD_NTSTATUS_WIN_STATUS_MAPPED_ALIGNMENT = 0xC0000220, - MD_NTSTATUS_WIN_STATUS_IMAGE_CHECKSUM_MISMATCH = 0xC0000221, - MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA = 0xC0000222, - MD_NTSTATUS_WIN_STATUS_CLIENT_SERVER_PARAMETERS_INVALID = 0xC0000223, - MD_NTSTATUS_WIN_STATUS_PASSWORD_MUST_CHANGE = 0xC0000224, - MD_NTSTATUS_WIN_STATUS_NOT_FOUND = 0xC0000225, - MD_NTSTATUS_WIN_STATUS_NOT_TINY_STREAM = 0xC0000226, - MD_NTSTATUS_WIN_STATUS_RECOVERY_FAILURE = 0xC0000227, - MD_NTSTATUS_WIN_STATUS_STACK_OVERFLOW_READ = 0xC0000228, - MD_NTSTATUS_WIN_STATUS_FAIL_CHECK = 0xC0000229, - MD_NTSTATUS_WIN_STATUS_DUPLICATE_OBJECTID = 0xC000022A, - MD_NTSTATUS_WIN_STATUS_OBJECTID_EXISTS = 0xC000022B, - MD_NTSTATUS_WIN_STATUS_CONVERT_TO_LARGE = 0xC000022C, - MD_NTSTATUS_WIN_STATUS_RETRY = 0xC000022D, - MD_NTSTATUS_WIN_STATUS_FOUND_OUT_OF_SCOPE = 0xC000022E, - MD_NTSTATUS_WIN_STATUS_ALLOCATE_BUCKET = 0xC000022F, - MD_NTSTATUS_WIN_STATUS_PROPSET_NOT_FOUND = 0xC0000230, - MD_NTSTATUS_WIN_STATUS_MARSHALL_OVERFLOW = 0xC0000231, - MD_NTSTATUS_WIN_STATUS_INVALID_VARIANT = 0xC0000232, - MD_NTSTATUS_WIN_STATUS_DOMAIN_CONTROLLER_NOT_FOUND = 0xC0000233, - MD_NTSTATUS_WIN_STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234, - MD_NTSTATUS_WIN_STATUS_HANDLE_NOT_CLOSABLE = 0xC0000235, - MD_NTSTATUS_WIN_STATUS_CONNECTION_REFUSED = 0xC0000236, - MD_NTSTATUS_WIN_STATUS_GRACEFUL_DISCONNECT = 0xC0000237, - MD_NTSTATUS_WIN_STATUS_ADDRESS_ALREADY_ASSOCIATED = 0xC0000238, - MD_NTSTATUS_WIN_STATUS_ADDRESS_NOT_ASSOCIATED = 0xC0000239, - MD_NTSTATUS_WIN_STATUS_CONNECTION_INVALID = 0xC000023A, - MD_NTSTATUS_WIN_STATUS_CONNECTION_ACTIVE = 0xC000023B, - MD_NTSTATUS_WIN_STATUS_NETWORK_UNREACHABLE = 0xC000023C, - MD_NTSTATUS_WIN_STATUS_HOST_UNREACHABLE = 0xC000023D, - MD_NTSTATUS_WIN_STATUS_PROTOCOL_UNREACHABLE = 0xC000023E, - MD_NTSTATUS_WIN_STATUS_PORT_UNREACHABLE = 0xC000023F, - MD_NTSTATUS_WIN_STATUS_REQUEST_ABORTED = 0xC0000240, - MD_NTSTATUS_WIN_STATUS_CONNECTION_ABORTED = 0xC0000241, - MD_NTSTATUS_WIN_STATUS_BAD_COMPRESSION_BUFFER = 0xC0000242, - MD_NTSTATUS_WIN_STATUS_USER_MAPPED_FILE = 0xC0000243, - MD_NTSTATUS_WIN_STATUS_AUDIT_FAILED = 0xC0000244, - MD_NTSTATUS_WIN_STATUS_TIMER_RESOLUTION_NOT_SET = 0xC0000245, - MD_NTSTATUS_WIN_STATUS_CONNECTION_COUNT_LIMIT = 0xC0000246, - MD_NTSTATUS_WIN_STATUS_LOGIN_TIME_RESTRICTION = 0xC0000247, - MD_NTSTATUS_WIN_STATUS_LOGIN_WKSTA_RESTRICTION = 0xC0000248, - MD_NTSTATUS_WIN_STATUS_IMAGE_MP_UP_MISMATCH = 0xC0000249, - MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_LOGON_INFO = 0xC0000250, - MD_NTSTATUS_WIN_STATUS_BAD_DLL_ENTRYPOINT = 0xC0000251, - MD_NTSTATUS_WIN_STATUS_BAD_SERVICE_ENTRYPOINT = 0xC0000252, - MD_NTSTATUS_WIN_STATUS_LPC_REPLY_LOST = 0xC0000253, - MD_NTSTATUS_WIN_STATUS_IP_ADDRESS_CONFLICT1 = 0xC0000254, - MD_NTSTATUS_WIN_STATUS_IP_ADDRESS_CONFLICT2 = 0xC0000255, - MD_NTSTATUS_WIN_STATUS_REGISTRY_QUOTA_LIMIT = 0xC0000256, - MD_NTSTATUS_WIN_STATUS_PATH_NOT_COVERED = 0xC0000257, - MD_NTSTATUS_WIN_STATUS_NO_CALLBACK_ACTIVE = 0xC0000258, - MD_NTSTATUS_WIN_STATUS_LICENSE_QUOTA_EXCEEDED = 0xC0000259, - MD_NTSTATUS_WIN_STATUS_PWD_TOO_SHORT = 0xC000025A, - MD_NTSTATUS_WIN_STATUS_PWD_TOO_RECENT = 0xC000025B, - MD_NTSTATUS_WIN_STATUS_PWD_HISTORY_CONFLICT = 0xC000025C, - MD_NTSTATUS_WIN_STATUS_PLUGPLAY_NO_DEVICE = 0xC000025E, - MD_NTSTATUS_WIN_STATUS_UNSUPPORTED_COMPRESSION = 0xC000025F, - MD_NTSTATUS_WIN_STATUS_INVALID_HW_PROFILE = 0xC0000260, - MD_NTSTATUS_WIN_STATUS_INVALID_PLUGPLAY_DEVICE_PATH = 0xC0000261, - MD_NTSTATUS_WIN_STATUS_DRIVER_ORDINAL_NOT_FOUND = 0xC0000262, - MD_NTSTATUS_WIN_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND = 0xC0000263, - MD_NTSTATUS_WIN_STATUS_RESOURCE_NOT_OWNED = 0xC0000264, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_LINKS = 0xC0000265, - MD_NTSTATUS_WIN_STATUS_QUOTA_LIST_INCONSISTENT = 0xC0000266, - MD_NTSTATUS_WIN_STATUS_FILE_IS_OFFLINE = 0xC0000267, - MD_NTSTATUS_WIN_STATUS_EVALUATION_EXPIRATION = 0xC0000268, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_DLL_RELOCATION = 0xC0000269, - MD_NTSTATUS_WIN_STATUS_LICENSE_VIOLATION = 0xC000026A, - MD_NTSTATUS_WIN_STATUS_DLL_INIT_FAILED_LOGOFF = 0xC000026B, - MD_NTSTATUS_WIN_STATUS_DRIVER_UNABLE_TO_LOAD = 0xC000026C, - MD_NTSTATUS_WIN_STATUS_DFS_UNAVAILABLE = 0xC000026D, - MD_NTSTATUS_WIN_STATUS_VOLUME_DISMOUNTED = 0xC000026E, - MD_NTSTATUS_WIN_STATUS_WX86_INTERNAL_ERROR = 0xC000026F, - MD_NTSTATUS_WIN_STATUS_WX86_FLOAT_STACK_CHECK = 0xC0000270, - MD_NTSTATUS_WIN_STATUS_VALIDATE_CONTINUE = 0xC0000271, - MD_NTSTATUS_WIN_STATUS_NO_MATCH = 0xC0000272, - MD_NTSTATUS_WIN_STATUS_NO_MORE_MATCHES = 0xC0000273, - MD_NTSTATUS_WIN_STATUS_NOT_A_REPARSE_POINT = 0xC0000275, - MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_INVALID = 0xC0000276, - MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_MISMATCH = 0xC0000277, - MD_NTSTATUS_WIN_STATUS_IO_REPARSE_DATA_INVALID = 0xC0000278, - MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_NOT_HANDLED = 0xC0000279, - MD_NTSTATUS_WIN_STATUS_PWD_TOO_LONG = 0xC000027A, - MD_NTSTATUS_WIN_STATUS_STOWED_EXCEPTION = 0xC000027B, - MD_NTSTATUS_WIN_STATUS_REPARSE_POINT_NOT_RESOLVED = 0xC0000280, - MD_NTSTATUS_WIN_STATUS_DIRECTORY_IS_A_REPARSE_POINT = 0xC0000281, - MD_NTSTATUS_WIN_STATUS_RANGE_LIST_CONFLICT = 0xC0000282, - MD_NTSTATUS_WIN_STATUS_SOURCE_ELEMENT_EMPTY = 0xC0000283, - MD_NTSTATUS_WIN_STATUS_DESTINATION_ELEMENT_FULL = 0xC0000284, - MD_NTSTATUS_WIN_STATUS_ILLEGAL_ELEMENT_ADDRESS = 0xC0000285, - MD_NTSTATUS_WIN_STATUS_MAGAZINE_NOT_PRESENT = 0xC0000286, - MD_NTSTATUS_WIN_STATUS_REINITIALIZATION_NEEDED = 0xC0000287, - MD_NTSTATUS_WIN_STATUS_ENCRYPTION_FAILED = 0xC000028A, - MD_NTSTATUS_WIN_STATUS_DECRYPTION_FAILED = 0xC000028B, - MD_NTSTATUS_WIN_STATUS_RANGE_NOT_FOUND = 0xC000028C, - MD_NTSTATUS_WIN_STATUS_NO_RECOVERY_POLICY = 0xC000028D, - MD_NTSTATUS_WIN_STATUS_NO_EFS = 0xC000028E, - MD_NTSTATUS_WIN_STATUS_WRONG_EFS = 0xC000028F, - MD_NTSTATUS_WIN_STATUS_NO_USER_KEYS = 0xC0000290, - MD_NTSTATUS_WIN_STATUS_FILE_NOT_ENCRYPTED = 0xC0000291, - MD_NTSTATUS_WIN_STATUS_NOT_EXPORT_FORMAT = 0xC0000292, - MD_NTSTATUS_WIN_STATUS_FILE_ENCRYPTED = 0xC0000293, - MD_NTSTATUS_WIN_STATUS_WMI_GUID_NOT_FOUND = 0xC0000295, - MD_NTSTATUS_WIN_STATUS_WMI_INSTANCE_NOT_FOUND = 0xC0000296, - MD_NTSTATUS_WIN_STATUS_WMI_ITEMID_NOT_FOUND = 0xC0000297, - MD_NTSTATUS_WIN_STATUS_WMI_TRY_AGAIN = 0xC0000298, - MD_NTSTATUS_WIN_STATUS_SHARED_POLICY = 0xC0000299, - MD_NTSTATUS_WIN_STATUS_POLICY_OBJECT_NOT_FOUND = 0xC000029A, - MD_NTSTATUS_WIN_STATUS_POLICY_ONLY_IN_DS = 0xC000029B, - MD_NTSTATUS_WIN_STATUS_VOLUME_NOT_UPGRADED = 0xC000029C, - MD_NTSTATUS_WIN_STATUS_REMOTE_STORAGE_NOT_ACTIVE = 0xC000029D, - MD_NTSTATUS_WIN_STATUS_REMOTE_STORAGE_MEDIA_ERROR = 0xC000029E, - MD_NTSTATUS_WIN_STATUS_NO_TRACKING_SERVICE = 0xC000029F, - MD_NTSTATUS_WIN_STATUS_SERVER_SID_MISMATCH = 0xC00002A0, - MD_NTSTATUS_WIN_STATUS_DS_NO_ATTRIBUTE_OR_VALUE = 0xC00002A1, - MD_NTSTATUS_WIN_STATUS_DS_INVALID_ATTRIBUTE_SYNTAX = 0xC00002A2, - MD_NTSTATUS_WIN_STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED = 0xC00002A3, - MD_NTSTATUS_WIN_STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS = 0xC00002A4, - MD_NTSTATUS_WIN_STATUS_DS_BUSY = 0xC00002A5, - MD_NTSTATUS_WIN_STATUS_DS_UNAVAILABLE = 0xC00002A6, - MD_NTSTATUS_WIN_STATUS_DS_NO_RIDS_ALLOCATED = 0xC00002A7, - MD_NTSTATUS_WIN_STATUS_DS_NO_MORE_RIDS = 0xC00002A8, - MD_NTSTATUS_WIN_STATUS_DS_INCORRECT_ROLE_OWNER = 0xC00002A9, - MD_NTSTATUS_WIN_STATUS_DS_RIDMGR_INIT_ERROR = 0xC00002AA, - MD_NTSTATUS_WIN_STATUS_DS_OBJ_CLASS_VIOLATION = 0xC00002AB, - MD_NTSTATUS_WIN_STATUS_DS_CANT_ON_NON_LEAF = 0xC00002AC, - MD_NTSTATUS_WIN_STATUS_DS_CANT_ON_RDN = 0xC00002AD, - MD_NTSTATUS_WIN_STATUS_DS_CANT_MOD_OBJ_CLASS = 0xC00002AE, - MD_NTSTATUS_WIN_STATUS_DS_CROSS_DOM_MOVE_FAILED = 0xC00002AF, - MD_NTSTATUS_WIN_STATUS_DS_GC_NOT_AVAILABLE = 0xC00002B0, - MD_NTSTATUS_WIN_STATUS_DIRECTORY_SERVICE_REQUIRED = 0xC00002B1, - MD_NTSTATUS_WIN_STATUS_REPARSE_ATTRIBUTE_CONFLICT = 0xC00002B2, - MD_NTSTATUS_WIN_STATUS_CANT_ENABLE_DENY_ONLY = 0xC00002B3, - MD_NTSTATUS_WIN_STATUS_FLOAT_MULTIPLE_FAULTS = 0xC00002B4, - MD_NTSTATUS_WIN_STATUS_FLOAT_MULTIPLE_TRAPS = 0xC00002B5, - MD_NTSTATUS_WIN_STATUS_DEVICE_REMOVED = 0xC00002B6, - MD_NTSTATUS_WIN_STATUS_JOURNAL_DELETE_IN_PROGRESS = 0xC00002B7, - MD_NTSTATUS_WIN_STATUS_JOURNAL_NOT_ACTIVE = 0xC00002B8, - MD_NTSTATUS_WIN_STATUS_NOINTERFACE = 0xC00002B9, - MD_NTSTATUS_WIN_STATUS_DS_RIDMGR_DISABLED = 0xC00002BA, - MD_NTSTATUS_WIN_STATUS_DS_ADMIN_LIMIT_EXCEEDED = 0xC00002C1, - MD_NTSTATUS_WIN_STATUS_DRIVER_FAILED_SLEEP = 0xC00002C2, - MD_NTSTATUS_WIN_STATUS_MUTUAL_AUTHENTICATION_FAILED = 0xC00002C3, - MD_NTSTATUS_WIN_STATUS_CORRUPT_SYSTEM_FILE = 0xC00002C4, - MD_NTSTATUS_WIN_STATUS_DATATYPE_MISALIGNMENT_ERROR = 0xC00002C5, - MD_NTSTATUS_WIN_STATUS_WMI_READ_ONLY = 0xC00002C6, - MD_NTSTATUS_WIN_STATUS_WMI_SET_FAILURE = 0xC00002C7, - MD_NTSTATUS_WIN_STATUS_COMMITMENT_MINIMUM = 0xC00002C8, - MD_NTSTATUS_WIN_STATUS_REG_NAT_CONSUMPTION = 0xC00002C9, - MD_NTSTATUS_WIN_STATUS_TRANSPORT_FULL = 0xC00002CA, - MD_NTSTATUS_WIN_STATUS_DS_SAM_INIT_FAILURE = 0xC00002CB, - MD_NTSTATUS_WIN_STATUS_ONLY_IF_CONNECTED = 0xC00002CC, - MD_NTSTATUS_WIN_STATUS_DS_SENSITIVE_GROUP_VIOLATION = 0xC00002CD, - MD_NTSTATUS_WIN_STATUS_PNP_RESTART_ENUMERATION = 0xC00002CE, - MD_NTSTATUS_WIN_STATUS_JOURNAL_ENTRY_DELETED = 0xC00002CF, - MD_NTSTATUS_WIN_STATUS_DS_CANT_MOD_PRIMARYGROUPID = 0xC00002D0, - MD_NTSTATUS_WIN_STATUS_SYSTEM_IMAGE_BAD_SIGNATURE = 0xC00002D1, - MD_NTSTATUS_WIN_STATUS_PNP_REBOOT_REQUIRED = 0xC00002D2, - MD_NTSTATUS_WIN_STATUS_POWER_STATE_INVALID = 0xC00002D3, - MD_NTSTATUS_WIN_STATUS_DS_INVALID_GROUP_TYPE = 0xC00002D4, - MD_NTSTATUS_WIN_STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 0xC00002D5, - MD_NTSTATUS_WIN_STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 0xC00002D6, - MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D7, - MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 0xC00002D8, - MD_NTSTATUS_WIN_STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D9, - MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 0xC00002DA, - MD_NTSTATUS_WIN_STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 0xC00002DB, - MD_NTSTATUS_WIN_STATUS_DS_HAVE_PRIMARY_MEMBERS = 0xC00002DC, - MD_NTSTATUS_WIN_STATUS_WMI_NOT_SUPPORTED = 0xC00002DD, - MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_POWER = 0xC00002DE, - MD_NTSTATUS_WIN_STATUS_SAM_NEED_BOOTKEY_PASSWORD = 0xC00002DF, - MD_NTSTATUS_WIN_STATUS_SAM_NEED_BOOTKEY_FLOPPY = 0xC00002E0, - MD_NTSTATUS_WIN_STATUS_DS_CANT_START = 0xC00002E1, - MD_NTSTATUS_WIN_STATUS_DS_INIT_FAILURE = 0xC00002E2, - MD_NTSTATUS_WIN_STATUS_SAM_INIT_FAILURE = 0xC00002E3, - MD_NTSTATUS_WIN_STATUS_DS_GC_REQUIRED = 0xC00002E4, - MD_NTSTATUS_WIN_STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 0xC00002E5, - MD_NTSTATUS_WIN_STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS = 0xC00002E6, - MD_NTSTATUS_WIN_STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 0xC00002E7, - MD_NTSTATUS_WIN_STATUS_MULTIPLE_FAULT_VIOLATION = 0xC00002E8, - MD_NTSTATUS_WIN_STATUS_CURRENT_DOMAIN_NOT_ALLOWED = 0xC00002E9, - MD_NTSTATUS_WIN_STATUS_CANNOT_MAKE = 0xC00002EA, - MD_NTSTATUS_WIN_STATUS_SYSTEM_SHUTDOWN = 0xC00002EB, - MD_NTSTATUS_WIN_STATUS_DS_INIT_FAILURE_CONSOLE = 0xC00002EC, - MD_NTSTATUS_WIN_STATUS_DS_SAM_INIT_FAILURE_CONSOLE = 0xC00002ED, - MD_NTSTATUS_WIN_STATUS_UNFINISHED_CONTEXT_DELETED = 0xC00002EE, - MD_NTSTATUS_WIN_STATUS_NO_TGT_REPLY = 0xC00002EF, - MD_NTSTATUS_WIN_STATUS_OBJECTID_NOT_FOUND = 0xC00002F0, - MD_NTSTATUS_WIN_STATUS_NO_IP_ADDRESSES = 0xC00002F1, - MD_NTSTATUS_WIN_STATUS_WRONG_CREDENTIAL_HANDLE = 0xC00002F2, - MD_NTSTATUS_WIN_STATUS_CRYPTO_SYSTEM_INVALID = 0xC00002F3, - MD_NTSTATUS_WIN_STATUS_MAX_REFERRALS_EXCEEDED = 0xC00002F4, - MD_NTSTATUS_WIN_STATUS_MUST_BE_KDC = 0xC00002F5, - MD_NTSTATUS_WIN_STATUS_STRONG_CRYPTO_NOT_SUPPORTED = 0xC00002F6, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_PRINCIPALS = 0xC00002F7, - MD_NTSTATUS_WIN_STATUS_NO_PA_DATA = 0xC00002F8, - MD_NTSTATUS_WIN_STATUS_PKINIT_NAME_MISMATCH = 0xC00002F9, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_LOGON_REQUIRED = 0xC00002FA, - MD_NTSTATUS_WIN_STATUS_KDC_INVALID_REQUEST = 0xC00002FB, - MD_NTSTATUS_WIN_STATUS_KDC_UNABLE_TO_REFER = 0xC00002FC, - MD_NTSTATUS_WIN_STATUS_KDC_UNKNOWN_ETYPE = 0xC00002FD, - MD_NTSTATUS_WIN_STATUS_SHUTDOWN_IN_PROGRESS = 0xC00002FE, - MD_NTSTATUS_WIN_STATUS_SERVER_SHUTDOWN_IN_PROGRESS = 0xC00002FF, - MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED_ON_SBS = 0xC0000300, - MD_NTSTATUS_WIN_STATUS_WMI_GUID_DISCONNECTED = 0xC0000301, - MD_NTSTATUS_WIN_STATUS_WMI_ALREADY_DISABLED = 0xC0000302, - MD_NTSTATUS_WIN_STATUS_WMI_ALREADY_ENABLED = 0xC0000303, - MD_NTSTATUS_WIN_STATUS_MFT_TOO_FRAGMENTED = 0xC0000304, - MD_NTSTATUS_WIN_STATUS_COPY_PROTECTION_FAILURE = 0xC0000305, - MD_NTSTATUS_WIN_STATUS_CSS_AUTHENTICATION_FAILURE = 0xC0000306, - MD_NTSTATUS_WIN_STATUS_CSS_KEY_NOT_PRESENT = 0xC0000307, - MD_NTSTATUS_WIN_STATUS_CSS_KEY_NOT_ESTABLISHED = 0xC0000308, - MD_NTSTATUS_WIN_STATUS_CSS_SCRAMBLED_SECTOR = 0xC0000309, - MD_NTSTATUS_WIN_STATUS_CSS_REGION_MISMATCH = 0xC000030A, - MD_NTSTATUS_WIN_STATUS_CSS_RESETS_EXHAUSTED = 0xC000030B, - MD_NTSTATUS_WIN_STATUS_PASSWORD_CHANGE_REQUIRED = 0xC000030C, - MD_NTSTATUS_WIN_STATUS_PKINIT_FAILURE = 0xC0000320, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_SUBSYSTEM_FAILURE = 0xC0000321, - MD_NTSTATUS_WIN_STATUS_NO_KERB_KEY = 0xC0000322, - MD_NTSTATUS_WIN_STATUS_HOST_DOWN = 0xC0000350, - MD_NTSTATUS_WIN_STATUS_UNSUPPORTED_PREAUTH = 0xC0000351, - MD_NTSTATUS_WIN_STATUS_EFS_ALG_BLOB_TOO_BIG = 0xC0000352, - MD_NTSTATUS_WIN_STATUS_PORT_NOT_SET = 0xC0000353, - MD_NTSTATUS_WIN_STATUS_DEBUGGER_INACTIVE = 0xC0000354, - MD_NTSTATUS_WIN_STATUS_DS_VERSION_CHECK_FAILURE = 0xC0000355, - MD_NTSTATUS_WIN_STATUS_AUDITING_DISABLED = 0xC0000356, - MD_NTSTATUS_WIN_STATUS_PRENT4_MACHINE_ACCOUNT = 0xC0000357, - MD_NTSTATUS_WIN_STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 0xC0000358, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_32 = 0xC0000359, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_64 = 0xC000035A, - MD_NTSTATUS_WIN_STATUS_BAD_BINDINGS = 0xC000035B, - MD_NTSTATUS_WIN_STATUS_NETWORK_SESSION_EXPIRED = 0xC000035C, - MD_NTSTATUS_WIN_STATUS_APPHELP_BLOCK = 0xC000035D, - MD_NTSTATUS_WIN_STATUS_ALL_SIDS_FILTERED = 0xC000035E, - MD_NTSTATUS_WIN_STATUS_NOT_SAFE_MODE_DRIVER = 0xC000035F, - MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT = 0xC0000361, - MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_PATH = 0xC0000362, - MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER = 0xC0000363, - MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER = 0xC0000364, - MD_NTSTATUS_WIN_STATUS_FAILED_DRIVER_ENTRY = 0xC0000365, - MD_NTSTATUS_WIN_STATUS_DEVICE_ENUMERATION_ERROR = 0xC0000366, - MD_NTSTATUS_WIN_STATUS_MOUNT_POINT_NOT_RESOLVED = 0xC0000368, - MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_OBJECT_PARAMETER = 0xC0000369, - MD_NTSTATUS_WIN_STATUS_MCA_OCCURED = 0xC000036A, - MD_NTSTATUS_WIN_STATUS_DRIVER_BLOCKED_CRITICAL = 0xC000036B, - MD_NTSTATUS_WIN_STATUS_DRIVER_BLOCKED = 0xC000036C, - MD_NTSTATUS_WIN_STATUS_DRIVER_DATABASE_ERROR = 0xC000036D, - MD_NTSTATUS_WIN_STATUS_SYSTEM_HIVE_TOO_LARGE = 0xC000036E, - MD_NTSTATUS_WIN_STATUS_INVALID_IMPORT_OF_NON_DLL = 0xC000036F, - MD_NTSTATUS_WIN_STATUS_NO_SECRETS = 0xC0000371, - MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 0xC0000372, - MD_NTSTATUS_WIN_STATUS_FAILED_STACK_SWITCH = 0xC0000373, - MD_NTSTATUS_WIN_STATUS_HEAP_CORRUPTION = 0xC0000374, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_WRONG_PIN = 0xC0000380, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_CARD_BLOCKED = 0xC0000381, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED = 0xC0000382, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_CARD = 0xC0000383, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_KEY_CONTAINER = 0xC0000384, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_CERTIFICATE = 0xC0000385, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_KEYSET = 0xC0000386, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_IO_ERROR = 0xC0000387, - MD_NTSTATUS_WIN_STATUS_DOWNGRADE_DETECTED = 0xC0000388, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_CERT_REVOKED = 0xC0000389, - MD_NTSTATUS_WIN_STATUS_ISSUING_CA_UNTRUSTED = 0xC000038A, - MD_NTSTATUS_WIN_STATUS_REVOCATION_OFFLINE_C = 0xC000038B, - MD_NTSTATUS_WIN_STATUS_PKINIT_CLIENT_FAILURE = 0xC000038C, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_CERT_EXPIRED = 0xC000038D, - MD_NTSTATUS_WIN_STATUS_DRIVER_FAILED_PRIOR_UNLOAD = 0xC000038E, - MD_NTSTATUS_WIN_STATUS_SMARTCARD_SILENT_CONTEXT = 0xC000038F, - MD_NTSTATUS_WIN_STATUS_PER_USER_TRUST_QUOTA_EXCEEDED = 0xC0000401, - MD_NTSTATUS_WIN_STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED = 0xC0000402, - MD_NTSTATUS_WIN_STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED = 0xC0000403, - MD_NTSTATUS_WIN_STATUS_DS_NAME_NOT_UNIQUE = 0xC0000404, - MD_NTSTATUS_WIN_STATUS_DS_DUPLICATE_ID_FOUND = 0xC0000405, - MD_NTSTATUS_WIN_STATUS_DS_GROUP_CONVERSION_ERROR = 0xC0000406, - MD_NTSTATUS_WIN_STATUS_VOLSNAP_PREPARE_HIBERNATE = 0xC0000407, - MD_NTSTATUS_WIN_STATUS_USER2USER_REQUIRED = 0xC0000408, - MD_NTSTATUS_WIN_STATUS_STACK_BUFFER_OVERRUN = 0xC0000409, - MD_NTSTATUS_WIN_STATUS_NO_S4U_PROT_SUPPORT = 0xC000040A, - MD_NTSTATUS_WIN_STATUS_CROSSREALM_DELEGATION_FAILURE = 0xC000040B, - MD_NTSTATUS_WIN_STATUS_REVOCATION_OFFLINE_KDC = 0xC000040C, - MD_NTSTATUS_WIN_STATUS_ISSUING_CA_UNTRUSTED_KDC = 0xC000040D, - MD_NTSTATUS_WIN_STATUS_KDC_CERT_EXPIRED = 0xC000040E, - MD_NTSTATUS_WIN_STATUS_KDC_CERT_REVOKED = 0xC000040F, - MD_NTSTATUS_WIN_STATUS_PARAMETER_QUOTA_EXCEEDED = 0xC0000410, - MD_NTSTATUS_WIN_STATUS_HIBERNATION_FAILURE = 0xC0000411, - MD_NTSTATUS_WIN_STATUS_DELAY_LOAD_FAILED = 0xC0000412, - MD_NTSTATUS_WIN_STATUS_AUTHENTICATION_FIREWALL_FAILED = 0xC0000413, - MD_NTSTATUS_WIN_STATUS_VDM_DISALLOWED = 0xC0000414, - MD_NTSTATUS_WIN_STATUS_HUNG_DISPLAY_DRIVER_THREAD = 0xC0000415, - MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 0xC0000416, - MD_NTSTATUS_WIN_STATUS_INVALID_CRUNTIME_PARAMETER = 0xC0000417, - MD_NTSTATUS_WIN_STATUS_NTLM_BLOCKED = 0xC0000418, - MD_NTSTATUS_WIN_STATUS_DS_SRC_SID_EXISTS_IN_FOREST = 0xC0000419, - MD_NTSTATUS_WIN_STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST = 0xC000041A, - MD_NTSTATUS_WIN_STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST = 0xC000041B, - MD_NTSTATUS_WIN_STATUS_INVALID_USER_PRINCIPAL_NAME = 0xC000041C, - MD_NTSTATUS_WIN_STATUS_FATAL_USER_CALLBACK_EXCEPTION = 0xC000041D, - MD_NTSTATUS_WIN_STATUS_ASSERTION_FAILURE = 0xC0000420, - MD_NTSTATUS_WIN_STATUS_VERIFIER_STOP = 0xC0000421, - MD_NTSTATUS_WIN_STATUS_CALLBACK_POP_STACK = 0xC0000423, - MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_DRIVER_BLOCKED = 0xC0000424, - MD_NTSTATUS_WIN_STATUS_HIVE_UNLOADED = 0xC0000425, - MD_NTSTATUS_WIN_STATUS_COMPRESSION_DISABLED = 0xC0000426, - MD_NTSTATUS_WIN_STATUS_FILE_SYSTEM_LIMITATION = 0xC0000427, - MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_HASH = 0xC0000428, - MD_NTSTATUS_WIN_STATUS_NOT_CAPABLE = 0xC0000429, - MD_NTSTATUS_WIN_STATUS_REQUEST_OUT_OF_SEQUENCE = 0xC000042A, - MD_NTSTATUS_WIN_STATUS_IMPLEMENTATION_LIMIT = 0xC000042B, - MD_NTSTATUS_WIN_STATUS_ELEVATION_REQUIRED = 0xC000042C, - MD_NTSTATUS_WIN_STATUS_NO_SECURITY_CONTEXT = 0xC000042D, - MD_NTSTATUS_WIN_STATUS_PKU2U_CERT_FAILURE = 0xC000042F, - MD_NTSTATUS_WIN_STATUS_BEYOND_VDL = 0xC0000432, - MD_NTSTATUS_WIN_STATUS_ENCOUNTERED_WRITE_IN_PROGRESS = 0xC0000433, - MD_NTSTATUS_WIN_STATUS_PTE_CHANGED = 0xC0000434, - MD_NTSTATUS_WIN_STATUS_PURGE_FAILED = 0xC0000435, - MD_NTSTATUS_WIN_STATUS_CRED_REQUIRES_CONFIRMATION = 0xC0000440, - MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE = 0xC0000441, - MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER = 0xC0000442, - MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE = 0xC0000443, - MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE = 0xC0000444, - MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_FILE_NOT_CSE = 0xC0000445, - MD_NTSTATUS_WIN_STATUS_INVALID_LABEL = 0xC0000446, - MD_NTSTATUS_WIN_STATUS_DRIVER_PROCESS_TERMINATED = 0xC0000450, - MD_NTSTATUS_WIN_STATUS_AMBIGUOUS_SYSTEM_DEVICE = 0xC0000451, - MD_NTSTATUS_WIN_STATUS_SYSTEM_DEVICE_NOT_FOUND = 0xC0000452, - MD_NTSTATUS_WIN_STATUS_RESTART_BOOT_APPLICATION = 0xC0000453, - MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_NVRAM_RESOURCES = 0xC0000454, - MD_NTSTATUS_WIN_STATUS_INVALID_SESSION = 0xC0000455, - MD_NTSTATUS_WIN_STATUS_THREAD_ALREADY_IN_SESSION = 0xC0000456, - MD_NTSTATUS_WIN_STATUS_THREAD_NOT_IN_SESSION = 0xC0000457, - MD_NTSTATUS_WIN_STATUS_INVALID_WEIGHT = 0xC0000458, - MD_NTSTATUS_WIN_STATUS_REQUEST_PAUSED = 0xC0000459, - MD_NTSTATUS_WIN_STATUS_NO_RANGES_PROCESSED = 0xC0000460, - MD_NTSTATUS_WIN_STATUS_DISK_RESOURCES_EXHAUSTED = 0xC0000461, - MD_NTSTATUS_WIN_STATUS_NEEDS_REMEDIATION = 0xC0000462, - MD_NTSTATUS_WIN_STATUS_DEVICE_FEATURE_NOT_SUPPORTED = 0xC0000463, - MD_NTSTATUS_WIN_STATUS_DEVICE_UNREACHABLE = 0xC0000464, - MD_NTSTATUS_WIN_STATUS_INVALID_TOKEN = 0xC0000465, - MD_NTSTATUS_WIN_STATUS_SERVER_UNAVAILABLE = 0xC0000466, - MD_NTSTATUS_WIN_STATUS_FILE_NOT_AVAILABLE = 0xC0000467, - MD_NTSTATUS_WIN_STATUS_DEVICE_INSUFFICIENT_RESOURCES = 0xC0000468, - MD_NTSTATUS_WIN_STATUS_PACKAGE_UPDATING = 0xC0000469, - MD_NTSTATUS_WIN_STATUS_NOT_READ_FROM_COPY = 0xC000046A, - MD_NTSTATUS_WIN_STATUS_FT_WRITE_FAILURE = 0xC000046B, - MD_NTSTATUS_WIN_STATUS_FT_DI_SCAN_REQUIRED = 0xC000046C, - MD_NTSTATUS_WIN_STATUS_OBJECT_NOT_EXTERNALLY_BACKED = 0xC000046D, - MD_NTSTATUS_WIN_STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN = 0xC000046E, - MD_NTSTATUS_WIN_STATUS_DATA_CHECKSUM_ERROR = 0xC0000470, - MD_NTSTATUS_WIN_STATUS_INTERMIXED_KERNEL_EA_OPERATION = 0xC0000471, - MD_NTSTATUS_WIN_STATUS_TRIM_READ_ZERO_NOT_SUPPORTED = 0xC0000472, - MD_NTSTATUS_WIN_STATUS_TOO_MANY_SEGMENT_DESCRIPTORS = 0xC0000473, - MD_NTSTATUS_WIN_STATUS_INVALID_OFFSET_ALIGNMENT = 0xC0000474, - MD_NTSTATUS_WIN_STATUS_INVALID_FIELD_IN_PARAMETER_LIST = 0xC0000475, - MD_NTSTATUS_WIN_STATUS_OPERATION_IN_PROGRESS = 0xC0000476, - MD_NTSTATUS_WIN_STATUS_INVALID_INITIATOR_TARGET_PATH = 0xC0000477, - MD_NTSTATUS_WIN_STATUS_SCRUB_DATA_DISABLED = 0xC0000478, - MD_NTSTATUS_WIN_STATUS_NOT_REDUNDANT_STORAGE = 0xC0000479, - MD_NTSTATUS_WIN_STATUS_RESIDENT_FILE_NOT_SUPPORTED = 0xC000047A, - MD_NTSTATUS_WIN_STATUS_COMPRESSED_FILE_NOT_SUPPORTED = 0xC000047B, - MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_SUPPORTED = 0xC000047C, - MD_NTSTATUS_WIN_STATUS_IO_OPERATION_TIMEOUT = 0xC000047D, - MD_NTSTATUS_WIN_STATUS_SYSTEM_NEEDS_REMEDIATION = 0xC000047E, - MD_NTSTATUS_WIN_STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN = 0xC000047F, - MD_NTSTATUS_WIN_STATUS_SHARE_UNAVAILABLE = 0xC0000480, - MD_NTSTATUS_WIN_STATUS_APISET_NOT_HOSTED = 0xC0000481, - MD_NTSTATUS_WIN_STATUS_APISET_NOT_PRESENT = 0xC0000482, - MD_NTSTATUS_WIN_STATUS_DEVICE_HARDWARE_ERROR = 0xC0000483, - MD_NTSTATUS_WIN_STATUS_INVALID_TASK_NAME = 0xC0000500, - MD_NTSTATUS_WIN_STATUS_INVALID_TASK_INDEX = 0xC0000501, - MD_NTSTATUS_WIN_STATUS_THREAD_ALREADY_IN_TASK = 0xC0000502, - MD_NTSTATUS_WIN_STATUS_CALLBACK_BYPASS = 0xC0000503, - MD_NTSTATUS_WIN_STATUS_UNDEFINED_SCOPE = 0xC0000504, - MD_NTSTATUS_WIN_STATUS_INVALID_CAP = 0xC0000505, - MD_NTSTATUS_WIN_STATUS_NOT_GUI_PROCESS = 0xC0000506, - MD_NTSTATUS_WIN_STATUS_FAIL_FAST_EXCEPTION = 0xC0000602, - MD_NTSTATUS_WIN_STATUS_IMAGE_CERT_REVOKED = 0xC0000603, - MD_NTSTATUS_WIN_STATUS_DYNAMIC_CODE_BLOCKED = 0xC0000604, - MD_NTSTATUS_WIN_STATUS_PORT_CLOSED = 0xC0000700, - MD_NTSTATUS_WIN_STATUS_MESSAGE_LOST = 0xC0000701, - MD_NTSTATUS_WIN_STATUS_INVALID_MESSAGE = 0xC0000702, - MD_NTSTATUS_WIN_STATUS_REQUEST_CANCELED = 0xC0000703, - MD_NTSTATUS_WIN_STATUS_RECURSIVE_DISPATCH = 0xC0000704, - MD_NTSTATUS_WIN_STATUS_LPC_RECEIVE_BUFFER_EXPECTED = 0xC0000705, - MD_NTSTATUS_WIN_STATUS_LPC_INVALID_CONNECTION_USAGE = 0xC0000706, - MD_NTSTATUS_WIN_STATUS_LPC_REQUESTS_NOT_ALLOWED = 0xC0000707, - MD_NTSTATUS_WIN_STATUS_RESOURCE_IN_USE = 0xC0000708, - MD_NTSTATUS_WIN_STATUS_HARDWARE_MEMORY_ERROR = 0xC0000709, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_HANDLE_EXCEPTION = 0xC000070A, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED = 0xC000070B, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED = 0xC000070C, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED = 0xC000070D, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED = 0xC000070E, - MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASED_DURING_OPERATION = 0xC000070F, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING = 0xC0000710, - MD_NTSTATUS_WIN_STATUS_APC_RETURNED_WHILE_IMPERSONATING = 0xC0000711, - MD_NTSTATUS_WIN_STATUS_PROCESS_IS_PROTECTED = 0xC0000712, - MD_NTSTATUS_WIN_STATUS_MCA_EXCEPTION = 0xC0000713, - MD_NTSTATUS_WIN_STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE = 0xC0000714, - MD_NTSTATUS_WIN_STATUS_SYMLINK_CLASS_DISABLED = 0xC0000715, - MD_NTSTATUS_WIN_STATUS_INVALID_IDN_NORMALIZATION = 0xC0000716, - MD_NTSTATUS_WIN_STATUS_NO_UNICODE_TRANSLATION = 0xC0000717, - MD_NTSTATUS_WIN_STATUS_ALREADY_REGISTERED = 0xC0000718, - MD_NTSTATUS_WIN_STATUS_CONTEXT_MISMATCH = 0xC0000719, - MD_NTSTATUS_WIN_STATUS_PORT_ALREADY_HAS_COMPLETION_LIST = 0xC000071A, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_THREAD_PRIORITY = 0xC000071B, - MD_NTSTATUS_WIN_STATUS_INVALID_THREAD = 0xC000071C, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_TRANSACTION = 0xC000071D, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_LDR_LOCK = 0xC000071E, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_LANG = 0xC000071F, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_PRI_BACK = 0xC0000720, - MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_THREAD_AFFINITY = 0xC0000721, - MD_NTSTATUS_WIN_STATUS_DISK_REPAIR_DISABLED = 0xC0000800, - MD_NTSTATUS_WIN_STATUS_DS_DOMAIN_RENAME_IN_PROGRESS = 0xC0000801, - MD_NTSTATUS_WIN_STATUS_DISK_QUOTA_EXCEEDED = 0xC0000802, - MD_NTSTATUS_WIN_STATUS_CONTENT_BLOCKED = 0xC0000804, - MD_NTSTATUS_WIN_STATUS_BAD_CLUSTERS = 0xC0000805, - MD_NTSTATUS_WIN_STATUS_VOLUME_DIRTY = 0xC0000806, - MD_NTSTATUS_WIN_STATUS_DISK_REPAIR_UNSUCCESSFUL = 0xC0000808, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_OVERFULL = 0xC0000809, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_CORRUPTED = 0xC000080A, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_UNAVAILABLE = 0xC000080B, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_DELETED_FULL = 0xC000080C, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_CLEARED = 0xC000080D, - MD_NTSTATUS_WIN_STATUS_ORPHAN_NAME_EXHAUSTED = 0xC000080E, - MD_NTSTATUS_WIN_STATUS_PROACTIVE_SCAN_IN_PROGRESS = 0xC000080F, - MD_NTSTATUS_WIN_STATUS_ENCRYPTED_IO_NOT_POSSIBLE = 0xC0000810, - MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_UPLEVEL_RECORDS = 0xC0000811, - MD_NTSTATUS_WIN_STATUS_FILE_CHECKED_OUT = 0xC0000901, - MD_NTSTATUS_WIN_STATUS_CHECKOUT_REQUIRED = 0xC0000902, - MD_NTSTATUS_WIN_STATUS_BAD_FILE_TYPE = 0xC0000903, - MD_NTSTATUS_WIN_STATUS_FILE_TOO_LARGE = 0xC0000904, - MD_NTSTATUS_WIN_STATUS_FORMS_AUTH_REQUIRED = 0xC0000905, - MD_NTSTATUS_WIN_STATUS_VIRUS_INFECTED = 0xC0000906, - MD_NTSTATUS_WIN_STATUS_VIRUS_DELETED = 0xC0000907, - MD_NTSTATUS_WIN_STATUS_BAD_MCFG_TABLE = 0xC0000908, - MD_NTSTATUS_WIN_STATUS_CANNOT_BREAK_OPLOCK = 0xC0000909, - MD_NTSTATUS_WIN_STATUS_BAD_KEY = 0xC000090A, - MD_NTSTATUS_WIN_STATUS_BAD_DATA = 0xC000090B, - MD_NTSTATUS_WIN_STATUS_NO_KEY = 0xC000090C, - MD_NTSTATUS_WIN_STATUS_FILE_HANDLE_REVOKED = 0xC0000910, - MD_NTSTATUS_WIN_STATUS_WOW_ASSERTION = 0xC0009898, - MD_NTSTATUS_WIN_STATUS_INVALID_SIGNATURE = 0xC000A000, - MD_NTSTATUS_WIN_STATUS_HMAC_NOT_SUPPORTED = 0xC000A001, - MD_NTSTATUS_WIN_STATUS_AUTH_TAG_MISMATCH = 0xC000A002, - MD_NTSTATUS_WIN_STATUS_INVALID_STATE_TRANSITION = 0xC000A003, - MD_NTSTATUS_WIN_STATUS_INVALID_KERNEL_INFO_VERSION = 0xC000A004, - MD_NTSTATUS_WIN_STATUS_INVALID_PEP_INFO_VERSION = 0xC000A005, - MD_NTSTATUS_WIN_STATUS_IPSEC_QUEUE_OVERFLOW = 0xC000A010, - MD_NTSTATUS_WIN_STATUS_ND_QUEUE_OVERFLOW = 0xC000A011, - MD_NTSTATUS_WIN_STATUS_HOPLIMIT_EXCEEDED = 0xC000A012, - MD_NTSTATUS_WIN_STATUS_PROTOCOL_NOT_SUPPORTED = 0xC000A013, - MD_NTSTATUS_WIN_STATUS_FASTPATH_REJECTED = 0xC000A014, - MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 0xC000A080, - MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 0xC000A081, - MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 0xC000A082, - MD_NTSTATUS_WIN_STATUS_XML_PARSE_ERROR = 0xC000A083, - MD_NTSTATUS_WIN_STATUS_XMLDSIG_ERROR = 0xC000A084, - MD_NTSTATUS_WIN_STATUS_WRONG_COMPARTMENT = 0xC000A085, - MD_NTSTATUS_WIN_STATUS_AUTHIP_FAILURE = 0xC000A086, - MD_NTSTATUS_WIN_STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS = 0xC000A087, - MD_NTSTATUS_WIN_STATUS_DS_OID_NOT_FOUND = 0xC000A088, - MD_NTSTATUS_WIN_STATUS_INCORRECT_ACCOUNT_TYPE = 0xC000A089, - MD_NTSTATUS_WIN_STATUS_HASH_NOT_SUPPORTED = 0xC000A100, - MD_NTSTATUS_WIN_STATUS_HASH_NOT_PRESENT = 0xC000A101, - MD_NTSTATUS_WIN_STATUS_SECONDARY_IC_PROVIDER_NOT_REGISTERED = 0xC000A121, - MD_NTSTATUS_WIN_STATUS_GPIO_CLIENT_INFORMATION_INVALID = 0xC000A122, - MD_NTSTATUS_WIN_STATUS_GPIO_VERSION_NOT_SUPPORTED = 0xC000A123, - MD_NTSTATUS_WIN_STATUS_GPIO_INVALID_REGISTRATION_PACKET = 0xC000A124, - MD_NTSTATUS_WIN_STATUS_GPIO_OPERATION_DENIED = 0xC000A125, - MD_NTSTATUS_WIN_STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE = 0xC000A126, - MD_NTSTATUS_WIN_STATUS_CANNOT_SWITCH_RUNLEVEL = 0xC000A141, - MD_NTSTATUS_WIN_STATUS_INVALID_RUNLEVEL_SETTING = 0xC000A142, - MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_TIMEOUT = 0xC000A143, - MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_AGENT_TIMEOUT = 0xC000A145, - MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_IN_PROGRESS = 0xC000A146, - MD_NTSTATUS_WIN_STATUS_NOT_APPCONTAINER = 0xC000A200, - MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED_IN_APPCONTAINER = 0xC000A201, - MD_NTSTATUS_WIN_STATUS_INVALID_PACKAGE_SID_LENGTH = 0xC000A202, - MD_NTSTATUS_WIN_STATUS_APP_DATA_NOT_FOUND = 0xC000A281, - MD_NTSTATUS_WIN_STATUS_APP_DATA_EXPIRED = 0xC000A282, - MD_NTSTATUS_WIN_STATUS_APP_DATA_CORRUPT = 0xC000A283, - MD_NTSTATUS_WIN_STATUS_APP_DATA_LIMIT_EXCEEDED = 0xC000A284, - MD_NTSTATUS_WIN_STATUS_APP_DATA_REBOOT_REQUIRED = 0xC000A285, - MD_NTSTATUS_WIN_STATUS_OFFLOAD_READ_FLT_NOT_SUPPORTED = 0xC000A2A1, - MD_NTSTATUS_WIN_STATUS_OFFLOAD_WRITE_FLT_NOT_SUPPORTED = 0xC000A2A2, - MD_NTSTATUS_WIN_STATUS_OFFLOAD_READ_FILE_NOT_SUPPORTED = 0xC000A2A3, - MD_NTSTATUS_WIN_STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED = 0xC000A2A4, - MD_NTSTATUS_WIN_DBG_NO_STATE_CHANGE = 0xC0010001, - MD_NTSTATUS_WIN_DBG_APP_NOT_IDLE = 0xC0010002, - MD_NTSTATUS_WIN_RPC_NT_INVALID_STRING_BINDING = 0xC0020001, - MD_NTSTATUS_WIN_RPC_NT_WRONG_KIND_OF_BINDING = 0xC0020002, - MD_NTSTATUS_WIN_RPC_NT_INVALID_BINDING = 0xC0020003, - MD_NTSTATUS_WIN_RPC_NT_PROTSEQ_NOT_SUPPORTED = 0xC0020004, - MD_NTSTATUS_WIN_RPC_NT_INVALID_RPC_PROTSEQ = 0xC0020005, - MD_NTSTATUS_WIN_RPC_NT_INVALID_STRING_UUID = 0xC0020006, - MD_NTSTATUS_WIN_RPC_NT_INVALID_ENDPOINT_FORMAT = 0xC0020007, - MD_NTSTATUS_WIN_RPC_NT_INVALID_NET_ADDR = 0xC0020008, - MD_NTSTATUS_WIN_RPC_NT_NO_ENDPOINT_FOUND = 0xC0020009, - MD_NTSTATUS_WIN_RPC_NT_INVALID_TIMEOUT = 0xC002000A, - MD_NTSTATUS_WIN_RPC_NT_OBJECT_NOT_FOUND = 0xC002000B, - MD_NTSTATUS_WIN_RPC_NT_ALREADY_REGISTERED = 0xC002000C, - MD_NTSTATUS_WIN_RPC_NT_TYPE_ALREADY_REGISTERED = 0xC002000D, - MD_NTSTATUS_WIN_RPC_NT_ALREADY_LISTENING = 0xC002000E, - MD_NTSTATUS_WIN_RPC_NT_NO_PROTSEQS_REGISTERED = 0xC002000F, - MD_NTSTATUS_WIN_RPC_NT_NOT_LISTENING = 0xC0020010, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_MGR_TYPE = 0xC0020011, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_IF = 0xC0020012, - MD_NTSTATUS_WIN_RPC_NT_NO_BINDINGS = 0xC0020013, - MD_NTSTATUS_WIN_RPC_NT_NO_PROTSEQS = 0xC0020014, - MD_NTSTATUS_WIN_RPC_NT_CANT_CREATE_ENDPOINT = 0xC0020015, - MD_NTSTATUS_WIN_RPC_NT_OUT_OF_RESOURCES = 0xC0020016, - MD_NTSTATUS_WIN_RPC_NT_SERVER_UNAVAILABLE = 0xC0020017, - MD_NTSTATUS_WIN_RPC_NT_SERVER_TOO_BUSY = 0xC0020018, - MD_NTSTATUS_WIN_RPC_NT_INVALID_NETWORK_OPTIONS = 0xC0020019, - MD_NTSTATUS_WIN_RPC_NT_NO_CALL_ACTIVE = 0xC002001A, - MD_NTSTATUS_WIN_RPC_NT_CALL_FAILED = 0xC002001B, - MD_NTSTATUS_WIN_RPC_NT_CALL_FAILED_DNE = 0xC002001C, - MD_NTSTATUS_WIN_RPC_NT_PROTOCOL_ERROR = 0xC002001D, - MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_TRANS_SYN = 0xC002001F, - MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_TYPE = 0xC0020021, - MD_NTSTATUS_WIN_RPC_NT_INVALID_TAG = 0xC0020022, - MD_NTSTATUS_WIN_RPC_NT_INVALID_BOUND = 0xC0020023, - MD_NTSTATUS_WIN_RPC_NT_NO_ENTRY_NAME = 0xC0020024, - MD_NTSTATUS_WIN_RPC_NT_INVALID_NAME_SYNTAX = 0xC0020025, - MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_NAME_SYNTAX = 0xC0020026, - MD_NTSTATUS_WIN_RPC_NT_UUID_NO_ADDRESS = 0xC0020028, - MD_NTSTATUS_WIN_RPC_NT_DUPLICATE_ENDPOINT = 0xC0020029, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_TYPE = 0xC002002A, - MD_NTSTATUS_WIN_RPC_NT_MAX_CALLS_TOO_SMALL = 0xC002002B, - MD_NTSTATUS_WIN_RPC_NT_STRING_TOO_LONG = 0xC002002C, - MD_NTSTATUS_WIN_RPC_NT_PROTSEQ_NOT_FOUND = 0xC002002D, - MD_NTSTATUS_WIN_RPC_NT_PROCNUM_OUT_OF_RANGE = 0xC002002E, - MD_NTSTATUS_WIN_RPC_NT_BINDING_HAS_NO_AUTH = 0xC002002F, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_SERVICE = 0xC0020030, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_LEVEL = 0xC0020031, - MD_NTSTATUS_WIN_RPC_NT_INVALID_AUTH_IDENTITY = 0xC0020032, - MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHZ_SERVICE = 0xC0020033, - MD_NTSTATUS_WIN_EPT_NT_INVALID_ENTRY = 0xC0020034, - MD_NTSTATUS_WIN_EPT_NT_CANT_PERFORM_OP = 0xC0020035, - MD_NTSTATUS_WIN_EPT_NT_NOT_REGISTERED = 0xC0020036, - MD_NTSTATUS_WIN_RPC_NT_NOTHING_TO_EXPORT = 0xC0020037, - MD_NTSTATUS_WIN_RPC_NT_INCOMPLETE_NAME = 0xC0020038, - MD_NTSTATUS_WIN_RPC_NT_INVALID_VERS_OPTION = 0xC0020039, - MD_NTSTATUS_WIN_RPC_NT_NO_MORE_MEMBERS = 0xC002003A, - MD_NTSTATUS_WIN_RPC_NT_NOT_ALL_OBJS_UNEXPORTED = 0xC002003B, - MD_NTSTATUS_WIN_RPC_NT_INTERFACE_NOT_FOUND = 0xC002003C, - MD_NTSTATUS_WIN_RPC_NT_ENTRY_ALREADY_EXISTS = 0xC002003D, - MD_NTSTATUS_WIN_RPC_NT_ENTRY_NOT_FOUND = 0xC002003E, - MD_NTSTATUS_WIN_RPC_NT_NAME_SERVICE_UNAVAILABLE = 0xC002003F, - MD_NTSTATUS_WIN_RPC_NT_INVALID_NAF_ID = 0xC0020040, - MD_NTSTATUS_WIN_RPC_NT_CANNOT_SUPPORT = 0xC0020041, - MD_NTSTATUS_WIN_RPC_NT_NO_CONTEXT_AVAILABLE = 0xC0020042, - MD_NTSTATUS_WIN_RPC_NT_INTERNAL_ERROR = 0xC0020043, - MD_NTSTATUS_WIN_RPC_NT_ZERO_DIVIDE = 0xC0020044, - MD_NTSTATUS_WIN_RPC_NT_ADDRESS_ERROR = 0xC0020045, - MD_NTSTATUS_WIN_RPC_NT_FP_DIV_ZERO = 0xC0020046, - MD_NTSTATUS_WIN_RPC_NT_FP_UNDERFLOW = 0xC0020047, - MD_NTSTATUS_WIN_RPC_NT_FP_OVERFLOW = 0xC0020048, - MD_NTSTATUS_WIN_RPC_NT_CALL_IN_PROGRESS = 0xC0020049, - MD_NTSTATUS_WIN_RPC_NT_NO_MORE_BINDINGS = 0xC002004A, - MD_NTSTATUS_WIN_RPC_NT_GROUP_MEMBER_NOT_FOUND = 0xC002004B, - MD_NTSTATUS_WIN_EPT_NT_CANT_CREATE = 0xC002004C, - MD_NTSTATUS_WIN_RPC_NT_INVALID_OBJECT = 0xC002004D, - MD_NTSTATUS_WIN_RPC_NT_NO_INTERFACES = 0xC002004F, - MD_NTSTATUS_WIN_RPC_NT_CALL_CANCELLED = 0xC0020050, - MD_NTSTATUS_WIN_RPC_NT_BINDING_INCOMPLETE = 0xC0020051, - MD_NTSTATUS_WIN_RPC_NT_COMM_FAILURE = 0xC0020052, - MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_AUTHN_LEVEL = 0xC0020053, - MD_NTSTATUS_WIN_RPC_NT_NO_PRINC_NAME = 0xC0020054, - MD_NTSTATUS_WIN_RPC_NT_NOT_RPC_ERROR = 0xC0020055, - MD_NTSTATUS_WIN_RPC_NT_SEC_PKG_ERROR = 0xC0020057, - MD_NTSTATUS_WIN_RPC_NT_NOT_CANCELLED = 0xC0020058, - MD_NTSTATUS_WIN_RPC_NT_INVALID_ASYNC_HANDLE = 0xC0020062, - MD_NTSTATUS_WIN_RPC_NT_INVALID_ASYNC_CALL = 0xC0020063, - MD_NTSTATUS_WIN_RPC_NT_PROXY_ACCESS_DENIED = 0xC0020064, - MD_NTSTATUS_WIN_RPC_NT_COOKIE_AUTH_FAILED = 0xC0020065, - MD_NTSTATUS_WIN_RPC_NT_NO_MORE_ENTRIES = 0xC0030001, - MD_NTSTATUS_WIN_RPC_NT_SS_CHAR_TRANS_OPEN_FAIL = 0xC0030002, - MD_NTSTATUS_WIN_RPC_NT_SS_CHAR_TRANS_SHORT_FILE = 0xC0030003, - MD_NTSTATUS_WIN_RPC_NT_SS_IN_NULL_CONTEXT = 0xC0030004, - MD_NTSTATUS_WIN_RPC_NT_SS_CONTEXT_MISMATCH = 0xC0030005, - MD_NTSTATUS_WIN_RPC_NT_SS_CONTEXT_DAMAGED = 0xC0030006, - MD_NTSTATUS_WIN_RPC_NT_SS_HANDLES_MISMATCH = 0xC0030007, - MD_NTSTATUS_WIN_RPC_NT_SS_CANNOT_GET_CALL_HANDLE = 0xC0030008, - MD_NTSTATUS_WIN_RPC_NT_NULL_REF_POINTER = 0xC0030009, - MD_NTSTATUS_WIN_RPC_NT_ENUM_VALUE_OUT_OF_RANGE = 0xC003000A, - MD_NTSTATUS_WIN_RPC_NT_BYTE_COUNT_TOO_SMALL = 0xC003000B, - MD_NTSTATUS_WIN_RPC_NT_BAD_STUB_DATA = 0xC003000C, - MD_NTSTATUS_WIN_RPC_NT_INVALID_ES_ACTION = 0xC0030059, - MD_NTSTATUS_WIN_RPC_NT_WRONG_ES_VERSION = 0xC003005A, - MD_NTSTATUS_WIN_RPC_NT_WRONG_STUB_VERSION = 0xC003005B, - MD_NTSTATUS_WIN_RPC_NT_INVALID_PIPE_OBJECT = 0xC003005C, - MD_NTSTATUS_WIN_RPC_NT_INVALID_PIPE_OPERATION = 0xC003005D, - MD_NTSTATUS_WIN_RPC_NT_WRONG_PIPE_VERSION = 0xC003005E, - MD_NTSTATUS_WIN_RPC_NT_PIPE_CLOSED = 0xC003005F, - MD_NTSTATUS_WIN_RPC_NT_PIPE_DISCIPLINE_ERROR = 0xC0030060, - MD_NTSTATUS_WIN_RPC_NT_PIPE_EMPTY = 0xC0030061, - MD_NTSTATUS_WIN_STATUS_PNP_BAD_MPS_TABLE = 0xC0040035, - MD_NTSTATUS_WIN_STATUS_PNP_TRANSLATION_FAILED = 0xC0040036, - MD_NTSTATUS_WIN_STATUS_PNP_IRQ_TRANSLATION_FAILED = 0xC0040037, - MD_NTSTATUS_WIN_STATUS_PNP_INVALID_ID = 0xC0040038, - MD_NTSTATUS_WIN_STATUS_IO_REISSUE_AS_CACHED = 0xC0040039, - MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NAME_INVALID = 0xC00A0001, - MD_NTSTATUS_WIN_STATUS_CTX_INVALID_PD = 0xC00A0002, - MD_NTSTATUS_WIN_STATUS_CTX_PD_NOT_FOUND = 0xC00A0003, - MD_NTSTATUS_WIN_STATUS_CTX_CLOSE_PENDING = 0xC00A0006, - MD_NTSTATUS_WIN_STATUS_CTX_NO_OUTBUF = 0xC00A0007, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_INF_NOT_FOUND = 0xC00A0008, - MD_NTSTATUS_WIN_STATUS_CTX_INVALID_MODEMNAME = 0xC00A0009, - MD_NTSTATUS_WIN_STATUS_CTX_RESPONSE_ERROR = 0xC00A000A, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_TIMEOUT = 0xC00A000B, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_NO_CARRIER = 0xC00A000C, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE = 0xC00A000D, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_BUSY = 0xC00A000E, - MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_VOICE = 0xC00A000F, - MD_NTSTATUS_WIN_STATUS_CTX_TD_ERROR = 0xC00A0010, - MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_CLIENT_INVALID = 0xC00A0012, - MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_NOT_AVAILABLE = 0xC00A0013, - MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_EXPIRED = 0xC00A0014, - MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NOT_FOUND = 0xC00A0015, - MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NAME_COLLISION = 0xC00A0016, - MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_BUSY = 0xC00A0017, - MD_NTSTATUS_WIN_STATUS_CTX_BAD_VIDEO_MODE = 0xC00A0018, - MD_NTSTATUS_WIN_STATUS_CTX_GRAPHICS_INVALID = 0xC00A0022, - MD_NTSTATUS_WIN_STATUS_CTX_NOT_CONSOLE = 0xC00A0024, - MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_QUERY_TIMEOUT = 0xC00A0026, - MD_NTSTATUS_WIN_STATUS_CTX_CONSOLE_DISCONNECT = 0xC00A0027, - MD_NTSTATUS_WIN_STATUS_CTX_CONSOLE_CONNECT = 0xC00A0028, - MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_DENIED = 0xC00A002A, - MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_ACCESS_DENIED = 0xC00A002B, - MD_NTSTATUS_WIN_STATUS_CTX_INVALID_WD = 0xC00A002E, - MD_NTSTATUS_WIN_STATUS_CTX_WD_NOT_FOUND = 0xC00A002F, - MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_INVALID = 0xC00A0030, - MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_DISABLED = 0xC00A0031, - MD_NTSTATUS_WIN_STATUS_RDP_PROTOCOL_ERROR = 0xC00A0032, - MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_LICENSE_NOT_SET = 0xC00A0033, - MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_LICENSE_IN_USE = 0xC00A0034, - MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE = 0xC00A0035, - MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_NOT_RUNNING = 0xC00A0036, - MD_NTSTATUS_WIN_STATUS_CTX_LOGON_DISABLED = 0xC00A0037, - MD_NTSTATUS_WIN_STATUS_CTX_SECURITY_LAYER_ERROR = 0xC00A0038, - MD_NTSTATUS_WIN_STATUS_TS_INCOMPATIBLE_SESSIONS = 0xC00A0039, - MD_NTSTATUS_WIN_STATUS_TS_VIDEO_SUBSYSTEM_ERROR = 0xC00A003A, - MD_NTSTATUS_WIN_STATUS_MUI_FILE_NOT_FOUND = 0xC00B0001, - MD_NTSTATUS_WIN_STATUS_MUI_INVALID_FILE = 0xC00B0002, - MD_NTSTATUS_WIN_STATUS_MUI_INVALID_RC_CONFIG = 0xC00B0003, - MD_NTSTATUS_WIN_STATUS_MUI_INVALID_LOCALE_NAME = 0xC00B0004, - MD_NTSTATUS_WIN_STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME = 0xC00B0005, - MD_NTSTATUS_WIN_STATUS_MUI_FILE_NOT_LOADED = 0xC00B0006, - MD_NTSTATUS_WIN_STATUS_RESOURCE_ENUM_USER_STOP = 0xC00B0007, - MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NODE = 0xC0130001, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_EXISTS = 0xC0130002, - MD_NTSTATUS_WIN_STATUS_CLUSTER_JOIN_IN_PROGRESS = 0xC0130003, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_FOUND = 0xC0130004, - MD_NTSTATUS_WIN_STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND = 0xC0130005, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_EXISTS = 0xC0130006, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_NOT_FOUND = 0xC0130007, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NETINTERFACE_EXISTS = 0xC0130008, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NETINTERFACE_NOT_FOUND = 0xC0130009, - MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_REQUEST = 0xC013000A, - MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NETWORK_PROVIDER = 0xC013000B, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_DOWN = 0xC013000C, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_UNREACHABLE = 0xC013000D, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_MEMBER = 0xC013000E, - MD_NTSTATUS_WIN_STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS = 0xC013000F, - MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NETWORK = 0xC0130010, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NO_NET_ADAPTERS = 0xC0130011, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_UP = 0xC0130012, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_PAUSED = 0xC0130013, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_PAUSED = 0xC0130014, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NO_SECURITY_CONTEXT = 0xC0130015, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_NOT_INTERNAL = 0xC0130016, - MD_NTSTATUS_WIN_STATUS_CLUSTER_POISONED = 0xC0130017, - MD_NTSTATUS_WIN_STATUS_CLUSTER_NON_CSV_PATH = 0xC0130018, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL = 0xC0130019, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS = 0xC0130020, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR = 0xC0130021, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_REDIRECTED = 0xC0130022, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_NOT_REDIRECTED = 0xC0130023, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_DRAINING = 0xC0130024, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS = 0xC0130025, - MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL = 0xC0130026, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_OPCODE = 0xC0140001, - MD_NTSTATUS_WIN_STATUS_ACPI_STACK_OVERFLOW = 0xC0140002, - MD_NTSTATUS_WIN_STATUS_ACPI_ASSERT_FAILED = 0xC0140003, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_INDEX = 0xC0140004, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ARGUMENT = 0xC0140005, - MD_NTSTATUS_WIN_STATUS_ACPI_FATAL = 0xC0140006, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_SUPERNAME = 0xC0140007, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ARGTYPE = 0xC0140008, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_OBJTYPE = 0xC0140009, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_TARGETTYPE = 0xC014000A, - MD_NTSTATUS_WIN_STATUS_ACPI_INCORRECT_ARGUMENT_COUNT = 0xC014000B, - MD_NTSTATUS_WIN_STATUS_ACPI_ADDRESS_NOT_MAPPED = 0xC014000C, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_EVENTTYPE = 0xC014000D, - MD_NTSTATUS_WIN_STATUS_ACPI_HANDLER_COLLISION = 0xC014000E, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_DATA = 0xC014000F, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_REGION = 0xC0140010, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ACCESS_SIZE = 0xC0140011, - MD_NTSTATUS_WIN_STATUS_ACPI_ACQUIRE_GLOBAL_LOCK = 0xC0140012, - MD_NTSTATUS_WIN_STATUS_ACPI_ALREADY_INITIALIZED = 0xC0140013, - MD_NTSTATUS_WIN_STATUS_ACPI_NOT_INITIALIZED = 0xC0140014, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_MUTEX_LEVEL = 0xC0140015, - MD_NTSTATUS_WIN_STATUS_ACPI_MUTEX_NOT_OWNED = 0xC0140016, - MD_NTSTATUS_WIN_STATUS_ACPI_MUTEX_NOT_OWNER = 0xC0140017, - MD_NTSTATUS_WIN_STATUS_ACPI_RS_ACCESS = 0xC0140018, - MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_TABLE = 0xC0140019, - MD_NTSTATUS_WIN_STATUS_ACPI_REG_HANDLER_FAILED = 0xC0140020, - MD_NTSTATUS_WIN_STATUS_ACPI_POWER_REQUEST_FAILED = 0xC0140021, - MD_NTSTATUS_WIN_STATUS_SXS_SECTION_NOT_FOUND = 0xC0150001, - MD_NTSTATUS_WIN_STATUS_SXS_CANT_GEN_ACTCTX = 0xC0150002, - MD_NTSTATUS_WIN_STATUS_SXS_INVALID_ACTCTXDATA_FORMAT = 0xC0150003, - MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_NOT_FOUND = 0xC0150004, - MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_FORMAT_ERROR = 0xC0150005, - MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_PARSE_ERROR = 0xC0150006, - MD_NTSTATUS_WIN_STATUS_SXS_ACTIVATION_CONTEXT_DISABLED = 0xC0150007, - MD_NTSTATUS_WIN_STATUS_SXS_KEY_NOT_FOUND = 0xC0150008, - MD_NTSTATUS_WIN_STATUS_SXS_VERSION_CONFLICT = 0xC0150009, - MD_NTSTATUS_WIN_STATUS_SXS_WRONG_SECTION_TYPE = 0xC015000A, - MD_NTSTATUS_WIN_STATUS_SXS_THREAD_QUERIES_DISABLED = 0xC015000B, - MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_MISSING = 0xC015000C, - MD_NTSTATUS_WIN_STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET = 0xC015000E, - MD_NTSTATUS_WIN_STATUS_SXS_EARLY_DEACTIVATION = 0xC015000F, - MD_NTSTATUS_WIN_STATUS_SXS_INVALID_DEACTIVATION = 0xC0150010, - MD_NTSTATUS_WIN_STATUS_SXS_MULTIPLE_DEACTIVATION = 0xC0150011, - MD_NTSTATUS_WIN_STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY = 0xC0150012, - MD_NTSTATUS_WIN_STATUS_SXS_PROCESS_TERMINATION_REQUESTED = 0xC0150013, - MD_NTSTATUS_WIN_STATUS_SXS_CORRUPT_ACTIVATION_STACK = 0xC0150014, - MD_NTSTATUS_WIN_STATUS_SXS_CORRUPTION = 0xC0150015, - MD_NTSTATUS_WIN_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE = 0xC0150016, - MD_NTSTATUS_WIN_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME = 0xC0150017, - MD_NTSTATUS_WIN_STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE = 0xC0150018, - MD_NTSTATUS_WIN_STATUS_SXS_IDENTITY_PARSE_ERROR = 0xC0150019, - MD_NTSTATUS_WIN_STATUS_SXS_COMPONENT_STORE_CORRUPT = 0xC015001A, - MD_NTSTATUS_WIN_STATUS_SXS_FILE_HASH_MISMATCH = 0xC015001B, - MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT = 0xC015001C, - MD_NTSTATUS_WIN_STATUS_SXS_IDENTITIES_DIFFERENT = 0xC015001D, - MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT = 0xC015001E, - MD_NTSTATUS_WIN_STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY = 0xC015001F, - MD_NTSTATUS_WIN_STATUS_ADVANCED_INSTALLER_FAILED = 0xC0150020, - MD_NTSTATUS_WIN_STATUS_XML_ENCODING_MISMATCH = 0xC0150021, - MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_TOO_BIG = 0xC0150022, - MD_NTSTATUS_WIN_STATUS_SXS_SETTING_NOT_REGISTERED = 0xC0150023, - MD_NTSTATUS_WIN_STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE = 0xC0150024, - MD_NTSTATUS_WIN_STATUS_SMI_PRIMITIVE_INSTALLER_FAILED = 0xC0150025, - MD_NTSTATUS_WIN_STATUS_GENERIC_COMMAND_FAILED = 0xC0150026, - MD_NTSTATUS_WIN_STATUS_SXS_FILE_HASH_MISSING = 0xC0150027, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONAL_CONFLICT = 0xC0190001, - MD_NTSTATUS_WIN_STATUS_INVALID_TRANSACTION = 0xC0190002, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ACTIVE = 0xC0190003, - MD_NTSTATUS_WIN_STATUS_TM_INITIALIZATION_FAILED = 0xC0190004, - MD_NTSTATUS_WIN_STATUS_RM_NOT_ACTIVE = 0xC0190005, - MD_NTSTATUS_WIN_STATUS_RM_METADATA_CORRUPT = 0xC0190006, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_JOINED = 0xC0190007, - MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_RM = 0xC0190008, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE = 0xC019000A, - MD_NTSTATUS_WIN_STATUS_LOG_RESIZE_INVALID_SIZE = 0xC019000B, - MD_NTSTATUS_WIN_STATUS_REMOTE_FILE_VERSION_MISMATCH = 0xC019000C, - MD_NTSTATUS_WIN_STATUS_CRM_PROTOCOL_ALREADY_EXISTS = 0xC019000F, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_PROPAGATION_FAILED = 0xC0190010, - MD_NTSTATUS_WIN_STATUS_CRM_PROTOCOL_NOT_FOUND = 0xC0190011, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_SUPERIOR_EXISTS = 0xC0190012, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_REQUEST_NOT_VALID = 0xC0190013, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_REQUESTED = 0xC0190014, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_ALREADY_ABORTED = 0xC0190015, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_ALREADY_COMMITTED = 0xC0190016, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER = 0xC0190017, - MD_NTSTATUS_WIN_STATUS_CURRENT_TRANSACTION_NOT_VALID = 0xC0190018, - MD_NTSTATUS_WIN_STATUS_LOG_GROWTH_FAILED = 0xC0190019, - MD_NTSTATUS_WIN_STATUS_OBJECT_NO_LONGER_EXISTS = 0xC0190021, - MD_NTSTATUS_WIN_STATUS_STREAM_MINIVERSION_NOT_FOUND = 0xC0190022, - MD_NTSTATUS_WIN_STATUS_STREAM_MINIVERSION_NOT_VALID = 0xC0190023, - MD_NTSTATUS_WIN_STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION = 0xC0190024, - MD_NTSTATUS_WIN_STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT = 0xC0190025, - MD_NTSTATUS_WIN_STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS = 0xC0190026, - MD_NTSTATUS_WIN_STATUS_HANDLE_NO_LONGER_VALID = 0xC0190028, - MD_NTSTATUS_WIN_STATUS_LOG_CORRUPTION_DETECTED = 0xC0190030, - MD_NTSTATUS_WIN_STATUS_RM_DISCONNECTED = 0xC0190032, - MD_NTSTATUS_WIN_STATUS_ENLISTMENT_NOT_SUPERIOR = 0xC0190033, - MD_NTSTATUS_WIN_STATUS_FILE_IDENTITY_NOT_PERSISTENT = 0xC0190036, - MD_NTSTATUS_WIN_STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY = 0xC0190037, - MD_NTSTATUS_WIN_STATUS_CANT_CROSS_RM_BOUNDARY = 0xC0190038, - MD_NTSTATUS_WIN_STATUS_TXF_DIR_NOT_EMPTY = 0xC0190039, - MD_NTSTATUS_WIN_STATUS_INDOUBT_TRANSACTIONS_EXIST = 0xC019003A, - MD_NTSTATUS_WIN_STATUS_TM_VOLATILE = 0xC019003B, - MD_NTSTATUS_WIN_STATUS_ROLLBACK_TIMER_EXPIRED = 0xC019003C, - MD_NTSTATUS_WIN_STATUS_TXF_ATTRIBUTE_CORRUPT = 0xC019003D, - MD_NTSTATUS_WIN_STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION = 0xC019003E, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED = 0xC019003F, - MD_NTSTATUS_WIN_STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE = 0xC0190040, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_REQUIRED_PROMOTION = 0xC0190043, - MD_NTSTATUS_WIN_STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION = 0xC0190044, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONS_NOT_FROZEN = 0xC0190045, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_FREEZE_IN_PROGRESS = 0xC0190046, - MD_NTSTATUS_WIN_STATUS_NOT_SNAPSHOT_VOLUME = 0xC0190047, - MD_NTSTATUS_WIN_STATUS_NO_SAVEPOINT_WITH_OPEN_FILES = 0xC0190048, - MD_NTSTATUS_WIN_STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION = 0xC0190049, - MD_NTSTATUS_WIN_STATUS_TM_IDENTITY_MISMATCH = 0xC019004A, - MD_NTSTATUS_WIN_STATUS_FLOATED_SECTION = 0xC019004B, - MD_NTSTATUS_WIN_STATUS_CANNOT_ACCEPT_TRANSACTED_WORK = 0xC019004C, - MD_NTSTATUS_WIN_STATUS_CANNOT_ABORT_TRANSACTIONS = 0xC019004D, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_FOUND = 0xC019004E, - MD_NTSTATUS_WIN_STATUS_RESOURCEMANAGER_NOT_FOUND = 0xC019004F, - MD_NTSTATUS_WIN_STATUS_ENLISTMENT_NOT_FOUND = 0xC0190050, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_NOT_FOUND = 0xC0190051, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_NOT_ONLINE = 0xC0190052, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION = 0xC0190053, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ROOT = 0xC0190054, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_OBJECT_EXPIRED = 0xC0190055, - MD_NTSTATUS_WIN_STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION = 0xC0190056, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED = 0xC0190057, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_RECORD_TOO_LONG = 0xC0190058, - MD_NTSTATUS_WIN_STATUS_NO_LINK_TRACKING_IN_TRANSACTION = 0xC0190059, - MD_NTSTATUS_WIN_STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION = 0xC019005A, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_INTEGRITY_VIOLATED = 0xC019005B, - MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH = 0xC019005C, - MD_NTSTATUS_WIN_STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT = 0xC019005D, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_MUST_WRITETHROUGH = 0xC019005E, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_SUPERIOR = 0xC019005F, - MD_NTSTATUS_WIN_STATUS_EXPIRED_HANDLE = 0xC0190060, - MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ENLISTED = 0xC0190061, - MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_INVALID = 0xC01A0001, - MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_PARITY_INVALID = 0xC01A0002, - MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_REMAPPED = 0xC01A0003, - MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_INCOMPLETE = 0xC01A0004, - MD_NTSTATUS_WIN_STATUS_LOG_INVALID_RANGE = 0xC01A0005, - MD_NTSTATUS_WIN_STATUS_LOG_BLOCKS_EXHAUSTED = 0xC01A0006, - MD_NTSTATUS_WIN_STATUS_LOG_READ_CONTEXT_INVALID = 0xC01A0007, - MD_NTSTATUS_WIN_STATUS_LOG_RESTART_INVALID = 0xC01A0008, - MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_VERSION = 0xC01A0009, - MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_INVALID = 0xC01A000A, - MD_NTSTATUS_WIN_STATUS_LOG_READ_MODE_INVALID = 0xC01A000B, - MD_NTSTATUS_WIN_STATUS_LOG_METADATA_CORRUPT = 0xC01A000D, - MD_NTSTATUS_WIN_STATUS_LOG_METADATA_INVALID = 0xC01A000E, - MD_NTSTATUS_WIN_STATUS_LOG_METADATA_INCONSISTENT = 0xC01A000F, - MD_NTSTATUS_WIN_STATUS_LOG_RESERVATION_INVALID = 0xC01A0010, - MD_NTSTATUS_WIN_STATUS_LOG_CANT_DELETE = 0xC01A0011, - MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_LIMIT_EXCEEDED = 0xC01A0012, - MD_NTSTATUS_WIN_STATUS_LOG_START_OF_LOG = 0xC01A0013, - MD_NTSTATUS_WIN_STATUS_LOG_POLICY_ALREADY_INSTALLED = 0xC01A0014, - MD_NTSTATUS_WIN_STATUS_LOG_POLICY_NOT_INSTALLED = 0xC01A0015, - MD_NTSTATUS_WIN_STATUS_LOG_POLICY_INVALID = 0xC01A0016, - MD_NTSTATUS_WIN_STATUS_LOG_POLICY_CONFLICT = 0xC01A0017, - MD_NTSTATUS_WIN_STATUS_LOG_PINNED_ARCHIVE_TAIL = 0xC01A0018, - MD_NTSTATUS_WIN_STATUS_LOG_RECORD_NONEXISTENT = 0xC01A0019, - MD_NTSTATUS_WIN_STATUS_LOG_RECORDS_RESERVED_INVALID = 0xC01A001A, - MD_NTSTATUS_WIN_STATUS_LOG_SPACE_RESERVED_INVALID = 0xC01A001B, - MD_NTSTATUS_WIN_STATUS_LOG_TAIL_INVALID = 0xC01A001C, - MD_NTSTATUS_WIN_STATUS_LOG_FULL = 0xC01A001D, - MD_NTSTATUS_WIN_STATUS_LOG_MULTIPLEXED = 0xC01A001E, - MD_NTSTATUS_WIN_STATUS_LOG_DEDICATED = 0xC01A001F, - MD_NTSTATUS_WIN_STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS = 0xC01A0020, - MD_NTSTATUS_WIN_STATUS_LOG_ARCHIVE_IN_PROGRESS = 0xC01A0021, - MD_NTSTATUS_WIN_STATUS_LOG_EPHEMERAL = 0xC01A0022, - MD_NTSTATUS_WIN_STATUS_LOG_NOT_ENOUGH_CONTAINERS = 0xC01A0023, - MD_NTSTATUS_WIN_STATUS_LOG_CLIENT_ALREADY_REGISTERED = 0xC01A0024, - MD_NTSTATUS_WIN_STATUS_LOG_CLIENT_NOT_REGISTERED = 0xC01A0025, - MD_NTSTATUS_WIN_STATUS_LOG_FULL_HANDLER_IN_PROGRESS = 0xC01A0026, - MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_READ_FAILED = 0xC01A0027, - MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_WRITE_FAILED = 0xC01A0028, - MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_OPEN_FAILED = 0xC01A0029, - MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_STATE_INVALID = 0xC01A002A, - MD_NTSTATUS_WIN_STATUS_LOG_STATE_INVALID = 0xC01A002B, - MD_NTSTATUS_WIN_STATUS_LOG_PINNED = 0xC01A002C, - MD_NTSTATUS_WIN_STATUS_LOG_METADATA_FLUSH_FAILED = 0xC01A002D, - MD_NTSTATUS_WIN_STATUS_LOG_INCONSISTENT_SECURITY = 0xC01A002E, - MD_NTSTATUS_WIN_STATUS_LOG_APPENDED_FLUSH_FAILED = 0xC01A002F, - MD_NTSTATUS_WIN_STATUS_LOG_PINNED_RESERVATION = 0xC01A0030, - MD_NTSTATUS_WIN_STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD = 0xC01B00EA, - MD_NTSTATUS_WIN_STATUS_FLT_NO_HANDLER_DEFINED = 0xC01C0001, - MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALREADY_DEFINED = 0xC01C0002, - MD_NTSTATUS_WIN_STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST = 0xC01C0003, - MD_NTSTATUS_WIN_STATUS_FLT_DISALLOW_FAST_IO = 0xC01C0004, - MD_NTSTATUS_WIN_STATUS_FLT_INVALID_NAME_REQUEST = 0xC01C0005, - MD_NTSTATUS_WIN_STATUS_FLT_NOT_SAFE_TO_POST_OPERATION = 0xC01C0006, - MD_NTSTATUS_WIN_STATUS_FLT_NOT_INITIALIZED = 0xC01C0007, - MD_NTSTATUS_WIN_STATUS_FLT_FILTER_NOT_READY = 0xC01C0008, - MD_NTSTATUS_WIN_STATUS_FLT_POST_OPERATION_CLEANUP = 0xC01C0009, - MD_NTSTATUS_WIN_STATUS_FLT_INTERNAL_ERROR = 0xC01C000A, - MD_NTSTATUS_WIN_STATUS_FLT_DELETING_OBJECT = 0xC01C000B, - MD_NTSTATUS_WIN_STATUS_FLT_MUST_BE_NONPAGED_POOL = 0xC01C000C, - MD_NTSTATUS_WIN_STATUS_FLT_DUPLICATE_ENTRY = 0xC01C000D, - MD_NTSTATUS_WIN_STATUS_FLT_CBDQ_DISABLED = 0xC01C000E, - MD_NTSTATUS_WIN_STATUS_FLT_DO_NOT_ATTACH = 0xC01C000F, - MD_NTSTATUS_WIN_STATUS_FLT_DO_NOT_DETACH = 0xC01C0010, - MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_ALTITUDE_COLLISION = 0xC01C0011, - MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_NAME_COLLISION = 0xC01C0012, - MD_NTSTATUS_WIN_STATUS_FLT_FILTER_NOT_FOUND = 0xC01C0013, - MD_NTSTATUS_WIN_STATUS_FLT_VOLUME_NOT_FOUND = 0xC01C0014, - MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_NOT_FOUND = 0xC01C0015, - MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND = 0xC01C0016, - MD_NTSTATUS_WIN_STATUS_FLT_INVALID_CONTEXT_REGISTRATION = 0xC01C0017, - MD_NTSTATUS_WIN_STATUS_FLT_NAME_CACHE_MISS = 0xC01C0018, - MD_NTSTATUS_WIN_STATUS_FLT_NO_DEVICE_OBJECT = 0xC01C0019, - MD_NTSTATUS_WIN_STATUS_FLT_VOLUME_ALREADY_MOUNTED = 0xC01C001A, - MD_NTSTATUS_WIN_STATUS_FLT_ALREADY_ENLISTED = 0xC01C001B, - MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALREADY_LINKED = 0xC01C001C, - MD_NTSTATUS_WIN_STATUS_FLT_NO_WAITER_FOR_REPLY = 0xC01C0020, - MD_NTSTATUS_WIN_STATUS_FLT_REGISTRATION_BUSY = 0xC01C0023, - MD_NTSTATUS_WIN_STATUS_MONITOR_NO_DESCRIPTOR = 0xC01D0001, - MD_NTSTATUS_WIN_STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT = 0xC01D0002, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM = 0xC01D0003, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK = 0xC01D0004, - MD_NTSTATUS_WIN_STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED = 0xC01D0005, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK = 0xC01D0006, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK = 0xC01D0007, - MD_NTSTATUS_WIN_STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA = 0xC01D0008, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK = 0xC01D0009, - MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_MANUFACTURE_DATE = 0xC01D000A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER = 0xC01E0000, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER = 0xC01E0001, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER = 0xC01E0002, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_WAS_RESET = 0xC01E0003, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_DRIVER_MODEL = 0xC01E0004, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_MODE_CHANGED = 0xC01E0005, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_OCCLUDED = 0xC01E0006, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_DENIED = 0xC01E0007, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANNOTCOLORCONVERT = 0xC01E0008, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DRIVER_MISMATCH = 0xC01E0009, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED = 0xC01E000B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_UNOCCLUDED = 0xC01E000C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_WINDOWDC_NOT_AVAILABLE = 0xC01E000D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_WINDOWLESS_PRESENT_DISABLED = 0xC01E000E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_VIDEO_MEMORY = 0xC01E0100, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_LOCK_MEMORY = 0xC01E0101, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_BUSY = 0xC01E0102, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TOO_MANY_REFERENCES = 0xC01E0103, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TRY_AGAIN_LATER = 0xC01E0104, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TRY_AGAIN_NOW = 0xC01E0105, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_INVALID = 0xC01E0106, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE = 0xC01E0107, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED = 0xC01E0108, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION = 0xC01E0109, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE = 0xC01E0110, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION = 0xC01E0111, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_CLOSED = 0xC01E0112, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE = 0xC01E0113, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE = 0xC01E0114, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE = 0xC01E0115, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST = 0xC01E0116, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE = 0xC01E0200, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY = 0xC01E0300, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED = 0xC01E0301, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED = 0xC01E0302, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN = 0xC01E0303, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE = 0xC01E0304, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET = 0xC01E0305, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED = 0xC01E0306, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET = 0xC01E0308, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET = 0xC01E0309, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_FREQUENCY = 0xC01E030A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ACTIVE_REGION = 0xC01E030B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_TOTAL_REGION = 0xC01E030C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE = 0xC01E0310, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE = 0xC01E0311, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET = 0xC01E0312, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY = 0xC01E0313, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET = 0xC01E0314, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET = 0xC01E0315, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET = 0xC01E0316, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET = 0xC01E0317, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_ALREADY_IN_SET = 0xC01E0318, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH = 0xC01E0319, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY = 0xC01E031A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET = 0xC01E031B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE = 0xC01E031C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET = 0xC01E031D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET = 0xC01E031F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_STALE_MODESET = 0xC01E0320, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET = 0xC01E0321, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE = 0xC01E0322, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN = 0xC01E0323, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE = 0xC01E0324, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION = 0xC01E0325, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES = 0xC01E0326, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY = 0xC01E0327, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE = 0xC01E0328, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET = 0xC01E0329, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET = 0xC01E032A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR = 0xC01E032B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET = 0xC01E032C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET = 0xC01E032D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE = 0xC01E032E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE = 0xC01E032F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_RESOURCES_NOT_RELATED = 0xC01E0330, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE = 0xC01E0331, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE = 0xC01E0332, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET = 0xC01E0333, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER = 0xC01E0334, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_VIDPNMGR = 0xC01E0335, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_ACTIVE_VIDPN = 0xC01E0336, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY = 0xC01E0337, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_NOT_CONNECTED = 0xC01E0338, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY = 0xC01E0339, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE = 0xC01E033A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE = 0xC01E033B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_STRIDE = 0xC01E033C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PIXELFORMAT = 0xC01E033D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_COLORBASIS = 0xC01E033E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE = 0xC01E033F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY = 0xC01E0340, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT = 0xC01E0341, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE = 0xC01E0342, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN = 0xC01E0343, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL = 0xC01E0344, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION = 0xC01E0345, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED = 0xC01E0346, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_GAMMA_RAMP = 0xC01E0347, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED = 0xC01E0348, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED = 0xC01E0349, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_NOT_IN_MODESET = 0xC01E034A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON = 0xC01E034D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE = 0xC01E034E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE = 0xC01E034F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS = 0xC01E0350, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING = 0xC01E0352, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED = 0xC01E0353, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS = 0xC01E0354, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT = 0xC01E0355, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM = 0xC01E0356, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN = 0xC01E0357, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT = 0xC01E0358, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED = 0xC01E0359, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION = 0xC01E035A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_CLIENT_TYPE = 0xC01E035B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET = 0xC01E035C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED = 0xC01E0400, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED = 0xC01E0401, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER = 0xC01E0430, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED = 0xC01E0431, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED = 0xC01E0432, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY = 0xC01E0433, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED = 0xC01E0434, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON = 0xC01E0435, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE = 0xC01E0436, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER = 0xC01E0438, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED = 0xC01E043B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_NOT_SUPPORTED = 0xC01E0500, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_COPP_NOT_SUPPORTED = 0xC01E0501, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_UAB_NOT_SUPPORTED = 0xC01E0502, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS = 0xC01E0503, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST = 0xC01E0505, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INTERNAL_ERROR = 0xC01E050B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_HANDLE = 0xC01E050C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH = 0xC01E050E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED = 0xC01E050F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED = 0xC01E0510, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PVP_HFS_FAILED = 0xC01E0511, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_SRM = 0xC01E0512, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP = 0xC01E0513, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP = 0xC01E0514, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA = 0xC01E0515, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET = 0xC01E0516, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH = 0xC01E0517, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE = 0xC01E0518, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS = 0xC01E051A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS = 0xC01E051C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST = 0xC01E051D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR = 0xC01E051E, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS = 0xC01E051F, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED = 0xC01E0520, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST = 0xC01E0521, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_NOT_SUPPORTED = 0xC01E0580, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST = 0xC01E0581, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA = 0xC01E0582, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA = 0xC01E0583, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED = 0xC01E0584, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_DATA = 0xC01E0585, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE = 0xC01E0586, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING = 0xC01E0587, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MCA_INTERNAL_ERROR = 0xC01E0588, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND = 0xC01E0589, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH = 0xC01E058A, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM = 0xC01E058B, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE = 0xC01E058C, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS = 0xC01E058D, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED = 0xC01E05E0, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME = 0xC01E05E1, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP = 0xC01E05E2, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED = 0xC01E05E3, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_POINTER = 0xC01E05E4, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE = 0xC01E05E5, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL = 0xC01E05E6, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_INTERNAL_ERROR = 0xC01E05E7, - MD_NTSTATUS_WIN_STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS = 0xC01E05E8, - MD_NTSTATUS_WIN_STATUS_FVE_LOCKED_VOLUME = 0xC0210000, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_ENCRYPTED = 0xC0210001, - MD_NTSTATUS_WIN_STATUS_FVE_BAD_INFORMATION = 0xC0210002, - MD_NTSTATUS_WIN_STATUS_FVE_TOO_SMALL = 0xC0210003, - MD_NTSTATUS_WIN_STATUS_FVE_FAILED_WRONG_FS = 0xC0210004, - MD_NTSTATUS_WIN_STATUS_FVE_BAD_PARTITION_SIZE = 0xC0210005, - MD_NTSTATUS_WIN_STATUS_FVE_FS_NOT_EXTENDED = 0xC0210006, - MD_NTSTATUS_WIN_STATUS_FVE_FS_MOUNTED = 0xC0210007, - MD_NTSTATUS_WIN_STATUS_FVE_NO_LICENSE = 0xC0210008, - MD_NTSTATUS_WIN_STATUS_FVE_ACTION_NOT_ALLOWED = 0xC0210009, - MD_NTSTATUS_WIN_STATUS_FVE_BAD_DATA = 0xC021000A, - MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_NOT_BOUND = 0xC021000B, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_DATA_VOLUME = 0xC021000C, - MD_NTSTATUS_WIN_STATUS_FVE_CONV_READ_ERROR = 0xC021000D, - MD_NTSTATUS_WIN_STATUS_FVE_CONV_WRITE_ERROR = 0xC021000E, - MD_NTSTATUS_WIN_STATUS_FVE_OVERLAPPED_UPDATE = 0xC021000F, - MD_NTSTATUS_WIN_STATUS_FVE_FAILED_SECTOR_SIZE = 0xC0210010, - MD_NTSTATUS_WIN_STATUS_FVE_FAILED_AUTHENTICATION = 0xC0210011, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_OS_VOLUME = 0xC0210012, - MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_NOT_FOUND = 0xC0210013, - MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_INVALID = 0xC0210014, - MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_NO_VMK = 0xC0210015, - MD_NTSTATUS_WIN_STATUS_FVE_TPM_DISABLED = 0xC0210016, - MD_NTSTATUS_WIN_STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO = 0xC0210017, - MD_NTSTATUS_WIN_STATUS_FVE_TPM_INVALID_PCR = 0xC0210018, - MD_NTSTATUS_WIN_STATUS_FVE_TPM_NO_VMK = 0xC0210019, - MD_NTSTATUS_WIN_STATUS_FVE_PIN_INVALID = 0xC021001A, - MD_NTSTATUS_WIN_STATUS_FVE_AUTH_INVALID_APPLICATION = 0xC021001B, - MD_NTSTATUS_WIN_STATUS_FVE_AUTH_INVALID_CONFIG = 0xC021001C, - MD_NTSTATUS_WIN_STATUS_FVE_DEBUGGER_ENABLED = 0xC021001D, - MD_NTSTATUS_WIN_STATUS_FVE_DRY_RUN_FAILED = 0xC021001E, - MD_NTSTATUS_WIN_STATUS_FVE_BAD_METADATA_POINTER = 0xC021001F, - MD_NTSTATUS_WIN_STATUS_FVE_OLD_METADATA_COPY = 0xC0210020, - MD_NTSTATUS_WIN_STATUS_FVE_REBOOT_REQUIRED = 0xC0210021, - MD_NTSTATUS_WIN_STATUS_FVE_RAW_ACCESS = 0xC0210022, - MD_NTSTATUS_WIN_STATUS_FVE_RAW_BLOCKED = 0xC0210023, - MD_NTSTATUS_WIN_STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY = 0xC0210024, - MD_NTSTATUS_WIN_STATUS_FVE_MOR_FAILED = 0xC0210025, - MD_NTSTATUS_WIN_STATUS_FVE_NO_FEATURE_LICENSE = 0xC0210026, - MD_NTSTATUS_WIN_STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED = 0xC0210027, - MD_NTSTATUS_WIN_STATUS_FVE_CONV_RECOVERY_FAILED = 0xC0210028, - MD_NTSTATUS_WIN_STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG = 0xC0210029, - MD_NTSTATUS_WIN_STATUS_FVE_INVALID_DATUM_TYPE = 0xC021002A, - MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_TOO_SMALL = 0xC0210030, - MD_NTSTATUS_WIN_STATUS_FVE_ENH_PIN_INVALID = 0xC0210031, - MD_NTSTATUS_WIN_STATUS_FVE_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE = 0xC0210032, - MD_NTSTATUS_WIN_STATUS_FVE_WIPE_NOT_ALLOWED_ON_TP_STORAGE = 0xC0210033, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_ON_CSV_STACK = 0xC0210034, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_ON_CLUSTER = 0xC0210035, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING = 0xC0210036, - MD_NTSTATUS_WIN_STATUS_FVE_WIPE_CANCEL_NOT_APPLICABLE = 0xC0210037, - MD_NTSTATUS_WIN_STATUS_FVE_EDRIVE_DRY_RUN_FAILED = 0xC0210038, - MD_NTSTATUS_WIN_STATUS_FVE_SECUREBOOT_DISABLED = 0xC0210039, - MD_NTSTATUS_WIN_STATUS_FVE_SECUREBOOT_CONFIG_CHANGE = 0xC021003A, - MD_NTSTATUS_WIN_STATUS_FVE_DEVICE_LOCKEDOUT = 0xC021003B, - MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT = 0xC021003C, - MD_NTSTATUS_WIN_STATUS_FVE_NOT_DE_VOLUME = 0xC021003D, - MD_NTSTATUS_WIN_STATUS_FVE_PROTECTION_DISABLED = 0xC021003E, - MD_NTSTATUS_WIN_STATUS_FVE_PROTECTION_CANNOT_BE_DISABLED = 0xC021003F, - MD_NTSTATUS_WIN_STATUS_FWP_CALLOUT_NOT_FOUND = 0xC0220001, - MD_NTSTATUS_WIN_STATUS_FWP_CONDITION_NOT_FOUND = 0xC0220002, - MD_NTSTATUS_WIN_STATUS_FWP_FILTER_NOT_FOUND = 0xC0220003, - MD_NTSTATUS_WIN_STATUS_FWP_LAYER_NOT_FOUND = 0xC0220004, - MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_NOT_FOUND = 0xC0220005, - MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND = 0xC0220006, - MD_NTSTATUS_WIN_STATUS_FWP_SUBLAYER_NOT_FOUND = 0xC0220007, - MD_NTSTATUS_WIN_STATUS_FWP_NOT_FOUND = 0xC0220008, - MD_NTSTATUS_WIN_STATUS_FWP_ALREADY_EXISTS = 0xC0220009, - MD_NTSTATUS_WIN_STATUS_FWP_IN_USE = 0xC022000A, - MD_NTSTATUS_WIN_STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS = 0xC022000B, - MD_NTSTATUS_WIN_STATUS_FWP_WRONG_SESSION = 0xC022000C, - MD_NTSTATUS_WIN_STATUS_FWP_NO_TXN_IN_PROGRESS = 0xC022000D, - MD_NTSTATUS_WIN_STATUS_FWP_TXN_IN_PROGRESS = 0xC022000E, - MD_NTSTATUS_WIN_STATUS_FWP_TXN_ABORTED = 0xC022000F, - MD_NTSTATUS_WIN_STATUS_FWP_SESSION_ABORTED = 0xC0220010, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_TXN = 0xC0220011, - MD_NTSTATUS_WIN_STATUS_FWP_TIMEOUT = 0xC0220012, - MD_NTSTATUS_WIN_STATUS_FWP_NET_EVENTS_DISABLED = 0xC0220013, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_LAYER = 0xC0220014, - MD_NTSTATUS_WIN_STATUS_FWP_KM_CLIENTS_ONLY = 0xC0220015, - MD_NTSTATUS_WIN_STATUS_FWP_LIFETIME_MISMATCH = 0xC0220016, - MD_NTSTATUS_WIN_STATUS_FWP_BUILTIN_OBJECT = 0xC0220017, - MD_NTSTATUS_WIN_STATUS_FWP_TOO_MANY_CALLOUTS = 0xC0220018, - MD_NTSTATUS_WIN_STATUS_FWP_NOTIFICATION_DROPPED = 0xC0220019, - MD_NTSTATUS_WIN_STATUS_FWP_TRAFFIC_MISMATCH = 0xC022001A, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_SA_STATE = 0xC022001B, - MD_NTSTATUS_WIN_STATUS_FWP_NULL_POINTER = 0xC022001C, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_ENUMERATOR = 0xC022001D, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_FLAGS = 0xC022001E, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_NET_MASK = 0xC022001F, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_RANGE = 0xC0220020, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_INTERVAL = 0xC0220021, - MD_NTSTATUS_WIN_STATUS_FWP_ZERO_LENGTH_ARRAY = 0xC0220022, - MD_NTSTATUS_WIN_STATUS_FWP_NULL_DISPLAY_NAME = 0xC0220023, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_ACTION_TYPE = 0xC0220024, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_WEIGHT = 0xC0220025, - MD_NTSTATUS_WIN_STATUS_FWP_MATCH_TYPE_MISMATCH = 0xC0220026, - MD_NTSTATUS_WIN_STATUS_FWP_TYPE_MISMATCH = 0xC0220027, - MD_NTSTATUS_WIN_STATUS_FWP_OUT_OF_BOUNDS = 0xC0220028, - MD_NTSTATUS_WIN_STATUS_FWP_RESERVED = 0xC0220029, - MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_CONDITION = 0xC022002A, - MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_KEYMOD = 0xC022002B, - MD_NTSTATUS_WIN_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER = 0xC022002C, - MD_NTSTATUS_WIN_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER = 0xC022002D, - MD_NTSTATUS_WIN_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER = 0xC022002E, - MD_NTSTATUS_WIN_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT = 0xC022002F, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_AUTH_METHOD = 0xC0220030, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_DH_GROUP = 0xC0220031, - MD_NTSTATUS_WIN_STATUS_FWP_EM_NOT_SUPPORTED = 0xC0220032, - MD_NTSTATUS_WIN_STATUS_FWP_NEVER_MATCH = 0xC0220033, - MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_CONTEXT_MISMATCH = 0xC0220034, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_PARAMETER = 0xC0220035, - MD_NTSTATUS_WIN_STATUS_FWP_TOO_MANY_SUBLAYERS = 0xC0220036, - MD_NTSTATUS_WIN_STATUS_FWP_CALLOUT_NOTIFICATION_FAILED = 0xC0220037, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_AUTH_TRANSFORM = 0xC0220038, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_CIPHER_TRANSFORM = 0xC0220039, - MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM = 0xC022003A, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_TRANSFORM_COMBINATION = 0xC022003B, - MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_AUTH_METHOD = 0xC022003C, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_TUNNEL_ENDPOINT = 0xC022003D, - MD_NTSTATUS_WIN_STATUS_FWP_L2_DRIVER_NOT_READY = 0xC022003E, - MD_NTSTATUS_WIN_STATUS_FWP_KEY_DICTATOR_ALREADY_REGISTERED = 0xC022003F, - MD_NTSTATUS_WIN_STATUS_FWP_KEY_DICTATION_INVALID_KEYING_MATERIAL = 0xC0220040, - MD_NTSTATUS_WIN_STATUS_FWP_CONNECTIONS_DISABLED = 0xC0220041, - MD_NTSTATUS_WIN_STATUS_FWP_INVALID_DNS_NAME = 0xC0220042, - MD_NTSTATUS_WIN_STATUS_FWP_STILL_ON = 0xC0220043, - MD_NTSTATUS_WIN_STATUS_FWP_IKEEXT_NOT_RUNNING = 0xC0220044, - MD_NTSTATUS_WIN_STATUS_FWP_TCPIP_NOT_READY = 0xC0220100, - MD_NTSTATUS_WIN_STATUS_FWP_INJECT_HANDLE_CLOSING = 0xC0220101, - MD_NTSTATUS_WIN_STATUS_FWP_INJECT_HANDLE_STALE = 0xC0220102, - MD_NTSTATUS_WIN_STATUS_FWP_CANNOT_PEND = 0xC0220103, - MD_NTSTATUS_WIN_STATUS_FWP_DROP_NOICMP = 0xC0220104, - MD_NTSTATUS_WIN_STATUS_NDIS_CLOSING = 0xC0230002, - MD_NTSTATUS_WIN_STATUS_NDIS_BAD_VERSION = 0xC0230004, - MD_NTSTATUS_WIN_STATUS_NDIS_BAD_CHARACTERISTICS = 0xC0230005, - MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_NOT_FOUND = 0xC0230006, - MD_NTSTATUS_WIN_STATUS_NDIS_OPEN_FAILED = 0xC0230007, - MD_NTSTATUS_WIN_STATUS_NDIS_DEVICE_FAILED = 0xC0230008, - MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_FULL = 0xC0230009, - MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_EXISTS = 0xC023000A, - MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_NOT_FOUND = 0xC023000B, - MD_NTSTATUS_WIN_STATUS_NDIS_REQUEST_ABORTED = 0xC023000C, - MD_NTSTATUS_WIN_STATUS_NDIS_RESET_IN_PROGRESS = 0xC023000D, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PACKET = 0xC023000F, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_DEVICE_REQUEST = 0xC0230010, - MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_NOT_READY = 0xC0230011, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_LENGTH = 0xC0230014, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_DATA = 0xC0230015, - MD_NTSTATUS_WIN_STATUS_NDIS_BUFFER_TOO_SHORT = 0xC0230016, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_OID = 0xC0230017, - MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_REMOVED = 0xC0230018, - MD_NTSTATUS_WIN_STATUS_NDIS_UNSUPPORTED_MEDIA = 0xC0230019, - MD_NTSTATUS_WIN_STATUS_NDIS_GROUP_ADDRESS_IN_USE = 0xC023001A, - MD_NTSTATUS_WIN_STATUS_NDIS_FILE_NOT_FOUND = 0xC023001B, - MD_NTSTATUS_WIN_STATUS_NDIS_ERROR_READING_FILE = 0xC023001C, - MD_NTSTATUS_WIN_STATUS_NDIS_ALREADY_MAPPED = 0xC023001D, - MD_NTSTATUS_WIN_STATUS_NDIS_RESOURCE_CONFLICT = 0xC023001E, - MD_NTSTATUS_WIN_STATUS_NDIS_MEDIA_DISCONNECTED = 0xC023001F, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_ADDRESS = 0xC0230022, - MD_NTSTATUS_WIN_STATUS_NDIS_PAUSED = 0xC023002A, - MD_NTSTATUS_WIN_STATUS_NDIS_INTERFACE_NOT_FOUND = 0xC023002B, - MD_NTSTATUS_WIN_STATUS_NDIS_UNSUPPORTED_REVISION = 0xC023002C, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PORT = 0xC023002D, - MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PORT_STATE = 0xC023002E, - MD_NTSTATUS_WIN_STATUS_NDIS_LOW_POWER_STATE = 0xC023002F, - MD_NTSTATUS_WIN_STATUS_NDIS_REINIT_REQUIRED = 0xC0230030, - MD_NTSTATUS_WIN_STATUS_NDIS_NOT_SUPPORTED = 0xC02300BB, - MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_POLICY = 0xC023100F, - MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED = 0xC0231012, - MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_PATH_REJECTED = 0xC0231013, - MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED = 0xC0232000, - MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_MEDIA_IN_USE = 0xC0232001, - MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_POWER_STATE_INVALID = 0xC0232002, - MD_NTSTATUS_WIN_STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL = 0xC0232003, - MD_NTSTATUS_WIN_STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL = 0xC0232004, - MD_NTSTATUS_WIN_STATUS_TPM_ERROR_MASK = 0xC0290000, - MD_NTSTATUS_WIN_STATUS_TPM_AUTHFAIL = 0xC0290001, - MD_NTSTATUS_WIN_STATUS_TPM_BADINDEX = 0xC0290002, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_PARAMETER = 0xC0290003, - MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAILURE = 0xC0290004, - MD_NTSTATUS_WIN_STATUS_TPM_CLEAR_DISABLED = 0xC0290005, - MD_NTSTATUS_WIN_STATUS_TPM_DEACTIVATED = 0xC0290006, - MD_NTSTATUS_WIN_STATUS_TPM_DISABLED = 0xC0290007, - MD_NTSTATUS_WIN_STATUS_TPM_DISABLED_CMD = 0xC0290008, - MD_NTSTATUS_WIN_STATUS_TPM_FAIL = 0xC0290009, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_ORDINAL = 0xC029000A, - MD_NTSTATUS_WIN_STATUS_TPM_INSTALL_DISABLED = 0xC029000B, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_KEYHANDLE = 0xC029000C, - MD_NTSTATUS_WIN_STATUS_TPM_KEYNOTFOUND = 0xC029000D, - MD_NTSTATUS_WIN_STATUS_TPM_INAPPROPRIATE_ENC = 0xC029000E, - MD_NTSTATUS_WIN_STATUS_TPM_MIGRATEFAIL = 0xC029000F, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_PCR_INFO = 0xC0290010, - MD_NTSTATUS_WIN_STATUS_TPM_NOSPACE = 0xC0290011, - MD_NTSTATUS_WIN_STATUS_TPM_NOSRK = 0xC0290012, - MD_NTSTATUS_WIN_STATUS_TPM_NOTSEALED_BLOB = 0xC0290013, - MD_NTSTATUS_WIN_STATUS_TPM_OWNER_SET = 0xC0290014, - MD_NTSTATUS_WIN_STATUS_TPM_RESOURCES = 0xC0290015, - MD_NTSTATUS_WIN_STATUS_TPM_SHORTRANDOM = 0xC0290016, - MD_NTSTATUS_WIN_STATUS_TPM_SIZE = 0xC0290017, - MD_NTSTATUS_WIN_STATUS_TPM_WRONGPCRVAL = 0xC0290018, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_PARAM_SIZE = 0xC0290019, - MD_NTSTATUS_WIN_STATUS_TPM_SHA_THREAD = 0xC029001A, - MD_NTSTATUS_WIN_STATUS_TPM_SHA_ERROR = 0xC029001B, - MD_NTSTATUS_WIN_STATUS_TPM_FAILEDSELFTEST = 0xC029001C, - MD_NTSTATUS_WIN_STATUS_TPM_AUTH2FAIL = 0xC029001D, - MD_NTSTATUS_WIN_STATUS_TPM_BADTAG = 0xC029001E, - MD_NTSTATUS_WIN_STATUS_TPM_IOERROR = 0xC029001F, - MD_NTSTATUS_WIN_STATUS_TPM_ENCRYPT_ERROR = 0xC0290020, - MD_NTSTATUS_WIN_STATUS_TPM_DECRYPT_ERROR = 0xC0290021, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_AUTHHANDLE = 0xC0290022, - MD_NTSTATUS_WIN_STATUS_TPM_NO_ENDORSEMENT = 0xC0290023, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_KEYUSAGE = 0xC0290024, - MD_NTSTATUS_WIN_STATUS_TPM_WRONG_ENTITYTYPE = 0xC0290025, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_POSTINIT = 0xC0290026, - MD_NTSTATUS_WIN_STATUS_TPM_INAPPROPRIATE_SIG = 0xC0290027, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_KEY_PROPERTY = 0xC0290028, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_MIGRATION = 0xC0290029, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_SCHEME = 0xC029002A, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_DATASIZE = 0xC029002B, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_MODE = 0xC029002C, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_PRESENCE = 0xC029002D, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_VERSION = 0xC029002E, - MD_NTSTATUS_WIN_STATUS_TPM_NO_WRAP_TRANSPORT = 0xC029002F, - MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAIL_UNSUCCESSFUL = 0xC0290030, - MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAIL_SUCCESSFUL = 0xC0290031, - MD_NTSTATUS_WIN_STATUS_TPM_NOTRESETABLE = 0xC0290032, - MD_NTSTATUS_WIN_STATUS_TPM_NOTLOCAL = 0xC0290033, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_TYPE = 0xC0290034, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_RESOURCE = 0xC0290035, - MD_NTSTATUS_WIN_STATUS_TPM_NOTFIPS = 0xC0290036, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_FAMILY = 0xC0290037, - MD_NTSTATUS_WIN_STATUS_TPM_NO_NV_PERMISSION = 0xC0290038, - MD_NTSTATUS_WIN_STATUS_TPM_REQUIRES_SIGN = 0xC0290039, - MD_NTSTATUS_WIN_STATUS_TPM_KEY_NOTSUPPORTED = 0xC029003A, - MD_NTSTATUS_WIN_STATUS_TPM_AUTH_CONFLICT = 0xC029003B, - MD_NTSTATUS_WIN_STATUS_TPM_AREA_LOCKED = 0xC029003C, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_LOCALITY = 0xC029003D, - MD_NTSTATUS_WIN_STATUS_TPM_READ_ONLY = 0xC029003E, - MD_NTSTATUS_WIN_STATUS_TPM_PER_NOWRITE = 0xC029003F, - MD_NTSTATUS_WIN_STATUS_TPM_FAMILYCOUNT = 0xC0290040, - MD_NTSTATUS_WIN_STATUS_TPM_WRITE_LOCKED = 0xC0290041, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_ATTRIBUTES = 0xC0290042, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_STRUCTURE = 0xC0290043, - MD_NTSTATUS_WIN_STATUS_TPM_KEY_OWNER_CONTROL = 0xC0290044, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_COUNTER = 0xC0290045, - MD_NTSTATUS_WIN_STATUS_TPM_NOT_FULLWRITE = 0xC0290046, - MD_NTSTATUS_WIN_STATUS_TPM_CONTEXT_GAP = 0xC0290047, - MD_NTSTATUS_WIN_STATUS_TPM_MAXNVWRITES = 0xC0290048, - MD_NTSTATUS_WIN_STATUS_TPM_NOOPERATOR = 0xC0290049, - MD_NTSTATUS_WIN_STATUS_TPM_RESOURCEMISSING = 0xC029004A, - MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_LOCK = 0xC029004B, - MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_FAMILY = 0xC029004C, - MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_ADMIN = 0xC029004D, - MD_NTSTATUS_WIN_STATUS_TPM_TRANSPORT_NOTEXCLUSIVE = 0xC029004E, - MD_NTSTATUS_WIN_STATUS_TPM_OWNER_CONTROL = 0xC029004F, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_RESOURCES = 0xC0290050, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_INPUT_DATA0 = 0xC0290051, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_INPUT_DATA1 = 0xC0290052, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_ISSUER_SETTINGS = 0xC0290053, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_TPM_SETTINGS = 0xC0290054, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_STAGE = 0xC0290055, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_ISSUER_VALIDITY = 0xC0290056, - MD_NTSTATUS_WIN_STATUS_TPM_DAA_WRONG_W = 0xC0290057, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_HANDLE = 0xC0290058, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_DELEGATE = 0xC0290059, - MD_NTSTATUS_WIN_STATUS_TPM_BADCONTEXT = 0xC029005A, - MD_NTSTATUS_WIN_STATUS_TPM_TOOMANYCONTEXTS = 0xC029005B, - MD_NTSTATUS_WIN_STATUS_TPM_MA_TICKET_SIGNATURE = 0xC029005C, - MD_NTSTATUS_WIN_STATUS_TPM_MA_DESTINATION = 0xC029005D, - MD_NTSTATUS_WIN_STATUS_TPM_MA_SOURCE = 0xC029005E, - MD_NTSTATUS_WIN_STATUS_TPM_MA_AUTHORITY = 0xC029005F, - MD_NTSTATUS_WIN_STATUS_TPM_PERMANENTEK = 0xC0290061, - MD_NTSTATUS_WIN_STATUS_TPM_BAD_SIGNATURE = 0xC0290062, - MD_NTSTATUS_WIN_STATUS_TPM_NOCONTEXTSPACE = 0xC0290063, - MD_NTSTATUS_WIN_STATUS_TPM_COMMAND_BLOCKED = 0xC0290400, - MD_NTSTATUS_WIN_STATUS_TPM_INVALID_HANDLE = 0xC0290401, - MD_NTSTATUS_WIN_STATUS_TPM_DUPLICATE_VHANDLE = 0xC0290402, - MD_NTSTATUS_WIN_STATUS_TPM_EMBEDDED_COMMAND_BLOCKED = 0xC0290403, - MD_NTSTATUS_WIN_STATUS_TPM_EMBEDDED_COMMAND_UNSUPPORTED = 0xC0290404, - MD_NTSTATUS_WIN_STATUS_TPM_RETRY = 0xC0290800, - MD_NTSTATUS_WIN_STATUS_TPM_NEEDS_SELFTEST = 0xC0290801, - MD_NTSTATUS_WIN_STATUS_TPM_DOING_SELFTEST = 0xC0290802, - MD_NTSTATUS_WIN_STATUS_TPM_DEFEND_LOCK_RUNNING = 0xC0290803, - MD_NTSTATUS_WIN_STATUS_TPM_COMMAND_CANCELED = 0xC0291001, - MD_NTSTATUS_WIN_STATUS_TPM_TOO_MANY_CONTEXTS = 0xC0291002, - MD_NTSTATUS_WIN_STATUS_TPM_NOT_FOUND = 0xC0291003, - MD_NTSTATUS_WIN_STATUS_TPM_ACCESS_DENIED = 0xC0291004, - MD_NTSTATUS_WIN_STATUS_TPM_INSUFFICIENT_BUFFER = 0xC0291005, - MD_NTSTATUS_WIN_STATUS_TPM_PPI_FUNCTION_UNSUPPORTED = 0xC0291006, - MD_NTSTATUS_WIN_STATUS_PCP_ERROR_MASK = 0xC0292000, - MD_NTSTATUS_WIN_STATUS_PCP_DEVICE_NOT_READY = 0xC0292001, - MD_NTSTATUS_WIN_STATUS_PCP_INVALID_HANDLE = 0xC0292002, - MD_NTSTATUS_WIN_STATUS_PCP_INVALID_PARAMETER = 0xC0292003, - MD_NTSTATUS_WIN_STATUS_PCP_FLAG_NOT_SUPPORTED = 0xC0292004, - MD_NTSTATUS_WIN_STATUS_PCP_NOT_SUPPORTED = 0xC0292005, - MD_NTSTATUS_WIN_STATUS_PCP_BUFFER_TOO_SMALL = 0xC0292006, - MD_NTSTATUS_WIN_STATUS_PCP_INTERNAL_ERROR = 0xC0292007, - MD_NTSTATUS_WIN_STATUS_PCP_AUTHENTICATION_FAILED = 0xC0292008, - MD_NTSTATUS_WIN_STATUS_PCP_AUTHENTICATION_IGNORED = 0xC0292009, - MD_NTSTATUS_WIN_STATUS_PCP_POLICY_NOT_FOUND = 0xC029200A, - MD_NTSTATUS_WIN_STATUS_PCP_PROFILE_NOT_FOUND = 0xC029200B, - MD_NTSTATUS_WIN_STATUS_PCP_VALIDATION_FAILED = 0xC029200C, - MD_NTSTATUS_WIN_STATUS_PCP_DEVICE_NOT_FOUND = 0xC029200D, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_HYPERCALL_CODE = 0xC0350002, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_HYPERCALL_INPUT = 0xC0350003, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_ALIGNMENT = 0xC0350004, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARAMETER = 0xC0350005, - MD_NTSTATUS_WIN_STATUS_HV_ACCESS_DENIED = 0xC0350006, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARTITION_STATE = 0xC0350007, - MD_NTSTATUS_WIN_STATUS_HV_OPERATION_DENIED = 0xC0350008, - MD_NTSTATUS_WIN_STATUS_HV_UNKNOWN_PROPERTY = 0xC0350009, - MD_NTSTATUS_WIN_STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE = 0xC035000A, - MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_MEMORY = 0xC035000B, - MD_NTSTATUS_WIN_STATUS_HV_PARTITION_TOO_DEEP = 0xC035000C, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARTITION_ID = 0xC035000D, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_VP_INDEX = 0xC035000E, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_PORT_ID = 0xC0350011, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_CONNECTION_ID = 0xC0350012, - MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_BUFFERS = 0xC0350013, - MD_NTSTATUS_WIN_STATUS_HV_NOT_ACKNOWLEDGED = 0xC0350014, - MD_NTSTATUS_WIN_STATUS_HV_ACKNOWLEDGED = 0xC0350016, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_SAVE_RESTORE_STATE = 0xC0350017, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_SYNIC_STATE = 0xC0350018, - MD_NTSTATUS_WIN_STATUS_HV_OBJECT_IN_USE = 0xC0350019, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO = 0xC035001A, - MD_NTSTATUS_WIN_STATUS_HV_NO_DATA = 0xC035001B, - MD_NTSTATUS_WIN_STATUS_HV_INACTIVE = 0xC035001C, - MD_NTSTATUS_WIN_STATUS_HV_NO_RESOURCES = 0xC035001D, - MD_NTSTATUS_WIN_STATUS_HV_FEATURE_UNAVAILABLE = 0xC035001E, - MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_BUFFER = 0xC0350033, - MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_DEVICE_DOMAINS = 0xC0350038, - MD_NTSTATUS_WIN_STATUS_HV_INVALID_LP_INDEX = 0xC0350041, - MD_NTSTATUS_WIN_STATUS_HV_NOT_PRESENT = 0xC0351000, - MD_NTSTATUS_WIN_STATUS_IPSEC_BAD_SPI = 0xC0360001, - MD_NTSTATUS_WIN_STATUS_IPSEC_SA_LIFETIME_EXPIRED = 0xC0360002, - MD_NTSTATUS_WIN_STATUS_IPSEC_WRONG_SA = 0xC0360003, - MD_NTSTATUS_WIN_STATUS_IPSEC_REPLAY_CHECK_FAILED = 0xC0360004, - MD_NTSTATUS_WIN_STATUS_IPSEC_INVALID_PACKET = 0xC0360005, - MD_NTSTATUS_WIN_STATUS_IPSEC_INTEGRITY_CHECK_FAILED = 0xC0360006, - MD_NTSTATUS_WIN_STATUS_IPSEC_CLEAR_TEXT_DROP = 0xC0360007, - MD_NTSTATUS_WIN_STATUS_IPSEC_AUTH_FIREWALL_DROP = 0xC0360008, - MD_NTSTATUS_WIN_STATUS_IPSEC_THROTTLE_DROP = 0xC0360009, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_BLOCK = 0xC0368000, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_RECEIVED_MULTICAST = 0xC0368001, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_INVALID_PACKET = 0xC0368002, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED = 0xC0368003, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_MAX_ENTRIES = 0xC0368004, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED = 0xC0368005, - MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES = 0xC0368006, - MD_NTSTATUS_WIN_STATUS_VID_DUPLICATE_HANDLER = 0xC0370001, - MD_NTSTATUS_WIN_STATUS_VID_TOO_MANY_HANDLERS = 0xC0370002, - MD_NTSTATUS_WIN_STATUS_VID_QUEUE_FULL = 0xC0370003, - MD_NTSTATUS_WIN_STATUS_VID_HANDLER_NOT_PRESENT = 0xC0370004, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_OBJECT_NAME = 0xC0370005, - MD_NTSTATUS_WIN_STATUS_VID_PARTITION_NAME_TOO_LONG = 0xC0370006, - MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG = 0xC0370007, - MD_NTSTATUS_WIN_STATUS_VID_PARTITION_ALREADY_EXISTS = 0xC0370008, - MD_NTSTATUS_WIN_STATUS_VID_PARTITION_DOES_NOT_EXIST = 0xC0370009, - MD_NTSTATUS_WIN_STATUS_VID_PARTITION_NAME_NOT_FOUND = 0xC037000A, - MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS = 0xC037000B, - MD_NTSTATUS_WIN_STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT = 0xC037000C, - MD_NTSTATUS_WIN_STATUS_VID_MB_STILL_REFERENCED = 0xC037000D, - MD_NTSTATUS_WIN_STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED = 0xC037000E, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_NUMA_SETTINGS = 0xC037000F, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_NUMA_NODE_INDEX = 0xC0370010, - MD_NTSTATUS_WIN_STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED = 0xC0370011, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE = 0xC0370012, - MD_NTSTATUS_WIN_STATUS_VID_PAGE_RANGE_OVERFLOW = 0xC0370013, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE = 0xC0370014, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_GPA_RANGE_HANDLE = 0xC0370015, - MD_NTSTATUS_WIN_STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE = 0xC0370016, - MD_NTSTATUS_WIN_STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED = 0xC0370017, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_PPM_HANDLE = 0xC0370018, - MD_NTSTATUS_WIN_STATUS_VID_MBPS_ARE_LOCKED = 0xC0370019, - MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_CLOSED = 0xC037001A, - MD_NTSTATUS_WIN_STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED = 0xC037001B, - MD_NTSTATUS_WIN_STATUS_VID_STOP_PENDING = 0xC037001C, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_PROCESSOR_STATE = 0xC037001D, - MD_NTSTATUS_WIN_STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT = 0xC037001E, - MD_NTSTATUS_WIN_STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED = 0xC037001F, - MD_NTSTATUS_WIN_STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET = 0xC0370020, - MD_NTSTATUS_WIN_STATUS_VID_MMIO_RANGE_DESTROYED = 0xC0370021, - MD_NTSTATUS_WIN_STATUS_VID_INVALID_CHILD_GPA_PAGE_SET = 0xC0370022, - MD_NTSTATUS_WIN_STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED = 0xC0370023, - MD_NTSTATUS_WIN_STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL = 0xC0370024, - MD_NTSTATUS_WIN_STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE = 0xC0370025, - MD_NTSTATUS_WIN_STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT = 0xC0370026, - MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_CORRUPT = 0xC0370027, - MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM = 0xC0370028, - MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_INCOMPATIBLE = 0xC0370029, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DATABASE_FULL = 0xC0380001, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED = 0xC0380002, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC = 0xC0380003, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED = 0xC0380004, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME = 0xC0380005, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_DUPLICATE = 0xC0380006, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_DYNAMIC = 0xC0380007, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_ID_INVALID = 0xC0380008, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_INVALID = 0xC0380009, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAST_VOTER = 0xC038000A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_INVALID = 0xC038000B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS = 0xC038000C, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED = 0xC038000D, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL = 0xC038000E, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS = 0xC038000F, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS = 0xC0380010, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_MISSING = 0xC0380011, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_NOT_EMPTY = 0xC0380012, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE = 0xC0380013, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_REVECTORING_FAILED = 0xC0380014, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID = 0xC0380015, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_SET_NOT_CONTAINED = 0xC0380016, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS = 0xC0380017, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES = 0xC0380018, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED = 0xC0380019, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_ALREADY_USED = 0xC038001A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS = 0xC038001B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION = 0xC038001C, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED = 0xC038001D, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION = 0xC038001E, - MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH = 0xC038001F, - MD_NTSTATUS_WIN_STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED = 0xC0380020, - MD_NTSTATUS_WIN_STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID = 0xC0380021, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS = 0xC0380022, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_IN_SYNC = 0xC0380023, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE = 0xC0380024, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_INDEX_INVALID = 0xC0380025, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_MISSING = 0xC0380026, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_NOT_DETACHED = 0xC0380027, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_REGENERATING = 0xC0380028, - MD_NTSTATUS_WIN_STATUS_VOLMGR_ALL_DISKS_FAILED = 0xC0380029, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_REGISTERED_USERS = 0xC038002A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_SUCH_USER = 0xC038002B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NOTIFICATION_RESET = 0xC038002C, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID = 0xC038002D, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID = 0xC038002E, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_DUPLICATE = 0xC038002F, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_ID_INVALID = 0xC0380030, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_INVALID = 0xC0380031, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_NAME_INVALID = 0xC0380032, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_OFFLINE = 0xC0380033, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_HAS_QUORUM = 0xC0380034, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_WITHOUT_QUORUM = 0xC0380035, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PARTITION_STYLE_INVALID = 0xC0380036, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PARTITION_UPDATE_FAILED = 0xC0380037, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_IN_SYNC = 0xC0380038, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_INDEX_DUPLICATE = 0xC0380039, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_INDEX_INVALID = 0xC038003A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_LAST_ACTIVE = 0xC038003B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_MISSING = 0xC038003C, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_REGENERATING = 0xC038003D, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_TYPE_INVALID = 0xC038003E, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_RAID5 = 0xC038003F, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_SIMPLE = 0xC0380040, - MD_NTSTATUS_WIN_STATUS_VOLMGR_STRUCTURE_SIZE_INVALID = 0xC0380041, - MD_NTSTATUS_WIN_STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS = 0xC0380042, - MD_NTSTATUS_WIN_STATUS_VOLMGR_TRANSACTION_IN_PROGRESS = 0xC0380043, - MD_NTSTATUS_WIN_STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE = 0xC0380044, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK = 0xC0380045, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_ID_INVALID = 0xC0380046, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_LENGTH_INVALID = 0xC0380047, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE = 0xC0380048, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_NOT_MIRRORED = 0xC0380049, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_NOT_RETAINED = 0xC038004A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_OFFLINE = 0xC038004B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_RETAINED = 0xC038004C, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID = 0xC038004D, - MD_NTSTATUS_WIN_STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE = 0xC038004E, - MD_NTSTATUS_WIN_STATUS_VOLMGR_BAD_BOOT_DISK = 0xC038004F, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_OFFLINE = 0xC0380050, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_ONLINE = 0xC0380051, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NOT_PRIMARY_PACK = 0xC0380052, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED = 0xC0380053, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID = 0xC0380054, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID = 0xC0380055, - MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_MIRRORED = 0xC0380056, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED = 0xC0380057, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_VALID_LOG_COPIES = 0xC0380058, - MD_NTSTATUS_WIN_STATUS_VOLMGR_PRIMARY_PACK_PRESENT = 0xC0380059, - MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID = 0xC038005A, - MD_NTSTATUS_WIN_STATUS_VOLMGR_MIRROR_NOT_SUPPORTED = 0xC038005B, - MD_NTSTATUS_WIN_STATUS_VOLMGR_RAID5_NOT_SUPPORTED = 0xC038005C, - MD_NTSTATUS_WIN_STATUS_BCD_TOO_MANY_ELEMENTS = 0xC0390002, - MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_MISSING = 0xC03A0001, - MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH = 0xC03A0002, - MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_CORRUPT = 0xC03A0003, - MD_NTSTATUS_WIN_STATUS_VHD_FORMAT_UNKNOWN = 0xC03A0004, - MD_NTSTATUS_WIN_STATUS_VHD_FORMAT_UNSUPPORTED_VERSION = 0xC03A0005, - MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH = 0xC03A0006, - MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION = 0xC03A0007, - MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_CORRUPT = 0xC03A0008, - MD_NTSTATUS_WIN_STATUS_VHD_BLOCK_ALLOCATION_FAILURE = 0xC03A0009, - MD_NTSTATUS_WIN_STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT = 0xC03A000A, - MD_NTSTATUS_WIN_STATUS_VHD_INVALID_BLOCK_SIZE = 0xC03A000B, - MD_NTSTATUS_WIN_STATUS_VHD_BITMAP_MISMATCH = 0xC03A000C, - MD_NTSTATUS_WIN_STATUS_VHD_PARENT_VHD_NOT_FOUND = 0xC03A000D, - MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_ID_MISMATCH = 0xC03A000E, - MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH = 0xC03A000F, - MD_NTSTATUS_WIN_STATUS_VHD_METADATA_READ_FAILURE = 0xC03A0010, - MD_NTSTATUS_WIN_STATUS_VHD_METADATA_WRITE_FAILURE = 0xC03A0011, - MD_NTSTATUS_WIN_STATUS_VHD_INVALID_SIZE = 0xC03A0012, - MD_NTSTATUS_WIN_STATUS_VHD_INVALID_FILE_SIZE = 0xC03A0013, - MD_NTSTATUS_WIN_STATUS_VIRTDISK_PROVIDER_NOT_FOUND = 0xC03A0014, - MD_NTSTATUS_WIN_STATUS_VIRTDISK_NOT_VIRTUAL_DISK = 0xC03A0015, - MD_NTSTATUS_WIN_STATUS_VHD_PARENT_VHD_ACCESS_DENIED = 0xC03A0016, - MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH = 0xC03A0017, - MD_NTSTATUS_WIN_STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED = 0xC03A0018, - MD_NTSTATUS_WIN_STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT = 0xC03A0019, - MD_NTSTATUS_WIN_STATUS_VIRTUAL_DISK_LIMITATION = 0xC03A001A, - MD_NTSTATUS_WIN_STATUS_VHD_INVALID_TYPE = 0xC03A001B, - MD_NTSTATUS_WIN_STATUS_VHD_INVALID_STATE = 0xC03A001C, - MD_NTSTATUS_WIN_STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE = 0xC03A001D, - MD_NTSTATUS_WIN_STATUS_VIRTDISK_DISK_ALREADY_OWNED = 0xC03A001E, - MD_NTSTATUS_WIN_STATUS_VIRTDISK_DISK_ONLINE_AND_WRITABLE = 0xC03A001F, - MD_NTSTATUS_WIN_STATUS_CTLOG_TRACKING_NOT_INITIALIZED = 0xC03A0020, - MD_NTSTATUS_WIN_STATUS_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE = 0xC03A0021, - MD_NTSTATUS_WIN_STATUS_CTLOG_VHD_CHANGED_OFFLINE = 0xC03A0022, - MD_NTSTATUS_WIN_STATUS_CTLOG_INVALID_TRACKING_STATE = 0xC03A0023, - MD_NTSTATUS_WIN_STATUS_CTLOG_INCONSISTENT_TRACKING_FILE = 0xC03A0024, - MD_NTSTATUS_WIN_STATUS_VHD_METADATA_FULL = 0xC03A0028, - MD_NTSTATUS_WIN_STATUS_RKF_KEY_NOT_FOUND = 0xC0400001, - MD_NTSTATUS_WIN_STATUS_RKF_DUPLICATE_KEY = 0xC0400002, - MD_NTSTATUS_WIN_STATUS_RKF_BLOB_FULL = 0xC0400003, - MD_NTSTATUS_WIN_STATUS_RKF_STORE_FULL = 0xC0400004, - MD_NTSTATUS_WIN_STATUS_RKF_FILE_BLOCKED = 0xC0400005, - MD_NTSTATUS_WIN_STATUS_RKF_ACTIVE_KEY = 0xC0400006, - MD_NTSTATUS_WIN_STATUS_RDBSS_RESTART_OPERATION = 0xC0410001, - MD_NTSTATUS_WIN_STATUS_RDBSS_CONTINUE_OPERATION = 0xC0410002, - MD_NTSTATUS_WIN_STATUS_RDBSS_POST_OPERATION = 0xC0410003, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_HANDLE = 0xC0420001, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_READ_NOT_PERMITTED = 0xC0420002, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_WRITE_NOT_PERMITTED = 0xC0420003, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_PDU = 0xC0420004, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_AUTHENTICATION = 0xC0420005, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_REQUEST_NOT_SUPPORTED = 0xC0420006, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_OFFSET = 0xC0420007, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_AUTHORIZATION = 0xC0420008, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_PREPARE_QUEUE_FULL = 0xC0420009, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_ATTRIBUTE_NOT_FOUND = 0xC042000A, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_ATTRIBUTE_NOT_LONG = 0xC042000B, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE = 0xC042000C, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH = 0xC042000D, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNLIKELY = 0xC042000E, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION = 0xC042000F, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNSUPPORTED_GROUP_TYPE = 0xC0420010, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_RESOURCES = 0xC0420011, - MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNKNOWN_ERROR = 0xC0421000, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_ROLLBACK_DETECTED = 0xC0430001, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_VIOLATION = 0xC0430002, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_INVALID_POLICY = 0xC0430003, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND = 0xC0430004, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_NOT_SIGNED = 0xC0430005, - MD_NTSTATUS_WIN_STATUS_SECUREBOOT_FILE_REPLACED = 0xC0430007, - MD_NTSTATUS_WIN_STATUS_AUDIO_ENGINE_NODE_NOT_FOUND = 0xC0440001, - MD_NTSTATUS_WIN_STATUS_HDAUDIO_EMPTY_CONNECTION_LIST = 0xC0440002, - MD_NTSTATUS_WIN_STATUS_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED = 0xC0440003, - MD_NTSTATUS_WIN_STATUS_HDAUDIO_NO_LOGICAL_DEVICES_CREATED = 0xC0440004, - MD_NTSTATUS_WIN_STATUS_HDAUDIO_NULL_LINKED_LIST_ENTRY = 0xC0440005, - MD_NTSTATUS_WIN_STATUS_VOLSNAP_BOOTFILE_NOT_VALID = 0xC0500003, - MD_NTSTATUS_WIN_STATUS_IO_PREEMPTED = 0xC0510001, - MD_NTSTATUS_WIN_STATUS_SVHDX_ERROR_STORED = 0xC05C0000, - MD_NTSTATUS_WIN_STATUS_SVHDX_ERROR_NOT_AVAILABLE = 0xC05CFF00, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_AVAILABLE = 0xC05CFF01, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED = 0xC05CFF02, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED = 0xC05CFF03, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED = 0xC05CFF04, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED = 0xC05CFF05, - MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED = 0xC05CFF06, - MD_NTSTATUS_WIN_STATUS_SVHDX_RESERVATION_CONFLICT = 0xC05CFF07, - MD_NTSTATUS_WIN_STATUS_SVHDX_WRONG_FILE_TYPE = 0xC05CFF08, - MD_NTSTATUS_WIN_STATUS_SVHDX_VERSION_MISMATCH = 0xC05CFF09, - MD_NTSTATUS_WIN_STATUS_VHD_SHARED = 0xC05CFF0A, - MD_NTSTATUS_WIN_STATUS_SPACES_RESILIENCY_TYPE_INVALID = 0xC0E70003, - MD_NTSTATUS_WIN_STATUS_SPACES_DRIVE_SECTOR_SIZE_INVALID = 0xC0E70004, - MD_NTSTATUS_WIN_STATUS_SPACES_INTERLEAVE_LENGTH_INVALID = 0xC0E70009, - MD_NTSTATUS_WIN_STATUS_SPACES_NUMBER_OF_COLUMNS_INVALID = 0xC0E7000A, - MD_NTSTATUS_WIN_STATUS_SPACES_NOT_ENOUGH_DRIVES = 0xC0E7000B -} MDNTStatusCodeWin; - -// These constants are defined in the MSDN documentation of -// the EXCEPTION_RECORD structure. -typedef enum { - MD_ACCESS_VIOLATION_WIN_READ = 0, - MD_ACCESS_VIOLATION_WIN_WRITE = 1, - MD_ACCESS_VIOLATION_WIN_EXEC = 8 -} MDAccessViolationTypeWin; - -// These constants are defined in the MSDN documentation of -// the EXCEPTION_RECORD structure. -typedef enum { - MD_IN_PAGE_ERROR_WIN_READ = 0, - MD_IN_PAGE_ERROR_WIN_WRITE = 1, - MD_IN_PAGE_ERROR_WIN_EXEC = 8 -} MDInPageErrorTypeWin; - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_format.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_format.h deleted file mode 100644 index 251e503df..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_format.h +++ /dev/null @@ -1,1045 +0,0 @@ -/* Copyright (c) 2006, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* minidump_format.h: A cross-platform reimplementation of minidump-related - * portions of DbgHelp.h from the Windows Platform SDK. - * - * (This is C99 source, please don't corrupt it with C++.) - * - * Structures that are defined by Microsoft to contain a zero-length array - * are instead defined here to contain an array with one element, as - * zero-length arrays are forbidden by standard C and C++. In these cases, - * *_minsize constants are provided to be used in place of sizeof. For a - * cleaner interface to these sizes when using C++, see minidump_size.h. - * - * These structures are also sufficient to populate minidump files. - * - * These definitions may be extended to support handling minidump files - * for other CPUs and other operating systems. - * - * Because precise data type sizes are crucial for this implementation to - * function properly and portably in terms of interoperability with minidumps - * produced by DbgHelp on Windows, a set of primitive types with known sizes - * are used as the basis of each structure defined by this file. DbgHelp - * on Windows is assumed to be the reference implementation; this file - * seeks to provide a cross-platform compatible implementation. To avoid - * collisions with the types and values defined and used by DbgHelp in the - * event that this implementation is used on Windows, each type and value - * defined here is given a new name, beginning with "MD". Names of the - * equivalent types and values in the Windows Platform SDK are given in - * comments. - * - * Author: Mark Mentovai */ - - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" - - -#if defined(_MSC_VER) -/* Disable "zero-sized array in struct/union" warnings when compiling in - * MSVC. DbgHelp.h does this too. */ -#pragma warning(push) -#pragma warning(disable:4200) -#endif /* _MSC_VER */ - - -/* - * guiddef.h - */ - -typedef struct { - uint32_t data1; - uint16_t data2; - uint16_t data3; - uint8_t data4[8]; -} MDGUID; /* GUID */ - - -/* - * WinNT.h - */ - -/* Non-x86 CPU identifiers found in the high 24 bits of - * (MDRawContext*).context_flags. These aren't used by Breakpad, but are - * defined here for reference, to avoid assigning values that conflict - * (although some values already conflict). */ -#define MD_CONTEXT_IA64 0x00080000 /* CONTEXT_IA64 */ -/* Additional values from winnt.h in the Windows CE 5.0 SDK: */ -#define MD_CONTEXT_SHX 0x000000c0 /* CONTEXT_SH4 (Super-H, includes SH3) */ -#define MD_CONTEXT_ALPHA 0x00020000 /* CONTEXT_ALPHA */ - -/* As of Windows 7 SP1, the number of flag bits has increased to - * include 0x40 (CONTEXT_XSTATE): - * http://msdn.microsoft.com/en-us/library/hh134238%28v=vs.85%29.aspx */ -#define MD_CONTEXT_CPU_MASK 0xffffff00 - - -/* This is a base type for MDRawContextX86 and MDRawContextPPC. This - * structure should never be allocated directly. The actual structure type - * can be determined by examining the context_flags field. */ -typedef struct { - uint32_t context_flags; -} MDRawContextBase; - -#include "minidump_cpu_amd64.h" -#include "minidump_cpu_arm.h" -#include "minidump_cpu_arm64.h" -#include "minidump_cpu_mips.h" -#include "minidump_cpu_ppc.h" -#include "minidump_cpu_ppc64.h" -#include "minidump_cpu_sparc.h" -#include "minidump_cpu_x86.h" - -/* - * WinVer.h - */ - - -typedef struct { - uint32_t signature; - uint32_t struct_version; - uint32_t file_version_hi; - uint32_t file_version_lo; - uint32_t product_version_hi; - uint32_t product_version_lo; - uint32_t file_flags_mask; /* Identifies valid bits in fileFlags */ - uint32_t file_flags; - uint32_t file_os; - uint32_t file_type; - uint32_t file_subtype; - uint32_t file_date_hi; - uint32_t file_date_lo; -} MDVSFixedFileInfo; /* VS_FIXEDFILEINFO */ - -/* For (MDVSFixedFileInfo).signature */ -#define MD_VSFIXEDFILEINFO_SIGNATURE 0xfeef04bd - /* VS_FFI_SIGNATURE */ - -/* For (MDVSFixedFileInfo).version */ -#define MD_VSFIXEDFILEINFO_VERSION 0x00010000 - /* VS_FFI_STRUCVERSION */ - -/* For (MDVSFixedFileInfo).file_flags_mask and - * (MDVSFixedFileInfo).file_flags */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG 0x00000001 - /* VS_FF_DEBUG */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRERELEASE 0x00000002 - /* VS_FF_PRERELEASE */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PATCHED 0x00000004 - /* VS_FF_PATCHED */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRIVATEBUILD 0x00000008 - /* VS_FF_PRIVATEBUILD */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_INFOINFERRED 0x00000010 - /* VS_FF_INFOINFERRED */ -#define MD_VSFIXEDFILEINFO_FILE_FLAGS_SPECIALBUILD 0x00000020 - /* VS_FF_SPECIALBUILD */ - -/* For (MDVSFixedFileInfo).file_os: high 16 bits */ -#define MD_VSFIXEDFILEINFO_FILE_OS_UNKNOWN 0 /* VOS_UNKNOWN */ -#define MD_VSFIXEDFILEINFO_FILE_OS_DOS (1 << 16) /* VOS_DOS */ -#define MD_VSFIXEDFILEINFO_FILE_OS_OS216 (2 << 16) /* VOS_OS216 */ -#define MD_VSFIXEDFILEINFO_FILE_OS_OS232 (3 << 16) /* VOS_OS232 */ -#define MD_VSFIXEDFILEINFO_FILE_OS_NT (4 << 16) /* VOS_NT */ -#define MD_VSFIXEDFILEINFO_FILE_OS_WINCE (5 << 16) /* VOS_WINCE */ -/* Low 16 bits */ -#define MD_VSFIXEDFILEINFO_FILE_OS__BASE 0 /* VOS__BASE */ -#define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS16 1 /* VOS__WINDOWS16 */ -#define MD_VSFIXEDFILEINFO_FILE_OS__PM16 2 /* VOS__PM16 */ -#define MD_VSFIXEDFILEINFO_FILE_OS__PM32 3 /* VOS__PM32 */ -#define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32 4 /* VOS__WINDOWS32 */ - -/* For (MDVSFixedFileInfo).file_type */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_UNKNOWN 0 /* VFT_UNKNOWN */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_APP 1 /* VFT_APP */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_DLL 2 /* VFT_DLL */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_DRV 3 /* VFT_DLL */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_FONT 4 /* VFT_FONT */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_VXD 5 /* VFT_VXD */ -#define MD_VSFIXEDFILEINFO_FILE_TYPE_STATIC_LIB 7 /* VFT_STATIC_LIB */ - -/* For (MDVSFixedFileInfo).file_subtype */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN 0 - /* VFT2_UNKNOWN */ -/* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_DRV */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_PRINTER 1 - /* VFT2_DRV_PRINTER */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_KEYBOARD 2 - /* VFT2_DRV_KEYBOARD */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_LANGUAGE 3 - /* VFT2_DRV_LANGUAGE */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_DISPLAY 4 - /* VFT2_DRV_DISPLAY */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_MOUSE 5 - /* VFT2_DRV_MOUSE */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_NETWORK 6 - /* VFT2_DRV_NETWORK */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SYSTEM 7 - /* VFT2_DRV_SYSTEM */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INSTALLABLE 8 - /* VFT2_DRV_INSTALLABLE */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SOUND 9 - /* VFT2_DRV_SOUND */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_COMM 10 - /* VFT2_DRV_COMM */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INPUTMETHOD 11 - /* VFT2_DRV_INPUTMETHOD */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_VERSIONED_PRINTER 12 - /* VFT2_DRV_VERSIONED_PRINTER */ -/* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_FONT */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_RASTER 1 - /* VFT2_FONT_RASTER */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_VECTOR 2 - /* VFT2_FONT_VECTOR */ -#define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_TRUETYPE 3 - /* VFT2_FONT_TRUETYPE */ - - -/* - * DbgHelp.h - */ - - -/* An MDRVA is an offset into the minidump file. The beginning of the - * MDRawHeader is at offset 0. */ -typedef uint32_t MDRVA; /* RVA */ - -typedef struct { - uint32_t data_size; - MDRVA rva; -} MDLocationDescriptor; /* MINIDUMP_LOCATION_DESCRIPTOR */ - - -typedef struct { - /* The base address of the memory range on the host that produced the - * minidump. */ - uint64_t start_of_memory_range; - - MDLocationDescriptor memory; -} MDMemoryDescriptor; /* MINIDUMP_MEMORY_DESCRIPTOR */ - - -typedef struct { - uint32_t signature; - uint32_t version; - uint32_t stream_count; - MDRVA stream_directory_rva; /* A |stream_count|-sized array of - * MDRawDirectory structures. */ - uint32_t checksum; /* Can be 0. In fact, that's all that's - * been found in minidump files. */ - uint32_t time_date_stamp; /* time_t */ - uint64_t flags; -} MDRawHeader; /* MINIDUMP_HEADER */ - -/* For (MDRawHeader).signature and (MDRawHeader).version. Note that only the - * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION. Per the - * documentation, the high 16 bits are implementation-specific. */ -#define MD_HEADER_SIGNATURE 0x504d444d /* 'PMDM' */ - /* MINIDUMP_SIGNATURE */ -#define MD_HEADER_VERSION 0x0000a793 /* 42899 */ - /* MINIDUMP_VERSION */ - -/* For (MDRawHeader).flags: */ -typedef enum { - /* MD_NORMAL is the standard type of minidump. It includes full - * streams for the thread list, module list, exception, system info, - * and miscellaneous info. A memory list stream is also present, - * pointing to the same stack memory contained in the thread list, - * as well as a 256-byte region around the instruction address that - * was executing when the exception occurred. Stack memory is from - * 4 bytes below a thread's stack pointer up to the top of the - * memory region encompassing the stack. */ - MD_NORMAL = 0x00000000, - MD_WITH_DATA_SEGS = 0x00000001, - MD_WITH_FULL_MEMORY = 0x00000002, - MD_WITH_HANDLE_DATA = 0x00000004, - MD_FILTER_MEMORY = 0x00000008, - MD_SCAN_MEMORY = 0x00000010, - MD_WITH_UNLOADED_MODULES = 0x00000020, - MD_WITH_INDIRECTLY_REFERENCED_MEMORY = 0x00000040, - MD_FILTER_MODULE_PATHS = 0x00000080, - MD_WITH_PROCESS_THREAD_DATA = 0x00000100, - MD_WITH_PRIVATE_READ_WRITE_MEMORY = 0x00000200, - MD_WITHOUT_OPTIONAL_DATA = 0x00000400, - MD_WITH_FULL_MEMORY_INFO = 0x00000800, - MD_WITH_THREAD_INFO = 0x00001000, - MD_WITH_CODE_SEGS = 0x00002000, - MD_WITHOUT_AUXILLIARY_SEGS = 0x00004000, - MD_WITH_FULL_AUXILLIARY_STATE = 0x00008000, - MD_WITH_PRIVATE_WRITE_COPY_MEMORY = 0x00010000, - MD_IGNORE_INACCESSIBLE_MEMORY = 0x00020000, - MD_WITH_TOKEN_INFORMATION = 0x00040000 -} MDType; /* MINIDUMP_TYPE */ - - -typedef struct { - uint32_t stream_type; - MDLocationDescriptor location; -} MDRawDirectory; /* MINIDUMP_DIRECTORY */ - -/* For (MDRawDirectory).stream_type */ -typedef enum { - MD_UNUSED_STREAM = 0, - MD_RESERVED_STREAM_0 = 1, - MD_RESERVED_STREAM_1 = 2, - MD_THREAD_LIST_STREAM = 3, /* MDRawThreadList */ - MD_MODULE_LIST_STREAM = 4, /* MDRawModuleList */ - MD_MEMORY_LIST_STREAM = 5, /* MDRawMemoryList */ - MD_EXCEPTION_STREAM = 6, /* MDRawExceptionStream */ - MD_SYSTEM_INFO_STREAM = 7, /* MDRawSystemInfo */ - MD_THREAD_EX_LIST_STREAM = 8, - MD_MEMORY_64_LIST_STREAM = 9, - MD_COMMENT_STREAM_A = 10, - MD_COMMENT_STREAM_W = 11, - MD_HANDLE_DATA_STREAM = 12, - MD_FUNCTION_TABLE_STREAM = 13, - MD_UNLOADED_MODULE_LIST_STREAM = 14, - MD_MISC_INFO_STREAM = 15, /* MDRawMiscInfo */ - MD_MEMORY_INFO_LIST_STREAM = 16, /* MDRawMemoryInfoList */ - MD_THREAD_INFO_LIST_STREAM = 17, - MD_HANDLE_OPERATION_LIST_STREAM = 18, - MD_TOKEN_STREAM = 19, - MD_JAVASCRIPT_DATA_STREAM = 20, - MD_SYSTEM_MEMORY_INFO_STREAM = 21, - MD_PROCESS_VM_COUNTERS_STREAM = 22, - MD_LAST_RESERVED_STREAM = 0x0000ffff, - - /* Breakpad extension types. 0x4767 = "Gg" */ - MD_BREAKPAD_INFO_STREAM = 0x47670001, /* MDRawBreakpadInfo */ - MD_ASSERTION_INFO_STREAM = 0x47670002, /* MDRawAssertionInfo */ - /* These are additional minidump stream values which are specific to - * the linux breakpad implementation. */ - MD_LINUX_CPU_INFO = 0x47670003, /* /proc/cpuinfo */ - MD_LINUX_PROC_STATUS = 0x47670004, /* /proc/$x/status */ - MD_LINUX_LSB_RELEASE = 0x47670005, /* /etc/lsb-release */ - MD_LINUX_CMD_LINE = 0x47670006, /* /proc/$x/cmdline */ - MD_LINUX_ENVIRON = 0x47670007, /* /proc/$x/environ */ - MD_LINUX_AUXV = 0x47670008, /* /proc/$x/auxv */ - MD_LINUX_MAPS = 0x47670009, /* /proc/$x/maps */ - MD_LINUX_DSO_DEBUG = 0x4767000A /* MDRawDebug{32,64} */ -} MDStreamType; /* MINIDUMP_STREAM_TYPE */ - - -typedef struct { - uint32_t length; /* Length of buffer in bytes (not characters), - * excluding 0-terminator */ - uint16_t buffer[1]; /* UTF-16-encoded, 0-terminated */ -} MDString; /* MINIDUMP_STRING */ - -static const size_t MDString_minsize = offsetof(MDString, buffer[0]); - - -typedef struct { - uint32_t thread_id; - uint32_t suspend_count; - uint32_t priority_class; - uint32_t priority; - uint64_t teb; /* Thread environment block */ - MDMemoryDescriptor stack; - MDLocationDescriptor thread_context; /* MDRawContext[CPU] */ -} MDRawThread; /* MINIDUMP_THREAD */ - - -typedef struct { - uint32_t number_of_threads; - MDRawThread threads[1]; -} MDRawThreadList; /* MINIDUMP_THREAD_LIST */ - -static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList, - threads[0]); - - -typedef struct { - uint64_t base_of_image; - uint32_t size_of_image; - uint32_t checksum; /* 0 if unknown */ - uint32_t time_date_stamp; /* time_t */ - MDRVA module_name_rva; /* MDString, pathname or filename */ - MDVSFixedFileInfo version_info; - - /* The next field stores a CodeView record and is populated when a module's - * debug information resides in a PDB file. It identifies the PDB file. */ - MDLocationDescriptor cv_record; - - /* The next field is populated when a module's debug information resides - * in a DBG file. It identifies the DBG file. This field is effectively - * obsolete with modules built by recent toolchains. */ - MDLocationDescriptor misc_record; - - /* Alignment problem: reserved0 and reserved1 are defined by the platform - * SDK as 64-bit quantities. However, that results in a structure whose - * alignment is unpredictable on different CPUs and ABIs. If the ABI - * specifies full alignment of 64-bit quantities in structures (as ppc - * does), there will be padding between miscRecord and reserved0. If - * 64-bit quantities can be aligned on 32-bit boundaries (as on x86), - * this padding will not exist. (Note that the structure up to this point - * contains 1 64-bit member followed by 21 32-bit members.) - * As a workaround, reserved0 and reserved1 are instead defined here as - * four 32-bit quantities. This should be harmless, as there are - * currently no known uses for these fields. */ - uint32_t reserved0[2]; - uint32_t reserved1[2]; -} MDRawModule; /* MINIDUMP_MODULE */ - -/* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to - * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC). - * This doesn't occur on systems that don't tail-pad in this manner. Define - * this macro to be the usable size of the MDRawModule struct, and use it in - * place of sizeof(MDRawModule). */ -#define MD_MODULE_SIZE 108 - - -/* (MDRawModule).cv_record can reference MDCVInfoPDB20 or MDCVInfoPDB70. - * Ref.: http://www.debuginfo.com/articles/debuginfomatch.html - * MDCVInfoPDB70 is the expected structure type with recent toolchains. */ - -typedef struct { - uint32_t signature; - uint32_t offset; /* Offset to debug data (expect 0 in minidump) */ -} MDCVHeader; - -typedef struct { - MDCVHeader cv_header; - uint32_t signature; /* time_t debug information created */ - uint32_t age; /* revision of PDB file */ - uint8_t pdb_file_name[1]; /* Pathname or filename of PDB file */ -} MDCVInfoPDB20; - -static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20, - pdb_file_name[0]); - -#define MD_CVINFOPDB20_SIGNATURE 0x3031424e /* cvHeader.signature = '01BN' */ - -typedef struct { - uint32_t cv_signature; - MDGUID signature; /* GUID, identifies PDB file */ - uint32_t age; /* Identifies incremental changes to PDB file */ - uint8_t pdb_file_name[1]; /* Pathname or filename of PDB file, - * 0-terminated 8-bit character data (UTF-8?) */ -} MDCVInfoPDB70; - -static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70, - pdb_file_name[0]); - -#define MD_CVINFOPDB70_SIGNATURE 0x53445352 /* cvSignature = 'SDSR' */ - -/* - * Modern ELF toolchains insert a "build id" into the ELF headers that - * usually contains a hash of some ELF headers + sections to uniquely - * identify a binary. - * - * https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Developer_Guide/compiling-build-id.html - * https://sourceware.org/binutils/docs-2.26/ld/Options.html#index-g_t_002d_002dbuild_002did-292 - */ -typedef struct { - uint32_t cv_signature; - uint8_t build_id[1]; /* Bytes of build id from GNU_BUILD_ID ELF note. - * This is variable-length, but usually 20 bytes - * as the binutils ld default is a SHA-1 hash. */ -} MDCVInfoELF; - -static const size_t MDCVInfoELF_minsize = offsetof(MDCVInfoELF, - build_id[0]); - -#define MD_CVINFOELF_SIGNATURE 0x4270454c /* cvSignature = 'BpEL' */ - -/* In addition to the two CodeView record formats above, used for linking - * to external pdb files, it is possible for debugging data to be carried - * directly in the CodeView record itself. These signature values will - * be found in the first 4 bytes of the CodeView record. Additional values - * not commonly experienced in the wild are given by "Microsoft Symbol and - * Type Information", http://www.x86.org/ftp/manuals/tools/sym.pdf, section - * 7.2. An in-depth description of the CodeView 4.1 format is given by - * "Undocumented Windows 2000 Secrets", Windows 2000 Debugging Support/ - * Microsoft Symbol File Internals/CodeView Subsections, - * http://www.rawol.com/features/undocumented/sbs-w2k-1-windows-2000-debugging-support.pdf - */ -#define MD_CVINFOCV41_SIGNATURE 0x3930424e /* '90BN', CodeView 4.10. */ -#define MD_CVINFOCV50_SIGNATURE 0x3131424e /* '11BN', CodeView 5.0, - * MS C7-format (/Z7). */ - -#define MD_CVINFOUNKNOWN_SIGNATURE 0xffffffff /* An unlikely value. */ - -/* (MDRawModule).miscRecord can reference MDImageDebugMisc. The Windows - * structure is actually defined in WinNT.h. This structure is effectively - * obsolete with modules built by recent toolchains. */ - -typedef struct { - uint32_t data_type; /* IMAGE_DEBUG_TYPE_*, not defined here because - * this debug record type is mostly obsolete. */ - uint32_t length; /* Length of entire MDImageDebugMisc structure */ - uint8_t unicode; /* True if data is multibyte */ - uint8_t reserved[3]; - uint8_t data[1]; -} MDImageDebugMisc; /* IMAGE_DEBUG_MISC */ - -static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc, - data[0]); - - -typedef struct { - uint32_t number_of_modules; - MDRawModule modules[1]; -} MDRawModuleList; /* MINIDUMP_MODULE_LIST */ - -static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList, - modules[0]); - - -typedef struct { - uint32_t number_of_memory_ranges; - MDMemoryDescriptor memory_ranges[1]; -} MDRawMemoryList; /* MINIDUMP_MEMORY_LIST */ - -static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList, - memory_ranges[0]); - - -#define MD_EXCEPTION_MAXIMUM_PARAMETERS 15 - -typedef struct { - uint32_t exception_code; /* Windows: MDExceptionCodeWin, - * Mac OS X: MDExceptionMac, - * Linux: MDExceptionCodeLinux. */ - uint32_t exception_flags; /* Windows: 1 if noncontinuable, - Mac OS X: MDExceptionCodeMac. */ - uint64_t exception_record; /* Address (in the minidump-producing host's - * memory) of another MDException, for - * nested exceptions. */ - uint64_t exception_address; /* The address that caused the exception. - * Mac OS X: exception subcode (which is - * typically the address). */ - uint32_t number_parameters; /* Number of valid elements in - * exception_information. */ - uint32_t __align; - uint64_t exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS]; -} MDException; /* MINIDUMP_EXCEPTION */ - -#include "minidump_exception_linux.h" -#include "minidump_exception_mac.h" -#include "minidump_exception_ps3.h" -#include "minidump_exception_solaris.h" -#include "minidump_exception_win32.h" - -typedef struct { - uint32_t thread_id; /* Thread in which the exception - * occurred. Corresponds to - * (MDRawThread).thread_id. */ - uint32_t __align; - MDException exception_record; - MDLocationDescriptor thread_context; /* MDRawContext[CPU] */ -} MDRawExceptionStream; /* MINIDUMP_EXCEPTION_STREAM */ - - -typedef union { - struct { - uint32_t vendor_id[3]; /* cpuid 0: ebx, edx, ecx */ - uint32_t version_information; /* cpuid 1: eax */ - uint32_t feature_information; /* cpuid 1: edx */ - uint32_t amd_extended_cpu_features; /* cpuid 0x80000001, ebx */ - } x86_cpu_info; - struct { - uint32_t cpuid; - uint32_t elf_hwcaps; /* linux specific, 0 otherwise */ - } arm_cpu_info; - struct { - uint64_t processor_features[2]; - } other_cpu_info; -} MDCPUInformation; /* CPU_INFORMATION */ - -/* For (MDCPUInformation).arm_cpu_info.elf_hwcaps. - * This matches the Linux kernel definitions from */ -typedef enum { - MD_CPU_ARM_ELF_HWCAP_SWP = (1 << 0), - MD_CPU_ARM_ELF_HWCAP_HALF = (1 << 1), - MD_CPU_ARM_ELF_HWCAP_THUMB = (1 << 2), - MD_CPU_ARM_ELF_HWCAP_26BIT = (1 << 3), - MD_CPU_ARM_ELF_HWCAP_FAST_MULT = (1 << 4), - MD_CPU_ARM_ELF_HWCAP_FPA = (1 << 5), - MD_CPU_ARM_ELF_HWCAP_VFP = (1 << 6), - MD_CPU_ARM_ELF_HWCAP_EDSP = (1 << 7), - MD_CPU_ARM_ELF_HWCAP_JAVA = (1 << 8), - MD_CPU_ARM_ELF_HWCAP_IWMMXT = (1 << 9), - MD_CPU_ARM_ELF_HWCAP_CRUNCH = (1 << 10), - MD_CPU_ARM_ELF_HWCAP_THUMBEE = (1 << 11), - MD_CPU_ARM_ELF_HWCAP_NEON = (1 << 12), - MD_CPU_ARM_ELF_HWCAP_VFPv3 = (1 << 13), - MD_CPU_ARM_ELF_HWCAP_VFPv3D16 = (1 << 14), - MD_CPU_ARM_ELF_HWCAP_TLS = (1 << 15), - MD_CPU_ARM_ELF_HWCAP_VFPv4 = (1 << 16), - MD_CPU_ARM_ELF_HWCAP_IDIVA = (1 << 17), - MD_CPU_ARM_ELF_HWCAP_IDIVT = (1 << 18), -} MDCPUInformationARMElfHwCaps; - -typedef struct { - /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO - * structure as returned by GetSystemInfo */ - uint16_t processor_architecture; - uint16_t processor_level; /* x86: 5 = 586, 6 = 686, ... */ - /* ARM: 6 = ARMv6, 7 = ARMv7 ... */ - uint16_t processor_revision; /* x86: 0xMMSS, where MM=model, - * SS=stepping */ - /* ARM: 0 */ - - uint8_t number_of_processors; - uint8_t product_type; /* Windows: VER_NT_* from WinNT.h */ - - /* The next 5 fields are from the OSVERSIONINFO structure as returned - * by GetVersionEx */ - uint32_t major_version; - uint32_t minor_version; - uint32_t build_number; - uint32_t platform_id; - MDRVA csd_version_rva; /* MDString further identifying the - * host OS. - * Windows: name of the installed OS - * service pack. - * Mac OS X: the Apple OS build number - * (sw_vers -buildVersion). - * Linux: uname -srvmo */ - - uint16_t suite_mask; /* Windows: VER_SUITE_* from WinNT.h */ - uint16_t reserved2; - - MDCPUInformation cpu; -} MDRawSystemInfo; /* MINIDUMP_SYSTEM_INFO */ - -/* For (MDRawSystemInfo).processor_architecture: */ -typedef enum { - MD_CPU_ARCHITECTURE_X86 = 0, /* PROCESSOR_ARCHITECTURE_INTEL */ - MD_CPU_ARCHITECTURE_MIPS = 1, /* PROCESSOR_ARCHITECTURE_MIPS */ - MD_CPU_ARCHITECTURE_ALPHA = 2, /* PROCESSOR_ARCHITECTURE_ALPHA */ - MD_CPU_ARCHITECTURE_PPC = 3, /* PROCESSOR_ARCHITECTURE_PPC */ - MD_CPU_ARCHITECTURE_SHX = 4, /* PROCESSOR_ARCHITECTURE_SHX - * (Super-H) */ - MD_CPU_ARCHITECTURE_ARM = 5, /* PROCESSOR_ARCHITECTURE_ARM */ - MD_CPU_ARCHITECTURE_IA64 = 6, /* PROCESSOR_ARCHITECTURE_IA64 */ - MD_CPU_ARCHITECTURE_ALPHA64 = 7, /* PROCESSOR_ARCHITECTURE_ALPHA64 */ - MD_CPU_ARCHITECTURE_MSIL = 8, /* PROCESSOR_ARCHITECTURE_MSIL - * (Microsoft Intermediate Language) */ - MD_CPU_ARCHITECTURE_AMD64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */ - MD_CPU_ARCHITECTURE_X86_WIN64 = 10, - /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */ - MD_CPU_ARCHITECTURE_SPARC = 0x8001, /* Breakpad-defined value for SPARC */ - MD_CPU_ARCHITECTURE_PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */ - MD_CPU_ARCHITECTURE_ARM64 = 0x8003, /* Breakpad-defined value for ARM64 */ - MD_CPU_ARCHITECTURE_MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */ - MD_CPU_ARCHITECTURE_UNKNOWN = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */ -} MDCPUArchitecture; - -/* For (MDRawSystemInfo).platform_id: */ -typedef enum { - MD_OS_WIN32S = 0, /* VER_PLATFORM_WIN32s (Windows 3.1) */ - MD_OS_WIN32_WINDOWS = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */ - MD_OS_WIN32_NT = 2, /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */ - MD_OS_WIN32_CE = 3, /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH - * (Windows CE, Windows Mobile, "Handheld") */ - - /* The following values are Breakpad-defined. */ - MD_OS_UNIX = 0x8000, /* Generic Unix-ish */ - MD_OS_MAC_OS_X = 0x8101, /* Mac OS X/Darwin */ - MD_OS_IOS = 0x8102, /* iOS */ - MD_OS_LINUX = 0x8201, /* Linux */ - MD_OS_SOLARIS = 0x8202, /* Solaris */ - MD_OS_ANDROID = 0x8203, /* Android */ - MD_OS_PS3 = 0x8204, /* PS3 */ - MD_OS_NACL = 0x8205 /* Native Client (NaCl) */ -} MDOSPlatform; - -typedef struct { - uint16_t year; - uint16_t month; - uint16_t day_of_week; - uint16_t day; - uint16_t hour; - uint16_t minute; - uint16_t second; - uint16_t milliseconds; -} MDSystemTime; /* SYSTEMTIME */ - -typedef struct { - /* Required field. The bias is the difference, in minutes, between - * Coordinated Universal Time (UTC) and local time. - * Formula: UTC = local time + bias */ - int32_t bias; - /* A description for standard time. For example, "EST" could indicate Eastern - * Standard Time. In practice this contains the full time zone names. This - * string can be empty. */ - uint16_t standard_name[32]; /* UTF-16-encoded, 0-terminated */ - /* A MDSystemTime structure that contains a date and local time when the - * transition from daylight saving time to standard time occurs on this - * operating system. If the time zone does not support daylight saving time, - * the month member in the MDSystemTime structure is zero. */ - MDSystemTime standard_date; - /* The bias value to be used during local time translations that occur during - * standard time. */ - int32_t standard_bias; - /* A description for daylight saving time. For example, "PDT" could indicate - * Pacific Daylight Time. In practice this contains the full time zone names. - * This string can be empty. */ - uint16_t daylight_name[32]; /* UTF-16-encoded, 0-terminated */ - /* A MDSystemTime structure that contains a date and local time when the - * transition from standard time to daylight saving time occurs on this - * operating system. If the time zone does not support daylight saving time, - * the month member in the MDSystemTime structure is zero.*/ - MDSystemTime daylight_date; - /* The bias value to be used during local time translations that occur during - * daylight saving time. */ - int32_t daylight_bias; -} MDTimeZoneInformation; /* TIME_ZONE_INFORMATION */ - -/* MAX_PATH from windef.h */ -#define MD_MAX_PATH 260 - -/* For MDXStateConfigFeatureMscInfo.features */ -typedef struct { - uint32_t offset; - uint32_t size; -} MDXStateFeature; - -/* For MDXStateConfigFeatureMscInfo.enabled_features from winnt.h */ -typedef enum { - MD_XSTATE_LEGACY_FLOATING_POINT = 0, /* XSTATE_LEGACY_FLOATING_POINT */ - MD_XSTATE_LEGACY_SSE = 1, /* XSTATE_LEGACY_SSE */ - MD_XSTATE_GSSE = 2, /* XSTATE_GSSE */ - MD_XSTATE_AVX = MD_XSTATE_GSSE, /* XSTATE_AVX */ - MD_XSTATE_MPX_BNDREGS = 3, /* XSTATE_MPX_BNDREGS */ - MD_XSTATE_MPX_BNDCSR = 4, /* XSTATE_MPX_BNDCSR */ - MD_XSTATE_AVX512_KMASK = 5, /* XSTATE_AVX512_KMASK */ - MD_XSTATE_AVX512_ZMM_H = 6, /* XSTATE_AVX512_ZMM_H */ - MD_XSTATE_AVX512_ZMM = 7, /* XSTATE_AVX512_ZMM */ - MD_XSTATE_IPT = 8, /* XSTATE_IPT */ - MD_XSTATE_LWP = 62 /* XSTATE_LWP */ -} MDXStateFeatureFlag; - -/* MAXIMUM_XSTATE_FEATURES from winnt.h */ -#define MD_MAXIMUM_XSTATE_FEATURES 64 - -/* For MDRawMiscInfo.xstate_data */ -typedef struct { - uint32_t size_of_info; - uint32_t context_size; - /* An entry in the features array is valid only if the corresponding bit in - * the enabled_features flag is set. */ - uint64_t enabled_features; - MDXStateFeature features[MD_MAXIMUM_XSTATE_FEATURES]; -} MDXStateConfigFeatureMscInfo; - - -/* The miscellaneous information stream contains a variety - * of small pieces of information. A member is valid if - * it's within the available size and its corresponding - * bit is set. */ -typedef struct { - uint32_t size_of_info; /* Length of entire MDRawMiscInfo structure. */ - uint32_t flags1; - - /* The next field is only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROCESS_ID. */ - uint32_t process_id; - - /* The next 3 fields are only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */ - uint32_t process_create_time; /* time_t process started */ - uint32_t process_user_time; /* seconds of user CPU time */ - uint32_t process_kernel_time; /* seconds of kernel CPU time */ - - /* The following fields are not present in MINIDUMP_MISC_INFO but are - * in MINIDUMP_MISC_INFO_2. When this struct is populated, these values - * may not be set. Use flags1 and size_of_info to determine whether these - * values are present. These are only valid when flags1 contains - * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */ - uint32_t processor_max_mhz; - uint32_t processor_current_mhz; - uint32_t processor_mhz_limit; - uint32_t processor_max_idle_state; - uint32_t processor_current_idle_state; - - /* The following fields are not present in MINIDUMP_MISC_INFO_2 but are - * in MINIDUMP_MISC_INFO_3. When this struct is populated, these values - * may not be set. Use flags1 and size_of_info to determine whether these - * values are present. */ - - /* The following field is only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY. */ - uint32_t process_integrity_level; - - /* The following field is only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS. */ - uint32_t process_execute_flags; - - /* The following field is only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROTECTED_PROCESS. */ - uint32_t protected_process; - - /* The following 2 fields are only valid if flags1 contains - * MD_MISCINFO_FLAGS1_TIMEZONE. */ - uint32_t time_zone_id; - MDTimeZoneInformation time_zone; - - /* The following fields are not present in MINIDUMP_MISC_INFO_3 but are - * in MINIDUMP_MISC_INFO_4. When this struct is populated, these values - * may not be set. Use flags1 and size_of_info to determine whether these - * values are present. */ - - /* The following 2 fields are only valid if flags1 contains - * MD_MISCINFO_FLAGS1_BUILDSTRING. */ - uint16_t build_string[MD_MAX_PATH]; /* UTF-16-encoded, 0-terminated */ - uint16_t dbg_bld_str[40]; /* UTF-16-encoded, 0-terminated */ - - /* The following fields are not present in MINIDUMP_MISC_INFO_4 but are - * in MINIDUMP_MISC_INFO_5. When this struct is populated, these values - * may not be set. Use flags1 and size_of_info to determine whether these - * values are present. */ - - /* The following field has its own flags for establishing the validity of - * the structure's contents.*/ - MDXStateConfigFeatureMscInfo xstate_data; - - /* The following field is only valid if flags1 contains - * MD_MISCINFO_FLAGS1_PROCESS_COOKIE. */ - uint32_t process_cookie; -} MDRawMiscInfo; /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2, - * MINIDUMP_MISC_INFO_3, MINIDUMP_MISC_INFO_4, - * MINIDUMP_MISC_INFO_5, MINIDUMP_MISC_INFO_N */ - -static const size_t MD_MISCINFO_SIZE = - offsetof(MDRawMiscInfo, processor_max_mhz); -static const size_t MD_MISCINFO2_SIZE = - offsetof(MDRawMiscInfo, process_integrity_level); -static const size_t MD_MISCINFO3_SIZE = - offsetof(MDRawMiscInfo, build_string[0]); -static const size_t MD_MISCINFO4_SIZE = - offsetof(MDRawMiscInfo, xstate_data); -/* Version 5 of the MDRawMiscInfo structure is not a multiple of 8 in size and - * yet it contains some 8-bytes sized fields. This causes many compilers to - * round the structure size up to a multiple of 8 by adding padding at the end. - * The following hack is thus required for matching the proper on-disk size. */ -static const size_t MD_MISCINFO5_SIZE = - offsetof(MDRawMiscInfo, process_cookie) + sizeof(uint32_t); - -/* For (MDRawMiscInfo).flags1. These values indicate which fields in the - * MDRawMiscInfoStructure are valid. */ -typedef enum { - MD_MISCINFO_FLAGS1_PROCESS_ID = 0x00000001, - /* MINIDUMP_MISC1_PROCESS_ID */ - MD_MISCINFO_FLAGS1_PROCESS_TIMES = 0x00000002, - /* MINIDUMP_MISC1_PROCESS_TIMES */ - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO = 0x00000004, - /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */ - MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY = 0x00000010, - /* MINIDUMP_MISC3_PROCESS_INTEGRITY */ - MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS = 0x00000020, - /* MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS */ - MD_MISCINFO_FLAGS1_TIMEZONE = 0x00000040, - /* MINIDUMP_MISC3_TIMEZONE */ - MD_MISCINFO_FLAGS1_PROTECTED_PROCESS = 0x00000080, - /* MINIDUMP_MISC3_PROTECTED_PROCESS */ - MD_MISCINFO_FLAGS1_BUILDSTRING = 0x00000100, - /* MINIDUMP_MISC4_BUILDSTRING */ - MD_MISCINFO_FLAGS1_PROCESS_COOKIE = 0x00000200, - /* MINIDUMP_MISC5_PROCESS_COOKIE */ -} MDMiscInfoFlags1; - -/* - * Around DbgHelp version 6.0, the style of new LIST structures changed - * from including an array of length 1 at the end of the struct to - * represent the variable-length data to including explicit - * "size of header", "size of entry" and "number of entries" fields - * in the header, presumably to allow backwards-compatibly-extending - * the structures in the future. The actual list entries follow the - * header data directly in this case. - */ - -typedef struct { - uint32_t size_of_header; /* sizeof(MDRawMemoryInfoList) */ - uint32_t size_of_entry; /* sizeof(MDRawMemoryInfo) */ - uint64_t number_of_entries; -} MDRawMemoryInfoList; /* MINIDUMP_MEMORY_INFO_LIST */ - -typedef struct { - uint64_t base_address; /* Base address of a region of pages */ - uint64_t allocation_base; /* Base address of a range of pages - * within this region. */ - uint32_t allocation_protection; /* Memory protection when this region - * was originally allocated: - * MDMemoryProtection */ - uint32_t __alignment1; - uint64_t region_size; - uint32_t state; /* MDMemoryState */ - uint32_t protection; /* MDMemoryProtection */ - uint32_t type; /* MDMemoryType */ - uint32_t __alignment2; -} MDRawMemoryInfo; /* MINIDUMP_MEMORY_INFO */ - -/* For (MDRawMemoryInfo).state */ -typedef enum { - MD_MEMORY_STATE_COMMIT = 0x1000, /* physical storage has been allocated */ - MD_MEMORY_STATE_RESERVE = 0x2000, /* reserved, but no physical storage */ - MD_MEMORY_STATE_FREE = 0x10000 /* available to be allocated */ -} MDMemoryState; - -/* For (MDRawMemoryInfo).allocation_protection and .protection */ -typedef enum { - MD_MEMORY_PROTECT_NOACCESS = 0x01, /* PAGE_NOACCESS */ - MD_MEMORY_PROTECT_READONLY = 0x02, /* PAGE_READONLY */ - MD_MEMORY_PROTECT_READWRITE = 0x04, /* PAGE_READWRITE */ - MD_MEMORY_PROTECT_WRITECOPY = 0x08, /* PAGE_WRITECOPY */ - MD_MEMORY_PROTECT_EXECUTE = 0x10, /* PAGE_EXECUTE */ - MD_MEMORY_PROTECT_EXECUTE_READ = 0x20, /* PAGE_EXECUTE_READ */ - MD_MEMORY_PROTECT_EXECUTE_READWRITE = 0x40, /* PAGE_EXECUTE_READWRITE */ - MD_MEMORY_PROTECT_EXECUTE_WRITECOPY = 0x80, /* PAGE_EXECUTE_WRITECOPY */ - /* These options can be combined with the previous flags. */ - MD_MEMORY_PROTECT_GUARD = 0x100, /* PAGE_GUARD */ - MD_MEMORY_PROTECT_NOCACHE = 0x200, /* PAGE_NOCACHE */ - MD_MEMORY_PROTECT_WRITECOMBINE = 0x400, /* PAGE_WRITECOMBINE */ -} MDMemoryProtection; - -/* Used to mask the mutually exclusive options from the combinable flags. */ -const uint32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF; - -/* For (MDRawMemoryInfo).type */ -typedef enum { - MD_MEMORY_TYPE_PRIVATE = 0x20000, /* not shared by other processes */ - MD_MEMORY_TYPE_MAPPED = 0x40000, /* mapped into the view of a section */ - MD_MEMORY_TYPE_IMAGE = 0x1000000 /* mapped into the view of an image */ -} MDMemoryType; - -/* - * Breakpad extension types - */ - - -typedef struct { - /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating - * which of the other fields in the structure are valid. */ - uint32_t validity; - - /* Thread ID of the handler thread. dump_thread_id should correspond to - * the thread_id of an MDRawThread in the minidump's MDRawThreadList if - * a dedicated thread in that list was used to produce the minidump. If - * the MDRawThreadList does not contain a dedicated thread used to produce - * the minidump, this field should be set to 0 and the validity field - * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */ - uint32_t dump_thread_id; - - /* Thread ID of the thread that requested the minidump be produced. As - * with dump_thread_id, requesting_thread_id should correspond to the - * thread_id of an MDRawThread in the minidump's MDRawThreadList. For - * minidumps produced as a result of an exception, requesting_thread_id - * will be the same as the MDRawExceptionStream's thread_id field. For - * minidumps produced "manually" at the program's request, - * requesting_thread_id will indicate which thread caused the dump to be - * written. If the minidump was produced at the request of something - * other than a thread in the MDRawThreadList, this field should be set - * to 0 and the validity field must not contain - * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */ - uint32_t requesting_thread_id; -} MDRawBreakpadInfo; - -/* For (MDRawBreakpadInfo).validity: */ -typedef enum { - /* When set, the dump_thread_id field is valid. */ - MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID = 1 << 0, - - /* When set, the requesting_thread_id field is valid. */ - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID = 1 << 1 -} MDBreakpadInfoValidity; - -typedef struct { - /* expression, function, and file are 0-terminated UTF-16 strings. They - * may be truncated if necessary, but should always be 0-terminated when - * written to a file. - * Fixed-length strings are used because MiniDumpWriteDump doesn't offer - * a way for user streams to point to arbitrary RVAs for strings. */ - uint16_t expression[128]; /* Assertion that failed... */ - uint16_t function[128]; /* ...within this function... */ - uint16_t file[128]; /* ...in this file... */ - uint32_t line; /* ...at this line. */ - uint32_t type; -} MDRawAssertionInfo; - -/* For (MDRawAssertionInfo).type: */ -typedef enum { - MD_ASSERTION_INFO_TYPE_UNKNOWN = 0, - - /* Used for assertions that would be raised by the MSVC CRT but are - * directed to an invalid parameter handler instead. */ - MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER, - - /* Used for assertions that would be raised by the MSVC CRT but are - * directed to a pure virtual call handler instead. */ - MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL -} MDAssertionInfoData; - -/* These structs are used to store the DSO debug data in Linux minidumps, - * which is necessary for converting minidumps to usable coredumps. - * Because of a historical accident, several fields are variably encoded - * according to client word size, so tools potentially need to support both. */ - -typedef struct { - uint32_t addr; - MDRVA name; - uint32_t ld; -} MDRawLinkMap32; - -typedef struct { - uint32_t version; - MDRVA map; /* array of MDRawLinkMap32 */ - uint32_t dso_count; - uint32_t brk; - uint32_t ldbase; - uint32_t dynamic; -} MDRawDebug32; - -typedef struct { - uint64_t addr; - MDRVA name; - uint64_t ld; -} MDRawLinkMap64; - -typedef struct { - uint32_t version; - MDRVA map; /* array of MDRawLinkMap64 */ - uint32_t dso_count; - uint64_t brk; - uint64_t ldbase; - uint64_t dynamic; -} MDRawDebug64; - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif /* _MSC_VER */ - - -#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ */ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_size.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_size.h deleted file mode 100644 index fae57923c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/common/minidump_size.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -// minidump_size.h: Provides a C++ template for programmatic access to -// the sizes of various types defined in minidump_format.h. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ -#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ - -#include - -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -template -class minidump_size { - public: - static size_t size() { return sizeof(T); } -}; - -// Explicit specializations for variable-length types. The size returned -// for these should be the size for an object without its variable-length -// section. - -template<> -class minidump_size { - public: - static size_t size() { return MDString_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDRawThreadList_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDCVInfoPDB20_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDCVInfoPDB70_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDCVInfoELF_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDImageDebugMisc_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDRawModuleList_minsize; } -}; - -template<> -class minidump_size { - public: - static size_t size() { return MDRawMemoryList_minsize; } -}; - -// Explicit specialization for MDRawModule, for which sizeof may include -// tail-padding on some architectures but not others. - -template<> -class minidump_size { - public: - static size_t size() { return MD_MODULE_SIZE; } -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/basic_source_line_resolver.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/basic_source_line_resolver.h deleted file mode 100644 index 6bb6d8639..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/basic_source_line_resolver.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// basic_source_line_resolver.h: BasicSourceLineResolver is derived from -// SourceLineResolverBase, and is a concrete implementation of -// SourceLineResolverInterface, using address map files produced by a -// compatible writer, e.g. PDBSourceLineWriter. -// -// see "processor/source_line_resolver_base.h" -// and "source_line_resolver_interface.h" for more documentation. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/source_line_resolver_base.h" - -namespace google_breakpad { - -using std::map; - -class BasicSourceLineResolver : public SourceLineResolverBase { - public: - BasicSourceLineResolver(); - virtual ~BasicSourceLineResolver() { } - - using SourceLineResolverBase::LoadModule; - using SourceLineResolverBase::LoadModuleUsingMapBuffer; - using SourceLineResolverBase::LoadModuleUsingMemoryBuffer; - using SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule; - using SourceLineResolverBase::UnloadModule; - using SourceLineResolverBase::HasModule; - using SourceLineResolverBase::IsModuleCorrupt; - using SourceLineResolverBase::FillSourceLineInfo; - using SourceLineResolverBase::FindWindowsFrameInfo; - using SourceLineResolverBase::FindCFIFrameInfo; - - private: - // friend declarations: - friend class BasicModuleFactory; - friend class ModuleComparer; - friend class ModuleSerializer; - template friend class SimpleSerializer; - - // Function derives from SourceLineResolverBase::Function. - struct Function; - // Module implements SourceLineResolverBase::Module interface. - class Module; - - // Disallow unwanted copy ctor and assignment operator - BasicSourceLineResolver(const BasicSourceLineResolver&); - void operator=(const BasicSourceLineResolver&); -}; - -// Helper class, containing useful methods for parsing of Breakpad symbol files. -class SymbolParseHelper { - public: - // Parses a |file_line| declaration. Returns true on success. - // Format: FILE . - // Notice, that this method modifies the input |file_line| which is why it - // can't be const. On success, , and are stored in |*index|, - // and |*filename|. No allocation is done, |*filename| simply points inside - // |file_line|. - static bool ParseFile(char *file_line, // in - long *index, // out - char **filename); // out - - // Parses a |function_line| declaration. Returns true on success. - // Format: FUNC
. - // Notice, that this method modifies the input |function_line| which is why it - // can't be const. On success,
, , , and - // are stored in |*address|, |*size|, |*stack_param_size|, and |*name|. - // No allocation is done, |*name| simply points inside |function_line|. - static bool ParseFunction(char *function_line, // in - uint64_t *address, // out - uint64_t *size, // out - long *stack_param_size, // out - char **name); // out - - // Parses a |line| declaration. Returns true on success. - // Format:
- // Notice, that this method modifies the input |function_line| which is why - // it can't be const. On success,
, , , and - // are stored in |*address|, |*size|, |*line_number|, and - // |*source_file|. - static bool ParseLine(char *line_line, // in - uint64_t *address, // out - uint64_t *size, // out - long *line_number, // out - long *source_file); // out - - // Parses a |public_line| declaration. Returns true on success. - // Format: PUBLIC
- // Notice, that this method modifies the input |function_line| which is why - // it can't be const. On success,
, , - // are stored in |*address|, |*stack_param_size|, and |*name|. - // No allocation is done, |*name| simply points inside |public_line|. - static bool ParsePublicSymbol(char *public_line, // in - uint64_t *address, // out - long *stack_param_size, // out - char **name); // out - - private: - // Used for success checks after strtoull and strtol. - static bool IsValidAfterNumber(char *after_number); - - // Only allow static methods. - SymbolParseHelper(); - SymbolParseHelper(const SymbolParseHelper&); - void operator=(const SymbolParseHelper&); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/call_stack.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/call_stack.h deleted file mode 100644 index c59142315..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/call_stack.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// call_stack.h: A call stack comprised of stack frames. -// -// This class manages a vector of stack frames. It is used instead of -// exposing the vector directly to allow the CallStack to own StackFrame -// pointers without having to publicly export the linked_ptr class. A -// CallStack must be composed of pointers instead of objects to allow for -// CPU-specific StackFrame subclasses. -// -// By convention, the stack frame at index 0 is the innermost callee frame, -// and the frame at the highest index in a call stack is the outermost -// caller. CallStack only allows stacks to be built by pushing frames, -// beginning with the innermost callee frame. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__ - -#include -#include - -namespace google_breakpad { - -using std::vector; - -struct StackFrame; -template class linked_ptr; - -class CallStack { - public: - CallStack() { Clear(); } - ~CallStack(); - - // Resets the CallStack to its initial empty state - void Clear(); - - const vector* frames() const { return &frames_; } - - // Set the TID associated with this call stack. - void set_tid(uint32_t tid) { tid_ = tid; } - - uint32_t tid() const { return tid_; } - - private: - // Stackwalker is responsible for building the frames_ vector. - friend class Stackwalker; - - // Storage for pushed frames. - vector frames_; - - // The TID associated with this call stack. Default to 0 if it's not - // available. - uint32_t tid_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCSSOR_CALL_STACK_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_module.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_module.h deleted file mode 100644 index b139907c4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_module.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// code_module.h: Carries information about code modules that are loaded -// into a process. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__ - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -class CodeModule { - public: - virtual ~CodeModule() {} - - // The base address of this code module as it was loaded by the process. - // (uint64_t)-1 on error. - virtual uint64_t base_address() const = 0; - - // The size of the code module. 0 on error. - virtual uint64_t size() const = 0; - - // The path or file name that the code module was loaded from. Empty on - // error. - virtual string code_file() const = 0; - - // An identifying string used to discriminate between multiple versions and - // builds of the same code module. This may contain a uuid, timestamp, - // version number, or any combination of this or other information, in an - // implementation-defined format. Empty on error. - virtual string code_identifier() const = 0; - - // The filename containing debugging information associated with the code - // module. If debugging information is stored in a file separate from the - // code module itself (as is the case when .pdb or .dSYM files are used), - // this will be different from code_file. If debugging information is - // stored in the code module itself (possibly prior to stripping), this - // will be the same as code_file. Empty on error. - virtual string debug_file() const = 0; - - // An identifying string similar to code_identifier, but identifies a - // specific version and build of the associated debug file. This may be - // the same as code_identifier when the debug_file and code_file are - // identical or when the same identifier is used to identify distinct - // debug and code files. - virtual string debug_identifier() const = 0; - - // A human-readable representation of the code module's version. Empty on - // error. - virtual string version() const = 0; - - // Creates a new copy of this CodeModule object, which the caller takes - // ownership of. The new CodeModule may be of a different concrete class - // than the CodeModule being copied, but will behave identically to the - // copied CodeModule as far as the CodeModule interface is concerned. - virtual CodeModule* Copy() const = 0; - - // Getter and setter for shrink_down_delta. This is used when the address - // range for a module is shrunk down due to address range conflicts with - // other modules. The base_address and size fields are not updated and they - // should always reflect the original values (reported in the minidump). - virtual uint64_t shrink_down_delta() const = 0; - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta) = 0; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_modules.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_modules.h deleted file mode 100644 index 509137cbb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/code_modules.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// code_modules.h: Contains all of the CodeModule objects that were loaded -// into a single process. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__ - -#include - -#include - -#include "google_breakpad/common/breakpad_types.h" -#include "processor/linked_ptr.h" - -namespace google_breakpad { - -class CodeModule; - -class CodeModules { - public: - virtual ~CodeModules() {} - - // The number of contained CodeModule objects. - virtual unsigned int module_count() const = 0; - - // Random access to modules. Returns the module whose code is present - // at the address indicated by |address|. If no module is present at this - // address, returns NULL. Ownership of the returned CodeModule is retained - // by the CodeModules object; pointers returned by this method are valid for - // comparison with pointers returned by the other Get methods. - virtual const CodeModule* GetModuleForAddress(uint64_t address) const = 0; - - // Returns the module corresponding to the main executable. If there is - // no main executable, returns NULL. Ownership of the returned CodeModule - // is retained by the CodeModules object; pointers returned by this method - // are valid for comparison with pointers returned by the other Get - // methods. - virtual const CodeModule* GetMainModule() const = 0; - - // Sequential access to modules. A sequence number of 0 corresponds to the - // module residing lowest in memory. If the sequence number is out of - // range, returns NULL. Ownership of the returned CodeModule is retained - // by the CodeModules object; pointers returned by this method are valid for - // comparison with pointers returned by the other Get methods. - virtual const CodeModule* GetModuleAtSequence( - unsigned int sequence) const = 0; - - // Sequential access to modules. This is similar to GetModuleAtSequence, - // except no ordering requirement is enforced. A CodeModules implementation - // may return CodeModule objects from GetModuleAtIndex in any order it - // wishes, provided that the order remain the same throughout the life of - // the CodeModules object. Typically, GetModuleAtIndex would be used by - // a caller to enumerate all CodeModule objects quickly when the enumeration - // does not require any ordering. If the index argument is out of range, - // returns NULL. Ownership of the returned CodeModule is retained by - // the CodeModules object; pointers returned by this method are valid for - // comparison with pointers returned by the other Get methods. - virtual const CodeModule* GetModuleAtIndex(unsigned int index) const = 0; - - // Creates a new copy of this CodeModules object, which the caller takes - // ownership of. The new object will also contain copies of the existing - // object's child CodeModule objects. The new CodeModules object may be of - // a different concrete class than the object being copied, but will behave - // identically to the copied object as far as the CodeModules and CodeModule - // interfaces are concerned, except that the order that GetModuleAtIndex - // returns objects in may differ between a copy and the original CodeModules - // object. - virtual const CodeModules* Copy() const = 0; - - // Returns a vector of all modules which address ranges needed to be shrunk - // down due to address range conflicts with other modules. - virtual std::vector > - GetShrunkRangeModules() const = 0; - - // Returns true, if module address range shrink is enabled. - virtual bool IsModuleShrinkEnabled() const = 0; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_context.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_context.h deleted file mode 100644 index df80bf7ef..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_context.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_context.h: A (mini/micro) dump CPU-specific context. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__ - -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/dump_object.h" - -namespace google_breakpad { - -// DumpContext carries a CPU-specific MDRawContext structure, which contains CPU -// context such as register states. -class DumpContext : public DumpObject { - public: - virtual ~DumpContext(); - - // Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC - // identifying the CPU type that the context was collected from. The - // returned value will identify the CPU only, and will have any other - // MD_CONTEXT_* bits masked out. Returns 0 on failure. - uint32_t GetContextCPU() const; - - // Return the raw value of |context_flags_| - uint32_t GetContextFlags() const; - - // Returns raw CPU-specific context data for the named CPU type. If the - // context data does not match the CPU type or does not exist, returns NULL. - const MDRawContextAMD64* GetContextAMD64() const; - const MDRawContextARM* GetContextARM() const; - const MDRawContextARM64* GetContextARM64() const; - const MDRawContextMIPS* GetContextMIPS() const; - const MDRawContextPPC* GetContextPPC() const; - const MDRawContextPPC64* GetContextPPC64() const; - const MDRawContextSPARC* GetContextSPARC() const; - const MDRawContextX86* GetContextX86() const; - - // A convenience method to get the instruction pointer out of the - // MDRawContext, since it varies per-CPU architecture. - bool GetInstructionPointer(uint64_t* ip) const; - - // Similar to the GetInstructionPointer method, this method gets the stack - // pointer for all CPU architectures. - bool GetStackPointer(uint64_t* sp) const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - protected: - DumpContext(); - - // Sets row CPU-specific context data for the names CPU type. - void SetContextFlags(uint32_t context_flags); - void SetContextX86(MDRawContextX86* x86); - void SetContextPPC(MDRawContextPPC* ppc); - void SetContextPPC64(MDRawContextPPC64* ppc64); - void SetContextAMD64(MDRawContextAMD64* amd64); - void SetContextSPARC(MDRawContextSPARC* ctx_sparc); - void SetContextARM(MDRawContextARM* arm); - void SetContextARM64(MDRawContextARM64* arm64); - void SetContextMIPS(MDRawContextMIPS* ctx_mips); - - // Free the CPU-specific context structure. - void FreeContext(); - - private: - // The CPU-specific context structure. - union { - MDRawContextBase* base; - MDRawContextX86* x86; - MDRawContextPPC* ppc; - MDRawContextPPC64* ppc64; - MDRawContextAMD64* amd64; - // on Solaris SPARC, sparc is defined as a numeric constant, - // so variables can NOT be named as sparc - MDRawContextSPARC* ctx_sparc; - MDRawContextARM* arm; - MDRawContextARM64* arm64; - MDRawContextMIPS* ctx_mips; - } context_; - - // Store this separately because of the weirdo AMD64 context - uint32_t context_flags_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_DUMP_CONTEXT_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_object.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_object.h deleted file mode 100644 index 112f687f4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/dump_object.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_object.h: A base class for all mini/micro dump object. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__ - -namespace google_breakpad { - -// DumpObject is the base of various mini/micro dump's objects. -class DumpObject { - public: - DumpObject(); - - bool valid() const { return valid_; } - - protected: - // DumpObjects are not valid when created. When a subclass populates its own - // fields, it can set valid_ to true. Accessors and mutators may wish to - // consider or alter the valid_ state as they interact with objects. - bool valid_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_DUMP_OBJECT_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/exploitability.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/exploitability.h deleted file mode 100644 index 014413c94..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/exploitability.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_engine.h: Generic exploitability engine. -// -// The Exploitability class is an abstract base class providing common -// generic methods that apply to exploitability engines for specific platforms. -// Specific implementations will extend this class by providing run -// methods to fill in the exploitability_ enumeration of the ProcessState -// for a crash. -// -// Author: Cris Neckar - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/process_state.h" - -namespace google_breakpad { - -class Exploitability { - public: - virtual ~Exploitability() {} - - static Exploitability *ExploitabilityForPlatform(Minidump *dump, - ProcessState *process_state); - - // The boolean parameter signals whether the exploitability engine is - // enabled to call out to objdump for disassembly. This is disabled by - // default. It is used to check the identity of the instruction that - // caused the program to crash. This should not be enabled if there are - // portability concerns. - static Exploitability *ExploitabilityForPlatform(Minidump *dump, - ProcessState *process_state, - bool enable_objdump); - - ExploitabilityRating CheckExploitability(); - bool AddressIsAscii(uint64_t); - - protected: - Exploitability(Minidump *dump, - ProcessState *process_state); - - Minidump *dump_; - ProcessState *process_state_; - SystemInfo *system_info_; - - private: - virtual ExploitabilityRating CheckPlatformExploitability() = 0; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/fast_source_line_resolver.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/fast_source_line_resolver.h deleted file mode 100644 index fdf910776..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/fast_source_line_resolver.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// fast_source_line_resolver.h: FastSourceLineResolver is derived from -// SourceLineResolverBase, and is a concrete implementation of -// SourceLineResolverInterface. -// -// FastSourceLineResolver is a sibling class of BasicSourceLineResolver. The -// difference is FastSourceLineResolver loads a serialized memory chunk of data -// which can be used directly a Module without parsing or copying of underlying -// data. Therefore loading a symbol in FastSourceLineResolver is much faster -// and more memory-efficient than BasicSourceLineResolver. -// -// See "source_line_resolver_base.h" and -// "google_breakpad/source_line_resolver_interface.h" for more reference. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__ - -#include -#include - -#include "google_breakpad/processor/source_line_resolver_base.h" - -namespace google_breakpad { - -using std::map; - -class FastSourceLineResolver : public SourceLineResolverBase { - public: - FastSourceLineResolver(); - virtual ~FastSourceLineResolver() { } - - using SourceLineResolverBase::FillSourceLineInfo; - using SourceLineResolverBase::FindCFIFrameInfo; - using SourceLineResolverBase::FindWindowsFrameInfo; - using SourceLineResolverBase::HasModule; - using SourceLineResolverBase::IsModuleCorrupt; - using SourceLineResolverBase::LoadModule; - using SourceLineResolverBase::LoadModuleUsingMapBuffer; - using SourceLineResolverBase::LoadModuleUsingMemoryBuffer; - using SourceLineResolverBase::UnloadModule; - - private: - // Friend declarations. - friend class ModuleComparer; - friend class ModuleSerializer; - friend class FastModuleFactory; - - // Nested types that will derive from corresponding nested types defined in - // SourceLineResolverBase. - struct Line; - struct Function; - struct PublicSymbol; - class Module; - - // Deserialize raw memory data to construct a WindowsFrameInfo object. - static WindowsFrameInfo CopyWFI(const char *raw_memory); - - // FastSourceLineResolver requires the memory buffer stays alive during the - // lifetime of a corresponding module, therefore it needs to redefine this - // virtual method. - virtual bool ShouldDeleteMemoryBufferAfterLoadModule(); - - // Disallow unwanted copy ctor and assignment operator - FastSourceLineResolver(const FastSourceLineResolver&); - void operator=(const FastSourceLineResolver&); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/memory_region.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/memory_region.h deleted file mode 100644 index 30f88df49..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/memory_region.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// memory_region.h: Access to memory regions. -// -// A MemoryRegion provides virtual access to a range of memory. It is an -// abstraction allowing the actual source of memory to be independent of -// methods which need to access a virtual memory space. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__ - - -#include "google_breakpad/common/breakpad_types.h" - - -namespace google_breakpad { - - -class MemoryRegion { - public: - virtual ~MemoryRegion() {} - - // The base address of this memory region. - virtual uint64_t GetBase() const = 0; - - // The size of this memory region. - virtual uint32_t GetSize() const = 0; - - // Access to data of various sizes within the memory region. address - // is a pointer to read, and it must lie within the memory region as - // defined by its base address and size. The location pointed to by - // value is set to the value at address. Byte-swapping is performed - // if necessary so that the value is appropriate for the running - // program. Returns true on success. Fails and returns false if address - // is out of the region's bounds (after considering the width of value), - // or for other types of errors. - virtual bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const = 0; - virtual bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const = 0; - virtual bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const = 0; - virtual bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const = 0; - - // Print a human-readable representation of the object to stdout. - virtual void Print() const = 0; -}; - - -} // namespace google_breakpad - - -#endif // GOOGLE_BREAKPAD_PROCESSOR_MEMORY_REGION_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump.h deleted file mode 100644 index 0e2cb7494..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// microdump.h: A microdump reader. Microdump is a minified variant of a -// minidump (see minidump.h for documentation) which contains the minimum -// amount of information required to get a stack trace for the crashing thread. -// The information contained in a microdump is: -// - the crashing thread stack -// - system information (os type / version) -// - cpu context (state of the registers) -// - list of mmaps - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__ - -#include -#include - -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/dump_context.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/basic_code_modules.h" - -namespace google_breakpad { - -// MicrodumpModuleList contains all of the loaded code modules for a process -// in the form of MicrodumpModules. It maintains a vector of these modules -// and provides access to a code module corresponding to a specific address. -class MicrodumpModules : public BasicCodeModules { - public: - // Takes over ownership of |module|. - void Add(const CodeModule* module); - - // Enables/disables module address range shrink. - void SetEnableModuleShrink(bool is_enabled); -}; - -// MicrodumpContext carries a CPU-specific context. -// See dump_context.h for documentation. -class MicrodumpContext : public DumpContext { - public: - virtual void SetContextARM(MDRawContextARM* arm); - virtual void SetContextARM64(MDRawContextARM64* arm64); - virtual void SetContextX86(MDRawContextX86* x86); - virtual void SetContextMIPS(MDRawContextMIPS* mips32); - virtual void SetContextMIPS64(MDRawContextMIPS* mips64); -}; - -// This class provides access to microdump memory regions. -// See memory_region.h for documentation. -class MicrodumpMemoryRegion : public MemoryRegion { - public: - MicrodumpMemoryRegion(); - virtual ~MicrodumpMemoryRegion() {} - - // Set this region's address and contents. If we have placed an - // instance of this class in a test fixture class, individual tests - // can use this to provide the region's contents. - void Init(uint64_t base_address, const std::vector& contents); - - virtual uint64_t GetBase() const; - virtual uint32_t GetSize() const; - - virtual bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const; - virtual bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const; - virtual bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const; - virtual bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const; - - // Print a human-readable representation of the object to stdout. - virtual void Print() const; - - private: - // Fetch a little-endian value from ADDRESS in contents_ whose size - // is BYTES, and store it in *VALUE. Returns true on success. - template - bool GetMemoryLittleEndian(uint64_t address, ValueType* value) const; - - uint64_t base_address_; - std::vector contents_; -}; - -// Microdump is the user's interface to a microdump file. It provides access to -// the microdump's context, memory regions and modules. -class Microdump { - public: - explicit Microdump(const string& contents); - virtual ~Microdump() {} - - DumpContext* GetContext() { return context_.get(); } - MicrodumpMemoryRegion* GetMemory() { return stack_region_.get(); } - MicrodumpModules* GetModules() { return modules_.get(); } - SystemInfo* GetSystemInfo() { return system_info_.get(); } - - private: - scoped_ptr context_; - scoped_ptr stack_region_; - scoped_ptr modules_; - scoped_ptr system_info_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__ - diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump_processor.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump_processor.h deleted file mode 100644 index 1322a01c7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/microdump_processor.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The processor for microdump (a reduced dump containing only the state of the -// crashing thread). See crbug.com/410294 for more info and design docs. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__ - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/process_result.h" - -namespace google_breakpad { - -class ProcessState; -class StackFrameSymbolizer; - -class MicrodumpProcessor { - public: - // Initializes the MicrodumpProcessor with a stack frame symbolizer. - // Does not take ownership of frame_symbolizer, which must NOT be NULL. - explicit MicrodumpProcessor(StackFrameSymbolizer* frame_symbolizer); - - virtual ~MicrodumpProcessor(); - - // Processes the microdump contents and fills process_state with the result. - google_breakpad::ProcessResult Process(const string& microdump_contents, - ProcessState* process_state); - private: - StackFrameSymbolizer* frame_symbolizer_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_PROCESSOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h deleted file mode 100644 index c8c3cd481..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h +++ /dev/null @@ -1,1171 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump.h: A minidump reader. -// -// The basic structure of this module tracks the structure of the minidump -// file itself. At the top level, a minidump file is represented by a -// Minidump object. Like most other classes in this module, Minidump -// provides a Read method that initializes the object with information from -// the file. Most of the classes in this file are wrappers around the -// "raw" structures found in the minidump file itself, and defined in -// minidump_format.h. For example, each thread is represented by a -// MinidumpThread object, whose parameters are specified in an MDRawThread -// structure. A properly byte-swapped MDRawThread can be obtained from a -// MinidumpThread easily by calling its thread() method. -// -// Most of the module lazily reads only the portion of the minidump file -// necessary to fulfill the user's request. Calling Minidump::Read -// only reads the minidump's directory. The thread list is not read until -// it is needed, and even once it's read, the memory regions for each -// thread's stack aren't read until they're needed. This strategy avoids -// unnecessary file input, and allocating memory for data in which the user -// has no interest. Note that although memory allocations for a typical -// minidump file are not particularly large, it is possible for legitimate -// minidumps to be sizable. A full-memory minidump, for example, contains -// a snapshot of the entire mapped memory space. Even a normal minidump, -// with stack memory only, can be large if, for example, the dump was -// generated in response to a crash that occurred due to an infinite- -// recursion bug that caused the stack's limits to be exceeded. Finally, -// some users of this library will unfortunately find themselves in the -// position of having to process potentially-hostile minidumps that might -// attempt to cause problems by forcing the minidump processor to over- -// allocate memory. -// -// Memory management in this module is based on a strict -// you-don't-own-anything policy. The only object owned by the user is -// the top-level Minidump object, the creation and destruction of which -// must be the user's own responsibility. All other objects obtained -// through interaction with this module are ultimately owned by the -// Minidump object, and will be freed upon the Minidump object's destruction. -// Because memory regions can potentially involve large allocations, a -// FreeMemory method is provided by MinidumpMemoryRegion, allowing the user -// to release data when it is no longer needed. Use of this method is -// optional but recommended. If freed data is later required, it will -// be read back in from the minidump file again. -// -// There is one exception to this memory management policy: -// Minidump::ReadString will return a string object to the user, and the user -// is responsible for its deletion. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__ - -#include - -#ifndef _WIN32 -#include -#endif - -#include -#include -#include -#include - -#include "common/basictypes.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/dump_context.h" -#include "google_breakpad/processor/dump_object.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/proc_maps_linux.h" - - -namespace google_breakpad { - - -using std::map; -using std::vector; - - -class Minidump; -template class RangeMap; - - -// MinidumpObject is the base of all Minidump* objects except for Minidump -// itself. -class MinidumpObject : public DumpObject { - public: - virtual ~MinidumpObject() {} - - protected: - explicit MinidumpObject(Minidump* minidump); - - // Refers to the Minidump object that is the ultimate parent of this - // Some MinidumpObjects are owned by other MinidumpObjects, but at the - // root of the ownership tree is always a Minidump. The Minidump object - // is kept here for access to its seeking and reading facilities, and - // for access to data about the minidump file itself, such as whether - // it should be byte-swapped. - Minidump* minidump_; -}; - - -// This class exists primarily to provide a virtual destructor in a base -// class common to all objects that might be stored in -// Minidump::mStreamObjects. Some object types will never be stored in -// Minidump::mStreamObjects, but are represented as streams and adhere to the -// same interface, and may be derived from this class. -class MinidumpStream : public MinidumpObject { - public: - virtual ~MinidumpStream() {} - - protected: - explicit MinidumpStream(Minidump* minidump); - - private: - // Populate (and validate) the MinidumpStream. minidump_ is expected - // to be positioned at the beginning of the stream, so that the next - // read from the minidump will be at the beginning of the stream. - // expected_size should be set to the stream's length as contained in - // the MDRawDirectory record or other identifying record. A class - // that implements MinidumpStream can compare expected_size to a - // known size as an integrity check. - virtual bool Read(uint32_t expected_size) = 0; - - DISALLOW_COPY_AND_ASSIGN(MinidumpStream); -}; - - -// MinidumpContext carries a CPU-specific MDRawContext structure, which -// contains CPU context such as register states. Each thread has its -// own context, and the exception record, if present, also has its own -// context. Note that if the exception record is present, the context it -// refers to is probably what the user wants to use for the exception -// thread, instead of that thread's own context. The exception thread's -// context (as opposed to the exception record's context) will contain -// context for the exception handler (which performs minidump generation), -// and not the context that caused the exception (which is probably what the -// user wants). -class MinidumpContext : public DumpContext { - public: - virtual ~MinidumpContext(); - - protected: - explicit MinidumpContext(Minidump* minidump); - - private: - friend class MinidumpThread; - friend class MinidumpException; - - bool Read(uint32_t expected_size); - - // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the - // system info stream gives an appropriate CPU type matching the context - // CPU type in context_cpu_type. Returns false if the CPU type does not - // match. Returns true if the CPU type matches or if the minidump does - // not contain a system info stream. - bool CheckAgainstSystemInfo(uint32_t context_cpu_type); - - // Refers to the Minidump object that is the ultimate parent of this - // Some MinidumpObjects are owned by other MinidumpObjects, but at the - // root of the ownership tree is always a Minidump. The Minidump object - // is kept here for access to its seeking and reading facilities, and - // for access to data about the minidump file itself, such as whether - // it should be byte-swapped. - Minidump* minidump_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpContext); -}; - - -// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains -// a reference to an MDMemoryDescriptor. This object is intended to wrap -// portions of a minidump file that contain memory dumps. In normal -// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding -// to the thread's stack memory. MinidumpMemoryList also gives access to -// memory regions in its list as MinidumpMemoryRegions. This class -// adheres to MemoryRegion so that it may be used as a data provider to -// the Stackwalker family of classes. -class MinidumpMemoryRegion : public MinidumpObject, - public MemoryRegion { - public: - virtual ~MinidumpMemoryRegion(); - - static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; } - static uint32_t max_bytes() { return max_bytes_; } - - // Returns a pointer to the base of the memory region. Returns the - // cached value if available, otherwise, reads the minidump file and - // caches the memory region. - const uint8_t* GetMemory() const; - - // The address of the base of the memory region. - uint64_t GetBase() const; - - // The size, in bytes, of the memory region. - uint32_t GetSize() const; - - // Frees the cached memory region, if cached. - void FreeMemory(); - - // Obtains the value of memory at the pointer specified by address. - bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const; - bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const; - bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const; - bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const; - - // Print a human-readable representation of the object to stdout. - void Print() const; - - protected: - explicit MinidumpMemoryRegion(Minidump* minidump); - - private: - friend class MinidumpThread; - friend class MinidumpMemoryList; - - // Identify the base address and size of the memory region, and the - // location it may be found in the minidump file. - void SetDescriptor(MDMemoryDescriptor* descriptor); - - // Implementation for GetMemoryAtAddress - template bool GetMemoryAtAddressInternal(uint64_t address, - T* value) const; - - // The largest memory region that will be read from a minidump. The - // default is 1MB. - static uint32_t max_bytes_; - - // Base address and size of the memory region, and its position in the - // minidump file. - MDMemoryDescriptor* descriptor_; - - // Cached memory. - mutable vector* memory_; -}; - - -// MinidumpThread contains information about a thread of execution, -// including a snapshot of the thread's stack and CPU context. For -// the thread that caused an exception, the context carried by -// MinidumpException is probably desired instead of the CPU context -// provided here. -// Note that a MinidumpThread may be valid() even if it does not -// contain a memory region or context. -class MinidumpThread : public MinidumpObject { - public: - virtual ~MinidumpThread(); - - const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; } - // GetMemory may return NULL even if the MinidumpThread is valid, - // if the thread memory cannot be read. - virtual MinidumpMemoryRegion* GetMemory(); - // GetContext may return NULL even if the MinidumpThread is valid. - virtual MinidumpContext* GetContext(); - - // The thread ID is used to determine if a thread is the exception thread, - // so a special getter is provided to retrieve this data from the - // MDRawThread structure. Returns false if the thread ID cannot be - // determined. - virtual bool GetThreadID(uint32_t *thread_id) const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - // Returns the start address of the thread stack memory region. Returns 0 if - // MinidumpThread is invalid. Note that this method can be called even when - // the thread memory cannot be read and GetMemory returns NULL. - virtual uint64_t GetStartOfStackMemoryRange() const; - - protected: - explicit MinidumpThread(Minidump* minidump); - - private: - // These objects are managed by MinidumpThreadList. - friend class MinidumpThreadList; - - // This works like MinidumpStream::Read, but is driven by - // MinidumpThreadList. No size checking is done, because - // MinidumpThreadList handles that directly. - bool Read(); - - MDRawThread thread_; - MinidumpMemoryRegion* memory_; - MinidumpContext* context_; -}; - - -// MinidumpThreadList contains all of the threads (as MinidumpThreads) in -// a process. -class MinidumpThreadList : public MinidumpStream { - public: - virtual ~MinidumpThreadList(); - - static void set_max_threads(uint32_t max_threads) { - max_threads_ = max_threads; - } - static uint32_t max_threads() { return max_threads_; } - - virtual unsigned int thread_count() const { - return valid_ ? thread_count_ : 0; - } - - // Sequential access to threads. - virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const; - - // Random access to threads. - MinidumpThread* GetThreadByID(uint32_t thread_id); - - // Print a human-readable representation of the object to stdout. - void Print(); - - protected: - explicit MinidumpThreadList(Minidump* aMinidump); - - private: - friend class Minidump; - - typedef map IDToThreadMap; - typedef vector MinidumpThreads; - - static const uint32_t kStreamType = MD_THREAD_LIST_STREAM; - - bool Read(uint32_t aExpectedSize); - - // The largest number of threads that will be read from a minidump. The - // default is 256. - static uint32_t max_threads_; - - // Access to threads using the thread ID as the key. - IDToThreadMap id_to_thread_map_; - - // The list of threads. - MinidumpThreads* threads_; - uint32_t thread_count_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpThreadList); -}; - - -// MinidumpModule wraps MDRawModule, which contains information about loaded -// code modules. Access is provided to various data referenced indirectly -// by MDRawModule, such as the module's name and a specification for where -// to locate debugging information for the module. -class MinidumpModule : public MinidumpObject, - public CodeModule { - public: - virtual ~MinidumpModule(); - - static void set_max_cv_bytes(uint32_t max_cv_bytes) { - max_cv_bytes_ = max_cv_bytes; - } - static uint32_t max_cv_bytes() { return max_cv_bytes_; } - - static void set_max_misc_bytes(uint32_t max_misc_bytes) { - max_misc_bytes_ = max_misc_bytes; - } - static uint32_t max_misc_bytes() { return max_misc_bytes_; } - - const MDRawModule* module() const { return valid_ ? &module_ : NULL; } - - // CodeModule implementation - virtual uint64_t base_address() const { - return valid_ ? module_.base_of_image : static_cast(-1); - } - virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; } - virtual string code_file() const; - virtual string code_identifier() const; - virtual string debug_file() const; - virtual string debug_identifier() const; - virtual string version() const; - virtual CodeModule* Copy() const; - - // Getter and setter for shrink_down_delta. This is used when the address - // range for a module is shrunk down due to address range conflicts with - // other modules. The base_address and size fields are not updated and they - // should always reflect the original values (reported in the minidump). - virtual uint64_t shrink_down_delta() const; - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta); - - // The CodeView record, which contains information to locate the module's - // debugging information (pdb). This is returned as uint8_t* because - // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be - // of a type unknown to Breakpad, in which case the raw data will still be - // returned but no byte-swapping will have been performed. Check the - // record's signature in the first four bytes to differentiate between - // the various types. Current toolchains generate modules which carry - // MDCVInfoPDB70 by default. Returns a pointer to the CodeView record on - // success, and NULL on failure. On success, the optional |size| argument - // is set to the size of the CodeView record. - const uint8_t* GetCVRecord(uint32_t* size); - - // The miscellaneous debug record, which is obsolete. Current toolchains - // do not generate this type of debugging information (dbg), and this - // field is not expected to be present. Returns a pointer to the debugging - // record on success, and NULL on failure. On success, the optional |size| - // argument is set to the size of the debugging record. - const MDImageDebugMisc* GetMiscRecord(uint32_t* size); - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - // These objects are managed by MinidumpModuleList. - friend class MinidumpModuleList; - - explicit MinidumpModule(Minidump* minidump); - - // This works like MinidumpStream::Read, but is driven by - // MinidumpModuleList. No size checking is done, because - // MinidumpModuleList handles that directly. - bool Read(); - - // Reads indirectly-referenced data, including the module name, CodeView - // record, and miscellaneous debugging record. This is necessary to allow - // MinidumpModuleList to fully construct MinidumpModule objects without - // requiring seeks to read a contiguous set of MinidumpModule objects. - // All auxiliary data should be available when Read is called, in order to - // allow the CodeModule getters to be const methods. - bool ReadAuxiliaryData(); - - // The largest number of bytes that will be read from a minidump for a - // CodeView record or miscellaneous debugging record, respectively. The - // default for each is 1024. - static uint32_t max_cv_bytes_; - static uint32_t max_misc_bytes_; - - // True after a successful Read. This is different from valid_, which is - // not set true until ReadAuxiliaryData also completes successfully. - // module_valid_ is only used by ReadAuxiliaryData and the functions it - // calls to determine whether the object is ready for auxiliary data to - // be read. - bool module_valid_; - - // True if debug info was read from the module. Certain modules - // may contain debug records in formats we don't support, - // so we can just set this to false to ignore them. - bool has_debug_info_; - - MDRawModule module_; - - // Cached module name. - const string* name_; - - // Cached CodeView record - this is MDCVInfoPDB20 or (likely) - // MDCVInfoPDB70, or possibly something else entirely. Stored as a uint8_t - // because the structure contains a variable-sized string and its exact - // size cannot be known until it is processed. - vector* cv_record_; - - // If cv_record_ is present, cv_record_signature_ contains a copy of the - // CodeView record's first four bytes, for ease of determinining the - // type of structure that cv_record_ contains. - uint32_t cv_record_signature_; - - // Cached MDImageDebugMisc (usually not present), stored as uint8_t - // because the structure contains a variable-sized string and its exact - // size cannot be known until it is processed. - vector* misc_record_; -}; - - -// MinidumpModuleList contains all of the loaded code modules for a process -// in the form of MinidumpModules. It maintains a map of these modules -// so that it may easily provide a code module corresponding to a specific -// address. -class MinidumpModuleList : public MinidumpStream, - public CodeModules { - public: - virtual ~MinidumpModuleList(); - - static void set_max_modules(uint32_t max_modules) { - max_modules_ = max_modules; - } - static uint32_t max_modules() { return max_modules_; } - - // CodeModules implementation. - virtual unsigned int module_count() const { - return valid_ ? module_count_ : 0; - } - virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const; - virtual const MinidumpModule* GetMainModule() const; - virtual const MinidumpModule* GetModuleAtSequence( - unsigned int sequence) const; - virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const; - virtual const CodeModules* Copy() const; - - // Returns a vector of all modules which address ranges needed to be shrunk - // down due to address range conflicts with other modules. - virtual vector > GetShrunkRangeModules() const; - - // Returns true, if module address range shrink is enabled. - virtual bool IsModuleShrinkEnabled() const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - protected: - explicit MinidumpModuleList(Minidump* minidump); - - private: - friend class Minidump; - - typedef vector MinidumpModules; - - static const uint32_t kStreamType = MD_MODULE_LIST_STREAM; - - bool Read(uint32_t expected_size); - - // The largest number of modules that will be read from a minidump. The - // default is 1024. - static uint32_t max_modules_; - - // Access to modules using addresses as the key. - RangeMap *range_map_; - - MinidumpModules *modules_; - uint32_t module_count_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpModuleList); -}; - - -// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream, -// which references the snapshots of all of the memory regions contained -// within the minidump. For a normal minidump, this includes stack memory -// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors -// here and in MDRawThread both point to exactly the same data in a -// minidump file, conserving space), as well as a 256-byte snapshot of memory -// surrounding the instruction pointer in the case of an exception. Other -// types of minidumps may contain significantly more memory regions. Full- -// memory minidumps contain all of a process' mapped memory. -class MinidumpMemoryList : public MinidumpStream { - public: - virtual ~MinidumpMemoryList(); - - static void set_max_regions(uint32_t max_regions) { - max_regions_ = max_regions; - } - static uint32_t max_regions() { return max_regions_; } - - unsigned int region_count() const { return valid_ ? region_count_ : 0; } - - // Sequential access to memory regions. - MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index); - - // Random access to memory regions. Returns the region encompassing - // the address identified by address. - virtual MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address); - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - friend class MockMinidumpMemoryList; - - typedef vector MemoryDescriptors; - typedef vector MemoryRegions; - - static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM; - - explicit MinidumpMemoryList(Minidump* minidump); - - bool Read(uint32_t expected_size); - - // The largest number of memory regions that will be read from a minidump. - // The default is 256. - static uint32_t max_regions_; - - // Access to memory regions using addresses as the key. - RangeMap *range_map_; - - // The list of descriptors. This is maintained separately from the list - // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it - // maintains a pointer to it. descriptors_ provides the storage for this - // purpose. - MemoryDescriptors *descriptors_; - - // The list of regions. - MemoryRegions *regions_; - uint32_t region_count_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryList); -}; - - -// MinidumpException wraps MDRawExceptionStream, which contains information -// about the exception that caused the minidump to be generated, if the -// minidump was generated in an exception handler called as a result of an -// exception. It also provides access to a MinidumpContext object, which -// contains the CPU context for the exception thread at the time the exception -// occurred. -class MinidumpException : public MinidumpStream { - public: - virtual ~MinidumpException(); - - const MDRawExceptionStream* exception() const { - return valid_ ? &exception_ : NULL; - } - - // The thread ID is used to determine if a thread is the exception thread, - // so a special getter is provided to retrieve this data from the - // MDRawExceptionStream structure. Returns false if the thread ID cannot - // be determined. - bool GetThreadID(uint32_t *thread_id) const; - - MinidumpContext* GetContext(); - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - - static const uint32_t kStreamType = MD_EXCEPTION_STREAM; - - explicit MinidumpException(Minidump* minidump); - - bool Read(uint32_t expected_size); - - MDRawExceptionStream exception_; - MinidumpContext* context_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpException); -}; - -// MinidumpAssertion wraps MDRawAssertionInfo, which contains information -// about an assertion that caused the minidump to be generated. -class MinidumpAssertion : public MinidumpStream { - public: - virtual ~MinidumpAssertion(); - - const MDRawAssertionInfo* assertion() const { - return valid_ ? &assertion_ : NULL; - } - - string expression() const { - return valid_ ? expression_ : ""; - } - - string function() const { - return valid_ ? function_ : ""; - } - - string file() const { - return valid_ ? file_ : ""; - } - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - - static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM; - - explicit MinidumpAssertion(Minidump* minidump); - - bool Read(uint32_t expected_size); - - MDRawAssertionInfo assertion_; - string expression_; - string function_; - string file_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpAssertion); -}; - - -// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about -// the system on which the minidump was generated. See also MinidumpMiscInfo. -class MinidumpSystemInfo : public MinidumpStream { - public: - virtual ~MinidumpSystemInfo(); - - const MDRawSystemInfo* system_info() const { - return valid_ ? &system_info_ : NULL; - } - - // GetOS and GetCPU return textual representations of the operating system - // and CPU that produced the minidump. Unlike most other Minidump* methods, - // they return string objects, not weak pointers. Defined values for - // GetOS() are "mac", "windows", and "linux". Defined values for GetCPU - // are "x86" and "ppc". These methods return an empty string when their - // values are unknown. - string GetOS(); - string GetCPU(); - - // I don't know what CSD stands for, but this field is documented as - // returning a textual representation of the OS service pack. On other - // platforms, this provides additional information about an OS version - // level beyond major.minor.micro. Returns NULL if unknown. - const string* GetCSDVersion(); - - // If a CPU vendor string can be determined, returns a pointer to it, - // otherwise, returns NULL. CPU vendor strings can be determined from - // x86 CPUs with CPUID 0. - const string* GetCPUVendor(); - - // Print a human-readable representation of the object to stdout. - void Print(); - - protected: - explicit MinidumpSystemInfo(Minidump* minidump); - MDRawSystemInfo system_info_; - - // Textual representation of the OS service pack, for minidumps produced - // by MiniDumpWriteDump on Windows. - const string* csd_version_; - - private: - friend class Minidump; - - static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM; - - bool Read(uint32_t expected_size); - - // A string identifying the CPU vendor, if known. - const string* cpu_vendor_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpSystemInfo); -}; - - -// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about -// the process that generated the minidump, and optionally additional system -// information. See also MinidumpSystemInfo. -class MinidumpMiscInfo : public MinidumpStream { - public: - const MDRawMiscInfo* misc_info() const { - return valid_ ? &misc_info_ : NULL; - } - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - friend class TestMinidumpMiscInfo; - - static const uint32_t kStreamType = MD_MISC_INFO_STREAM; - - explicit MinidumpMiscInfo(Minidump* minidump_); - - bool Read(uint32_t expected_size_); - - MDRawMiscInfo misc_info_; - - // Populated by Read. Contains the converted strings from the corresponding - // UTF-16 fields in misc_info_ - string standard_name_; - string daylight_name_; - string build_string_; - string dbg_bld_str_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpMiscInfo); -}; - - -// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in -// a minidump that provides additional information about the process state -// at the time the minidump was generated. -class MinidumpBreakpadInfo : public MinidumpStream { - public: - const MDRawBreakpadInfo* breakpad_info() const { - return valid_ ? &breakpad_info_ : NULL; - } - - // These thread IDs are used to determine if threads deserve special - // treatment, so special getters are provided to retrieve this data from - // the MDRawBreakpadInfo structure. The getters return false if the thread - // IDs cannot be determined. - bool GetDumpThreadID(uint32_t *thread_id) const; - bool GetRequestingThreadID(uint32_t *thread_id) const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - - static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM; - - explicit MinidumpBreakpadInfo(Minidump* minidump_); - - bool Read(uint32_t expected_size_); - - MDRawBreakpadInfo breakpad_info_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpBreakpadInfo); -}; - -// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information -// about mapped memory regions in a process, including their ranges -// and protection. -class MinidumpMemoryInfo : public MinidumpObject { - public: - const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; } - - // The address of the base of the memory region. - uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; } - - // The size, in bytes, of the memory region. - uint64_t GetSize() const { return valid_ ? memory_info_.region_size : 0; } - - // Return true if the memory protection allows execution. - bool IsExecutable() const; - - // Return true if the memory protection allows writing. - bool IsWritable() const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - // These objects are managed by MinidumpMemoryInfoList. - friend class MinidumpMemoryInfoList; - - explicit MinidumpMemoryInfo(Minidump* minidump_); - - // This works like MinidumpStream::Read, but is driven by - // MinidumpMemoryInfoList. No size checking is done, because - // MinidumpMemoryInfoList handles that directly. - bool Read(); - - MDRawMemoryInfo memory_info_; -}; - -// MinidumpMemoryInfoList contains a list of information about -// mapped memory regions for a process in the form of MDRawMemoryInfo. -// It maintains a map of these structures so that it may easily provide -// info corresponding to a specific address. -class MinidumpMemoryInfoList : public MinidumpStream { - public: - virtual ~MinidumpMemoryInfoList(); - - unsigned int info_count() const { return valid_ ? info_count_ : 0; } - - const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const; - const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const; - - // Print a human-readable representation of the object to stdout. - void Print(); - - private: - friend class Minidump; - - typedef vector MinidumpMemoryInfos; - - static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM; - - explicit MinidumpMemoryInfoList(Minidump* minidump_); - - bool Read(uint32_t expected_size); - - // Access to memory info using addresses as the key. - RangeMap *range_map_; - - MinidumpMemoryInfos* infos_; - uint32_t info_count_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryInfoList); -}; - -// MinidumpLinuxMaps wraps information about a single mapped memory region -// from /proc/self/maps. -class MinidumpLinuxMaps : public MinidumpObject { - public: - // The memory address of the base of the mapped region. - uint64_t GetBase() const { return valid_ ? region_.start : 0; } - // The size of the mapped region. - uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; } - - // The permissions of the mapped region. - bool IsReadable() const { - return valid_ ? region_.permissions & MappedMemoryRegion::READ : false; - } - bool IsWriteable() const { - return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false; - } - bool IsExecutable() const { - return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false; - } - bool IsPrivate() const { - return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false; - } - - // The offset of the mapped region. - uint64_t GetOffset() const { return valid_ ? region_.offset : 0; } - - // The major device number. - uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; } - // The minor device number. - uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; } - - // The inode of the mapped region. - uint64_t GetInode() const { return valid_ ? region_.inode : 0; } - - // The pathname of the mapped region. - const string GetPathname() const { return valid_ ? region_.path : ""; } - - // Print the contents of this mapping. - void Print() const; - - private: - // These objects are managed by MinidumpLinuxMapsList. - friend class MinidumpLinuxMapsList; - - // This caller owns the pointer. - explicit MinidumpLinuxMaps(Minidump *minidump); - - // The memory region struct that this class wraps. - MappedMemoryRegion region_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps); -}; - -// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS -// stream, which contains the contents of /prod/self/maps, which contains -// the mapped memory regions and their access permissions. -class MinidumpLinuxMapsList : public MinidumpStream { - public: - virtual ~MinidumpLinuxMapsList(); - - // Get number of mappings. - unsigned int get_maps_count() const { return valid_ ? maps_count_ : 0; } - - // Get mapping at the given memory address. The caller owns the pointer. - const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const; - // Get mapping at the given index. The caller owns the pointer. - const MinidumpLinuxMaps *GetLinuxMapsAtIndex(unsigned int index) const; - - // Print the contents of /proc/self/maps to stdout. - void Print() const; - - private: - friend class Minidump; - - typedef vector MinidumpLinuxMappings; - - static const uint32_t kStreamType = MD_LINUX_MAPS; - - // The caller owns the pointer. - explicit MinidumpLinuxMapsList(Minidump *minidump); - - // Read and load the contents of the process mapping data. - // The stream should have data in the form of /proc/self/maps. - // This method returns whether the stream was read successfully. - bool Read(uint32_t expected_size); - - // The list of individual mappings. - MinidumpLinuxMappings *maps_; - // The number of mappings. - uint32_t maps_count_; - - DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList); -}; - -// Minidump is the user's interface to a minidump file. It wraps MDRawHeader -// and provides access to the minidump's top-level stream directory. -class Minidump { - public: - // path is the pathname of a file containing the minidump. - explicit Minidump(const string& path); - // input is an istream wrapping minidump data. Minidump holds a - // weak pointer to input, and the caller must ensure that the stream - // is valid as long as the Minidump object is. - explicit Minidump(std::istream& input); - - virtual ~Minidump(); - - // path may be empty if the minidump was not opened from a file - virtual string path() const { - return path_; - } - static void set_max_streams(uint32_t max_streams) { - max_streams_ = max_streams; - } - static uint32_t max_streams() { return max_streams_; } - - static void set_max_string_length(uint32_t max_string_length) { - max_string_length_ = max_string_length; - } - static uint32_t max_string_length() { return max_string_length_; } - - virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; } - - // Reads the CPU information from the system info stream and generates the - // appropriate CPU flags. The returned context_cpu_flags are the same as - // if the CPU type bits were set in the context_flags of a context record. - // On success, context_cpu_flags will have the flags that identify the CPU. - // If a system info stream is missing, context_cpu_flags will be 0. - // Returns true if the current position in the stream was not changed. - // Returns false when the current location in the stream was changed and the - // attempt to restore the original position failed. - bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags); - - // Reads the minidump file's header and top-level stream directory. - // The minidump is expected to be positioned at the beginning of the - // header. Read() sets up the stream list and map, and validates the - // Minidump object. - virtual bool Read(); - - // The next set of methods are stubs that call GetStream. They exist to - // force code generation of the templatized API within the module, and - // to avoid exposing an ugly API (GetStream needs to accept a garbage - // parameter). - virtual MinidumpThreadList* GetThreadList(); - virtual MinidumpModuleList* GetModuleList(); - virtual MinidumpMemoryList* GetMemoryList(); - virtual MinidumpException* GetException(); - virtual MinidumpAssertion* GetAssertion(); - virtual MinidumpSystemInfo* GetSystemInfo(); - virtual MinidumpMiscInfo* GetMiscInfo(); - virtual MinidumpBreakpadInfo* GetBreakpadInfo(); - virtual MinidumpMemoryInfoList* GetMemoryInfoList(); - - // The next method also calls GetStream, but is exclusive for Linux dumps. - virtual MinidumpLinuxMapsList *GetLinuxMapsList(); - - // The next set of methods are provided for users who wish to access - // data in minidump files directly, while leveraging the rest of - // this class and related classes to handle the basic minidump - // structure and known stream types. - - unsigned int GetDirectoryEntryCount() const { - return valid_ ? header_.stream_count : 0; - } - const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const; - - // The next 2 methods are lower-level I/O routines. They use fd_. - - // Reads count bytes from the minidump at the current position into - // the storage area pointed to by bytes. bytes must be of sufficient - // size. After the read, the file position is advanced by count. - bool ReadBytes(void* bytes, size_t count); - - // Sets the position of the minidump file to offset. - bool SeekSet(off_t offset); - - // Returns the current position of the minidump file. - off_t Tell(); - - // The next 2 methods are medium-level I/O routines. - - // ReadString returns a string which is owned by the caller! offset - // specifies the offset that a length-encoded string is stored at in the - // minidump file. - string* ReadString(off_t offset); - - // SeekToStreamType positions the file at the beginning of a stream - // identified by stream_type, and informs the caller of the stream's - // length by setting *stream_length. Because stream_map maps each stream - // type to only one stream in the file, this might mislead the user into - // thinking that the stream that this seeks to is the only stream with - // type stream_type. That can't happen for streams that these classes - // deal with directly, because they're only supposed to be present in the - // file singly, and that's verified when stream_map_ is built. Users who - // are looking for other stream types should be aware of this - // possibility, and consider using GetDirectoryEntryAtIndex (possibly - // with GetDirectoryEntryCount) if expecting multiple streams of the same - // type in a single minidump file. - bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length); - - bool swap() const { return valid_ ? swap_ : false; } - - // Print a human-readable representation of the object to stdout. - void Print(); - - // Is the OS Android. - bool IsAndroid(); - - private: - // MinidumpStreamInfo is used in the MinidumpStreamMap. It lets - // the Minidump object locate interesting streams quickly, and - // provides a convenient place to stash MinidumpStream objects. - struct MinidumpStreamInfo { - MinidumpStreamInfo() : stream_index(0), stream(NULL) {} - ~MinidumpStreamInfo() { delete stream; } - - // Index into the MinidumpDirectoryEntries vector - unsigned int stream_index; - - // Pointer to the stream if cached, or NULL if not yet populated - MinidumpStream* stream; - }; - - typedef vector MinidumpDirectoryEntries; - typedef map MinidumpStreamMap; - - template T* GetStream(T** stream); - - // Opens the minidump file, or if already open, seeks to the beginning. - bool Open(); - - // The largest number of top-level streams that will be read from a minidump. - // Note that streams are only read (and only consume memory) as needed, - // when directed by the caller. The default is 128. - static uint32_t max_streams_; - - // The maximum length of a UTF-16 string that will be read from a minidump - // in 16-bit words. The default is 1024. UTF-16 strings are converted - // to UTF-8 when stored in memory, and each UTF-16 word will be represented - // by as many as 3 bytes in UTF-8. - static unsigned int max_string_length_; - - MDRawHeader header_; - - // The list of streams. - MinidumpDirectoryEntries* directory_; - - // Access to streams using the stream type as the key. - MinidumpStreamMap* stream_map_; - - // The pathname of the minidump file to process, set in the constructor. - // This may be empty if the minidump was opened directly from a stream. - const string path_; - - // The stream for all file I/O. Used by ReadBytes and SeekSet. - // Set based on the path in Open, or directly in the constructor. - std::istream* stream_; - - // swap_ is true if the minidump file should be byte-swapped. If the - // minidump was produced by a CPU that is other-endian than the CPU - // processing the minidump, this will be true. If the two CPUs are - // same-endian, this will be false. - bool swap_; - - // Validity of the Minidump structure, false immediately after - // construction or after a failed Read(); true following a successful - // Read(). - bool valid_; - - DISALLOW_COPY_AND_ASSIGN(Minidump); -}; - - -} // namespace google_breakpad - - -#endif // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump_processor.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump_processor.h deleted file mode 100644 index 387115ef7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump_processor.h +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/process_result.h" - -namespace google_breakpad { - -class Minidump; -class ProcessState; -class StackFrameSymbolizer; -class SourceLineResolverInterface; -class SymbolSupplier; -struct SystemInfo; - -class MinidumpProcessor { - public: - // Initializes this MinidumpProcessor. supplier should be an - // implementation of the SymbolSupplier abstract base class. - MinidumpProcessor(SymbolSupplier* supplier, - SourceLineResolverInterface* resolver); - - // Initializes the MinidumpProcessor with the option of - // enabling the exploitability framework to analyze dumps - // for probable security relevance. - MinidumpProcessor(SymbolSupplier* supplier, - SourceLineResolverInterface* resolver, - bool enable_exploitability); - - // Initializes the MinidumpProcessor with source line resolver helper, and - // the option of enabling the exploitability framework to analyze dumps - // for probable security relevance. - // Does not take ownership of resolver_helper, which must NOT be NULL. - MinidumpProcessor(StackFrameSymbolizer* stack_frame_symbolizer, - bool enable_exploitability); - - ~MinidumpProcessor(); - - // Processes the minidump file and fills process_state with the result. - ProcessResult Process(const string &minidump_file, - ProcessState* process_state); - - // Processes the minidump structure and fills process_state with the - // result. - ProcessResult Process(Minidump* minidump, - ProcessState* process_state); - // Populates the cpu_* fields of the |info| parameter with textual - // representations of the CPU type that the minidump in |dump| was - // produced on. Returns false if this information is not available in - // the minidump. - static bool GetCPUInfo(Minidump* dump, SystemInfo* info); - - // Populates the os_* fields of the |info| parameter with textual - // representations of the operating system that the minidump in |dump| - // was produced on. Returns false if this information is not available in - // the minidump. - static bool GetOSInfo(Minidump* dump, SystemInfo* info); - - // Populates the |process_create_time| parameter with the create time of the - // crashed process. Returns false if this information is not available in - // the minidump |dump|. - static bool GetProcessCreateTime(Minidump* dump, - uint32_t* process_create_time); - - // Returns a textual representation of the reason that a crash occurred, - // if the minidump in dump was produced as a result of a crash. Returns - // an empty string if this information cannot be determined. If address - // is non-NULL, it will be set to contain the address that caused the - // exception, if this information is available. This will be a code - // address when the crash was caused by problems such as illegal - // instructions or divisions by zero, or a data address when the crash - // was caused by a memory access violation. - static string GetCrashReason(Minidump* dump, uint64_t* address); - - // This function returns true if the passed-in error code is - // something unrecoverable(i.e. retry should not happen). For - // instance, if the minidump is corrupt, then it makes no sense to - // retry as we won't be able to glean additional information. - // However, as an example of the other case, the symbol supplier can - // return an error code indicating it was 'interrupted', which can - // happen of the symbols are fetched from a remote store, and a - // retry might be successful later on. - // You should not call this method with PROCESS_OK! Test for - // that separately before calling this. - static bool IsErrorUnrecoverable(ProcessResult p) { - assert(p != PROCESS_OK); - return (p != PROCESS_SYMBOL_SUPPLIER_INTERRUPTED); - } - - // Returns a textual representation of an assertion included - // in the minidump. Returns an empty string if this information - // does not exist or cannot be determined. - static string GetAssertion(Minidump* dump); - - void set_enable_objdump(bool enabled) { enable_objdump_ = enabled; } - - private: - StackFrameSymbolizer* frame_symbolizer_; - // Indicate whether resolver_helper_ is owned by this instance. - bool own_frame_symbolizer_; - - // This flag enables the exploitability scanner which attempts to - // guess how likely it is that the crash represents an exploitable - // memory corruption issue. - bool enable_exploitability_; - - // This flag permits the exploitability scanner to shell out to objdump - // for purposes of disassembly. - bool enable_objdump_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_PROCESSOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/proc_maps_linux.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/proc_maps_linux.h deleted file mode 100644 index b8e6eb926..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/proc_maps_linux.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_DEBUG_PROC_MAPS_LINUX_H_ -#define BASE_DEBUG_PROC_MAPS_LINUX_H_ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -// Describes a region of mapped memory and the path of the file mapped. -struct MappedMemoryRegion { - enum Permission { - READ = 1 << 0, - WRITE = 1 << 1, - EXECUTE = 1 << 2, - PRIVATE = 1 << 3, // If set, region is private, otherwise it is shared. - }; - - // The address range [start,end) of mapped memory. - uint64_t start; - uint64_t end; - - // Byte offset into |path| of the range mapped into memory. - uint64_t offset; - - // Bitmask of read/write/execute/private/shared permissions. - uint8_t permissions; - - // Major and minor devices. - uint8_t major_device; - uint8_t minor_device; - - // Value of the inode. - uint64_t inode; - - // Name of the file mapped into memory. - // - // NOTE: path names aren't guaranteed to point at valid files. For example, - // "[heap]" and "[stack]" are used to represent the location of the process' - // heap and stack, respectively. - string path; - - // The line from /proc//maps that this struct represents. - string line; -}; - -// Parses /proc//maps input data and stores in |regions|. Returns true -// and updates |regions| if and only if all of |input| was successfully parsed. -bool ParseProcMaps(const std::string& input, - std::vector* regions); - -} // namespace google_breakpad - -#endif // BASE_DEBUG_PROC_MAPS_LINUX_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_result.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_result.h deleted file mode 100644 index 15c7213e9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_result.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__ - -namespace google_breakpad { - -// Return type for MinidumpProcessor or MicrodumpProcessor's Process() -enum ProcessResult { - PROCESS_OK, // The dump was processed - // successfully. - - PROCESS_ERROR_MINIDUMP_NOT_FOUND, // The minidump file was not - // found. - - PROCESS_ERROR_NO_MINIDUMP_HEADER, // The minidump file had no - // header. - - PROCESS_ERROR_NO_THREAD_LIST, // The minidump file has no - // thread list. - - PROCESS_ERROR_GETTING_THREAD, // There was an error getting one - // thread's data from th dump. - - PROCESS_ERROR_GETTING_THREAD_ID, // There was an error getting a - // thread id from the thread's - // data. - - PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS, // There was more than one - // requesting thread. - - PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The dump processing was - // interrupted by the - // SymbolSupplier(not fatal). -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_PROCESS_RESULT_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_state.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_state.h deleted file mode 100644 index 9f12b0c69..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_state.h +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// process_state.h: A snapshot of a process, in a fully-digested state. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/linked_ptr.h" - -namespace google_breakpad { - -using std::vector; - -class CallStack; -class CodeModules; - -enum ExploitabilityRating { - EXPLOITABILITY_HIGH, // The crash likely represents - // a exploitable memory corruption - // vulnerability. - - EXPLOITABILITY_MEDIUM, // The crash appears to corrupt - // memory in a way which may be - // exploitable in some situations. - - EXPLOITABLITY_MEDIUM = EXPLOITABILITY_MEDIUM, // an old misspelling - - EXPLOITABILITY_LOW, // The crash either does not corrupt - // memory directly or control over - // the affected data is limited. The - // issue may still be exploitable - // on certain platforms or situations. - - EXPLOITABILITY_INTERESTING, // The crash does not appear to be - // directly exploitable. However it - // represents a condition which should - // be further analyzed. - - EXPLOITABILITY_NONE, // The crash does not appear to represent - // an exploitable condition. - - EXPLOITABILITY_NOT_ANALYZED, // The crash was not analyzed for - // exploitability because the engine - // was disabled. - - EXPLOITABILITY_ERR_NOENGINE, // The supplied minidump's platform does - // not have a exploitability engine - // associated with it. - - EXPLOITABILITY_ERR_PROCESSING // An error occured within the - // exploitability engine and no rating - // was calculated. -}; - -class ProcessState { - public: - ProcessState() : modules_(NULL) { Clear(); } - ~ProcessState(); - - // Resets the ProcessState to its default values - void Clear(); - - // Accessors. See the data declarations below. - uint32_t time_date_stamp() const { return time_date_stamp_; } - uint32_t process_create_time() const { return process_create_time_; } - bool crashed() const { return crashed_; } - string crash_reason() const { return crash_reason_; } - uint64_t crash_address() const { return crash_address_; } - string assertion() const { return assertion_; } - int requesting_thread() const { return requesting_thread_; } - const vector* threads() const { return &threads_; } - const vector* thread_memory_regions() const { - return &thread_memory_regions_; - } - const SystemInfo* system_info() const { return &system_info_; } - const CodeModules* modules() const { return modules_; } - const vector >* shrunk_range_modules() const { - return &shrunk_range_modules_; - } - const vector* modules_without_symbols() const { - return &modules_without_symbols_; - } - const vector* modules_with_corrupt_symbols() const { - return &modules_with_corrupt_symbols_; - } - ExploitabilityRating exploitability() const { return exploitability_; } - - private: - // MinidumpProcessor and MicrodumpProcessor are responsible for building - // ProcessState objects. - friend class MinidumpProcessor; - friend class MicrodumpProcessor; - - // The time-date stamp of the minidump (time_t format) - uint32_t time_date_stamp_; - - // The time-date stamp when the process was created (time_t format) - uint32_t process_create_time_; - - // True if the process crashed, false if the dump was produced outside - // of an exception handler. - bool crashed_; - - // If the process crashed, the type of crash. OS- and possibly CPU- - // specific. For example, "EXCEPTION_ACCESS_VIOLATION" (Windows), - // "EXC_BAD_ACCESS / KERN_INVALID_ADDRESS" (Mac OS X), "SIGSEGV" - // (other Unix). - string crash_reason_; - - // If the process crashed, and if crash_reason implicates memory, - // the memory address that caused the crash. For data access errors, - // this will be the data address that caused the fault. For code errors, - // this will be the address of the instruction that caused the fault. - uint64_t crash_address_; - - // If there was an assertion that was hit, a textual representation - // of that assertion, possibly including the file and line at which - // it occurred. - string assertion_; - - // The index of the thread that requested a dump be written in the - // threads vector. If a dump was produced as a result of a crash, this - // will point to the thread that crashed. If the dump was produced as - // by user code without crashing, and the dump contains extended Breakpad - // information, this will point to the thread that requested the dump. - // If the dump was not produced as a result of an exception and no - // extended Breakpad information is present, this field will be set to -1, - // indicating that the dump thread is not available. - int requesting_thread_; - - // Stacks for each thread (except possibly the exception handler - // thread) at the time of the crash. - vector threads_; - vector thread_memory_regions_; - - // OS and CPU information. - SystemInfo system_info_; - - // The modules that were loaded into the process represented by the - // ProcessState. - const CodeModules *modules_; - - // The modules which virtual address ranges were shrunk down due to - // virtual address conflicts. - vector > shrunk_range_modules_; - - // The modules that didn't have symbols when the report was processed. - vector modules_without_symbols_; - - // The modules that had corrupt symbols when the report was processed. - vector modules_with_corrupt_symbols_; - - // The exploitability rating as determined by the exploitability - // engine. When the exploitability engine is not enabled this - // defaults to EXPLOITABILITY_NOT_ANALYZED. - ExploitabilityRating exploitability_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_PROCESS_STATE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_base.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_base.h deleted file mode 100644 index c720b0c32..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_base.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// source_line_resolver_base.h: SourceLineResolverBase, an (incomplete) -// implementation of SourceLineResolverInterface. It serves as a common base -// class for concrete implementations: FastSourceLineResolver and -// BasicSourceLineResolver. It is designed for refactoring that removes -// code redundancy in the two concrete source line resolver classes. -// -// See "google_breakpad/processor/source_line_resolver_interface.h" for more -// documentation. - -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__ - -#include -#include -#include - -#include "google_breakpad/processor/source_line_resolver_interface.h" - -namespace google_breakpad { - -using std::map; -using std::set; - -// Forward declaration. -// ModuleFactory is a simple factory interface for creating a Module instance -// at run-time. -class ModuleFactory; - -class SourceLineResolverBase : public SourceLineResolverInterface { - public: - // Read the symbol_data from a file with given file_name. - // The part of code was originally in BasicSourceLineResolver::Module's - // LoadMap() method. - // Place dynamically allocated heap buffer in symbol_data. Caller has the - // ownership of the buffer, and should call delete [] to free the buffer. - static bool ReadSymbolFile(const string &file_name, - char **symbol_data, - size_t *symbol_data_size); - - protected: - // Users are not allowed create SourceLineResolverBase instance directly. - SourceLineResolverBase(ModuleFactory *module_factory); - virtual ~SourceLineResolverBase(); - - // Virtual methods inherited from SourceLineResolverInterface. - virtual bool LoadModule(const CodeModule *module, const string &map_file); - virtual bool LoadModuleUsingMapBuffer(const CodeModule *module, - const string &map_buffer); - virtual bool LoadModuleUsingMemoryBuffer(const CodeModule *module, - char *memory_buffer, - size_t memory_buffer_size); - virtual bool ShouldDeleteMemoryBufferAfterLoadModule(); - virtual void UnloadModule(const CodeModule *module); - virtual bool HasModule(const CodeModule *module); - virtual bool IsModuleCorrupt(const CodeModule *module); - virtual void FillSourceLineInfo(StackFrame *frame); - virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame); - virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame); - - // Nested structs and classes. - struct Line; - struct Function; - struct PublicSymbol; - struct CompareString { - bool operator()(const string &s1, const string &s2) const; - }; - // Module is an interface for an in-memory symbol file. - class Module; - class AutoFileCloser; - - // All of the modules that are loaded. - typedef map ModuleMap; - ModuleMap *modules_; - - // The loaded modules that were detecting to be corrupt during load. - typedef set ModuleSet; - ModuleSet *corrupt_modules_; - - // All of heap-allocated buffers that are owned locally by resolver. - typedef std::map MemoryMap; - MemoryMap *memory_buffers_; - - // Creates a concrete module at run-time. - ModuleFactory *module_factory_; - - private: - // ModuleFactory needs to have access to protected type Module. - friend class ModuleFactory; - - // Disallow unwanted copy ctor and assignment operator - SourceLineResolverBase(const SourceLineResolverBase&); - void operator=(const SourceLineResolverBase&); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_BASE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_interface.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_interface.h deleted file mode 100644 index a694bf2ea..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/source_line_resolver_interface.h +++ /dev/null @@ -1,117 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Abstract interface to return function/file/line info for a memory address. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/code_module.h" - -namespace google_breakpad { - -struct StackFrame; -struct WindowsFrameInfo; -class CFIFrameInfo; - -class SourceLineResolverInterface { - public: - typedef uint64_t MemAddr; - - virtual ~SourceLineResolverInterface() {} - - // Adds a module to this resolver, returning true on success. - // - // module should have at least the code_file, debug_file, - // and debug_identifier members populated. - // - // map_file should contain line/address mappings for this module. - virtual bool LoadModule(const CodeModule *module, - const string &map_file) = 0; - // Same as above, but takes the contents of a pre-read map buffer - virtual bool LoadModuleUsingMapBuffer(const CodeModule *module, - const string &map_buffer) = 0; - - // Add an interface to load symbol using C-String data instead of string. - // This is useful in the optimization design for avoiding unnecessary copying - // of symbol data, in order to improve memory efficiency. - // LoadModuleUsingMemoryBuffer() does NOT take ownership of memory_buffer. - // LoadModuleUsingMemoryBuffer() null terminates the passed in buffer, if - // the last character is not a null terminator. - virtual bool LoadModuleUsingMemoryBuffer(const CodeModule *module, - char *memory_buffer, - size_t memory_buffer_size) = 0; - - // Return true if the memory buffer should be deleted immediately after - // LoadModuleUsingMemoryBuffer(). Return false if the memory buffer has to be - // alive during the lifetime of the corresponding Module. - virtual bool ShouldDeleteMemoryBufferAfterLoadModule() = 0; - - // Request that the specified module be unloaded from this resolver. - // A resolver may choose to ignore such a request. - virtual void UnloadModule(const CodeModule *module) = 0; - - // Returns true if the module has been loaded. - virtual bool HasModule(const CodeModule *module) = 0; - - // Returns true if the module has been loaded and it is corrupt. - virtual bool IsModuleCorrupt(const CodeModule *module) = 0; - - // Fills in the function_base, function_name, source_file_name, - // and source_line fields of the StackFrame. The instruction and - // module_name fields must already be filled in. - virtual void FillSourceLineInfo(StackFrame *frame) = 0; - - // If Windows stack walking information is available covering - // FRAME's instruction address, return a WindowsFrameInfo structure - // describing it. If the information is not available, returns NULL. - // A NULL return value does not indicate an error. The caller takes - // ownership of any returned WindowsFrameInfo object. - virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) = 0; - - // If CFI stack walking information is available covering ADDRESS, - // return a CFIFrameInfo structure describing it. If the information - // is not available, return NULL. The caller takes ownership of any - // returned CFIFrameInfo object. - virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) = 0; - - protected: - // SourceLineResolverInterface cannot be instantiated except by subclasses - SourceLineResolverInterface() {} -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame.h deleted file mode 100644 index b55eb9c75..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__ - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -class CodeModule; - -struct StackFrame { - // Indicates how well the instruction pointer derived during - // stack walking is trusted. Since the stack walker can resort to - // stack scanning, it can wind up with dubious frames. - // In rough order of "trust metric". - enum FrameTrust { - FRAME_TRUST_NONE, // Unknown - FRAME_TRUST_SCAN, // Scanned the stack, found this - FRAME_TRUST_CFI_SCAN, // Found while scanning stack using call frame info - FRAME_TRUST_FP, // Derived from frame pointer - FRAME_TRUST_CFI, // Derived from call frame info - FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker. - FRAME_TRUST_CONTEXT // Given as instruction pointer in a context - }; - - StackFrame() - : instruction(), - module(NULL), - function_name(), - function_base(), - source_file_name(), - source_line(), - source_line_base(), - trust(FRAME_TRUST_NONE) {} - virtual ~StackFrame() {} - - // Return a string describing how this stack frame was found - // by the stackwalker. - string trust_description() const { - switch (trust) { - case StackFrame::FRAME_TRUST_CONTEXT: - return "given as instruction pointer in context"; - case StackFrame::FRAME_TRUST_PREWALKED: - return "recovered by external stack walker"; - case StackFrame::FRAME_TRUST_CFI: - return "call frame info"; - case StackFrame::FRAME_TRUST_CFI_SCAN: - return "call frame info with scanning"; - case StackFrame::FRAME_TRUST_FP: - return "previous frame's frame pointer"; - case StackFrame::FRAME_TRUST_SCAN: - return "stack scanning"; - default: - return "unknown"; - } - }; - - // Return the actual return address, as saved on the stack or in a - // register. See the comments for 'instruction', below, for details. - virtual uint64_t ReturnAddress() const { return instruction; } - - // The program counter location as an absolute virtual address. - // - // - For the innermost called frame in a stack, this will be an exact - // program counter or instruction pointer value. - // - // - For all other frames, this address is within the instruction that - // caused execution to branch to this frame's callee (although it may - // not point to the exact beginning of that instruction). This ensures - // that, when we look up the source code location for this frame, we - // get the source location of the call, not of the point at which - // control will resume when the call returns, which may be on the next - // line. (If the compiler knows the callee never returns, it may even - // place the call instruction at the very end of the caller's machine - // code, such that the "return address" (which will never be used) - // immediately after the call instruction is in an entirely different - // function, perhaps even from a different source file.) - // - // On some architectures, the return address as saved on the stack or in - // a register is fine for looking up the point of the call. On others, it - // requires adjustment. ReturnAddress returns the address as saved by the - // machine. - uint64_t instruction; - - // The module in which the instruction resides. - const CodeModule *module; - - // The function name, may be omitted if debug symbols are not available. - string function_name; - - // The start address of the function, may be omitted if debug symbols - // are not available. - uint64_t function_base; - - // The source file name, may be omitted if debug symbols are not available. - string source_file_name; - - // The (1-based) source line number, may be omitted if debug symbols are - // not available. - int source_line; - - // The start address of the source line, may be omitted if debug symbols - // are not available. - uint64_t source_line_base; - - // Amount of trust the stack walker has in the instruction pointer - // of this frame. - FrameTrust trust; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_cpu.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_cpu.h deleted file mode 100644 index dc5d8ae67..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_cpu.h +++ /dev/null @@ -1,405 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stack_frame_cpu.h: CPU-specific StackFrame extensions. -// -// These types extend the StackFrame structure to carry CPU-specific register -// state. They are defined in this header instead of stack_frame.h to -// avoid the need to include minidump_format.h when only the generic -// StackFrame type is needed. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__ - -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stack_frame.h" - -namespace google_breakpad { - -struct WindowsFrameInfo; -class CFIFrameInfo; - -struct StackFrameX86 : public StackFrame { - // ContextValidity has one entry for each relevant hardware pointer - // register (%eip and %esp) and one entry for each general-purpose - // register. It's worthwhile having validity flags for caller-saves - // registers: they are valid in the youngest frame, and such a frame - // might save a callee-saves register in a caller-saves register, but - // SimpleCFIWalker won't touch registers unless they're marked as valid. - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_EIP = 1 << 0, - CONTEXT_VALID_ESP = 1 << 1, - CONTEXT_VALID_EBP = 1 << 2, - CONTEXT_VALID_EAX = 1 << 3, - CONTEXT_VALID_EBX = 1 << 4, - CONTEXT_VALID_ECX = 1 << 5, - CONTEXT_VALID_EDX = 1 << 6, - CONTEXT_VALID_ESI = 1 << 7, - CONTEXT_VALID_EDI = 1 << 8, - CONTEXT_VALID_ALL = -1 - }; - - StackFrameX86() - : context(), - context_validity(CONTEXT_VALID_NONE), - windows_frame_info(NULL), - cfi_frame_info(NULL) {} - ~StackFrameX86(); - - // Overriden to return the return address as saved on the stack. - virtual uint64_t ReturnAddress() const; - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextX86 context; - - // context_validity is actually ContextValidity, but int is used because - // the OR operator doesn't work well with enumerated types. This indicates - // which fields in context are valid. - int context_validity; - - // Any stack walking information we found describing this.instruction. - // These may be NULL if there is no such information for that address. - WindowsFrameInfo *windows_frame_info; - CFIFrameInfo *cfi_frame_info; -}; - -struct StackFramePPC : public StackFrame { - // ContextValidity should eventually contain entries for the validity of - // other nonvolatile (callee-save) registers as in - // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently - // locate registers other than the ones listed here. - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_SRR0 = 1 << 0, - CONTEXT_VALID_GPR1 = 1 << 1, - CONTEXT_VALID_ALL = -1 - }; - - StackFramePPC() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextPPC context; - - // context_validity is actually ContextValidity, but int is used because - // the OR operator doesn't work well with enumerated types. This indicates - // which fields in context are valid. - int context_validity; -}; - -struct StackFramePPC64 : public StackFrame { - // ContextValidity should eventually contain entries for the validity of - // other nonvolatile (callee-save) registers as in - // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently - // locate registers other than the ones listed here. - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_SRR0 = 1 << 0, - CONTEXT_VALID_GPR1 = 1 << 1, - CONTEXT_VALID_ALL = -1 - }; - - StackFramePPC64() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextPPC64 context; - - // context_validity is actually ContextValidity, but int is used because - // the OR operator doesn't work well with enumerated types. This indicates - // which fields in context are valid. - int context_validity; -}; - -struct StackFrameAMD64 : public StackFrame { - // ContextValidity has one entry for each register that we might be able - // to recover. - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_RAX = 1 << 0, - CONTEXT_VALID_RDX = 1 << 1, - CONTEXT_VALID_RCX = 1 << 2, - CONTEXT_VALID_RBX = 1 << 3, - CONTEXT_VALID_RSI = 1 << 4, - CONTEXT_VALID_RDI = 1 << 5, - CONTEXT_VALID_RBP = 1 << 6, - CONTEXT_VALID_RSP = 1 << 7, - CONTEXT_VALID_R8 = 1 << 8, - CONTEXT_VALID_R9 = 1 << 9, - CONTEXT_VALID_R10 = 1 << 10, - CONTEXT_VALID_R11 = 1 << 11, - CONTEXT_VALID_R12 = 1 << 12, - CONTEXT_VALID_R13 = 1 << 13, - CONTEXT_VALID_R14 = 1 << 14, - CONTEXT_VALID_R15 = 1 << 15, - CONTEXT_VALID_RIP = 1 << 16, - CONTEXT_VALID_ALL = -1 - }; - - StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Overriden to return the return address as saved on the stack. - virtual uint64_t ReturnAddress() const; - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, which registers are present depends on what - // debugging information we had available. Refer to context_validity. - MDRawContextAMD64 context; - - // For each register in context whose value has been recovered, we set - // the corresponding CONTEXT_VALID_ bit in context_validity. - // - // context_validity's type should actually be ContextValidity, but - // we use int instead because the bitwise inclusive or operator - // yields an int when applied to enum values, and C++ doesn't - // silently convert from ints to enums. - int context_validity; -}; - -struct StackFrameSPARC : public StackFrame { - // to be confirmed - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_PC = 1 << 0, - CONTEXT_VALID_SP = 1 << 1, - CONTEXT_VALID_FP = 1 << 2, - CONTEXT_VALID_ALL = -1 - }; - - StackFrameSPARC() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextSPARC context; - - // context_validity is actually ContextValidity, but int is used because - // the OR operator doesn't work well with enumerated types. This indicates - // which fields in context are valid. - int context_validity; -}; - -struct StackFrameARM : public StackFrame { - // A flag for each register we might know. - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_R0 = 1 << 0, - CONTEXT_VALID_R1 = 1 << 1, - CONTEXT_VALID_R2 = 1 << 2, - CONTEXT_VALID_R3 = 1 << 3, - CONTEXT_VALID_R4 = 1 << 4, - CONTEXT_VALID_R5 = 1 << 5, - CONTEXT_VALID_R6 = 1 << 6, - CONTEXT_VALID_R7 = 1 << 7, - CONTEXT_VALID_R8 = 1 << 8, - CONTEXT_VALID_R9 = 1 << 9, - CONTEXT_VALID_R10 = 1 << 10, - CONTEXT_VALID_R11 = 1 << 11, - CONTEXT_VALID_R12 = 1 << 12, - CONTEXT_VALID_R13 = 1 << 13, - CONTEXT_VALID_R14 = 1 << 14, - CONTEXT_VALID_R15 = 1 << 15, - CONTEXT_VALID_ALL = ~CONTEXT_VALID_NONE, - - // Aliases for registers with dedicated or conventional roles. - CONTEXT_VALID_FP = CONTEXT_VALID_R11, - CONTEXT_VALID_SP = CONTEXT_VALID_R13, - CONTEXT_VALID_LR = CONTEXT_VALID_R14, - CONTEXT_VALID_PC = CONTEXT_VALID_R15 - }; - - StackFrameARM() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Return the ContextValidity flag for register rN. - static ContextValidity RegisterValidFlag(int n) { - return ContextValidity(1 << n); - } - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextARM context; - - // For each register in context whose value has been recovered, we set - // the corresponding CONTEXT_VALID_ bit in context_validity. - // - // context_validity's type should actually be ContextValidity, but - // we use int instead because the bitwise inclusive or operator - // yields an int when applied to enum values, and C++ doesn't - // silently convert from ints to enums. - int context_validity; -}; - -struct StackFrameARM64 : public StackFrame { - // A flag for each register we might know. Note that we can't use an enum - // here as there are 33 values to represent. - static const uint64_t CONTEXT_VALID_NONE = 0; - static const uint64_t CONTEXT_VALID_X0 = 1ULL << 0; - static const uint64_t CONTEXT_VALID_X1 = 1ULL << 1; - static const uint64_t CONTEXT_VALID_X2 = 1ULL << 2; - static const uint64_t CONTEXT_VALID_X3 = 1ULL << 3; - static const uint64_t CONTEXT_VALID_X4 = 1ULL << 4; - static const uint64_t CONTEXT_VALID_X5 = 1ULL << 5; - static const uint64_t CONTEXT_VALID_X6 = 1ULL << 6; - static const uint64_t CONTEXT_VALID_X7 = 1ULL << 7; - static const uint64_t CONTEXT_VALID_X8 = 1ULL << 8; - static const uint64_t CONTEXT_VALID_X9 = 1ULL << 9; - static const uint64_t CONTEXT_VALID_X10 = 1ULL << 10; - static const uint64_t CONTEXT_VALID_X11 = 1ULL << 11; - static const uint64_t CONTEXT_VALID_X12 = 1ULL << 12; - static const uint64_t CONTEXT_VALID_X13 = 1ULL << 13; - static const uint64_t CONTEXT_VALID_X14 = 1ULL << 14; - static const uint64_t CONTEXT_VALID_X15 = 1ULL << 15; - static const uint64_t CONTEXT_VALID_X16 = 1ULL << 16; - static const uint64_t CONTEXT_VALID_X17 = 1ULL << 17; - static const uint64_t CONTEXT_VALID_X18 = 1ULL << 18; - static const uint64_t CONTEXT_VALID_X19 = 1ULL << 19; - static const uint64_t CONTEXT_VALID_X20 = 1ULL << 20; - static const uint64_t CONTEXT_VALID_X21 = 1ULL << 21; - static const uint64_t CONTEXT_VALID_X22 = 1ULL << 22; - static const uint64_t CONTEXT_VALID_X23 = 1ULL << 23; - static const uint64_t CONTEXT_VALID_X24 = 1ULL << 24; - static const uint64_t CONTEXT_VALID_X25 = 1ULL << 25; - static const uint64_t CONTEXT_VALID_X26 = 1ULL << 26; - static const uint64_t CONTEXT_VALID_X27 = 1ULL << 27; - static const uint64_t CONTEXT_VALID_X28 = 1ULL << 28; - static const uint64_t CONTEXT_VALID_X29 = 1ULL << 29; - static const uint64_t CONTEXT_VALID_X30 = 1ULL << 30; - static const uint64_t CONTEXT_VALID_X31 = 1ULL << 31; - static const uint64_t CONTEXT_VALID_X32 = 1ULL << 32; - static const uint64_t CONTEXT_VALID_ALL = ~CONTEXT_VALID_NONE; - - // Aliases for registers with dedicated or conventional roles. - static const uint64_t CONTEXT_VALID_FP = CONTEXT_VALID_X29; - static const uint64_t CONTEXT_VALID_LR = CONTEXT_VALID_X30; - static const uint64_t CONTEXT_VALID_SP = CONTEXT_VALID_X31; - static const uint64_t CONTEXT_VALID_PC = CONTEXT_VALID_X32; - - StackFrameARM64() : context(), - context_validity(CONTEXT_VALID_NONE) {} - - // Return the validity flag for register xN. - static uint64_t RegisterValidFlag(int n) { - return 1ULL << n; - } - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, the values of nonvolatile registers may be - // present, given sufficient debugging information. Refer to - // context_validity. - MDRawContextARM64 context; - - // For each register in context whose value has been recovered, we set - // the corresponding CONTEXT_VALID_ bit in context_validity. - uint64_t context_validity; -}; - -struct StackFrameMIPS : public StackFrame { - // MIPS callee save registers for o32 ABI (32bit registers) are: - // 1. $s0-$s7, - // 2. $sp, $fp - // 3. $f20-$f31 - // - // The register structure is available at - // http://en.wikipedia.org/wiki/MIPS_architecture#Compiler_register_usage - -#define INDEX_MIPS_REG_S0 MD_CONTEXT_MIPS_REG_S0 // 16 -#define INDEX_MIPS_REG_S7 MD_CONTEXT_MIPS_REG_S7 // 23 -#define INDEX_MIPS_REG_GP MD_CONTEXT_MIPS_REG_GP // 28 -#define INDEX_MIPS_REG_RA MD_CONTEXT_MIPS_REG_RA // 31 -#define INDEX_MIPS_REG_PC 34 -#define SHIFT_MIPS_REG_S0 0 -#define SHIFT_MIPS_REG_GP 8 -#define SHIFT_MIPS_REG_PC 12 - - enum ContextValidity { - CONTEXT_VALID_NONE = 0, - CONTEXT_VALID_S0 = 1 << 0, // $16 - CONTEXT_VALID_S1 = 1 << 1, // $17 - CONTEXT_VALID_S2 = 1 << 2, // $18 - CONTEXT_VALID_S3 = 1 << 3, // $19 - CONTEXT_VALID_S4 = 1 << 4, // $20 - CONTEXT_VALID_S5 = 1 << 5, // $21 - CONTEXT_VALID_S6 = 1 << 6, // $22 - CONTEXT_VALID_S7 = 1 << 7, // $23 - // GP is not calee-save for o32 abi. - CONTEXT_VALID_GP = 1 << 8, // $28 - CONTEXT_VALID_SP = 1 << 9, // $29 - CONTEXT_VALID_FP = 1 << 10, // $30 - CONTEXT_VALID_RA = 1 << 11, // $31 - CONTEXT_VALID_PC = 1 << 12, // $34 - CONTEXT_VALID_ALL = ~CONTEXT_VALID_NONE - }; - - // Return the ContextValidity flag for register rN. - static ContextValidity RegisterValidFlag(int n) { - if (n >= INDEX_MIPS_REG_S0 && n <= INDEX_MIPS_REG_S7) - return ContextValidity(1 << (n - INDEX_MIPS_REG_S0 + SHIFT_MIPS_REG_S0)); - else if (n >= INDEX_MIPS_REG_GP && n <= INDEX_MIPS_REG_RA) - return ContextValidity(1 << (n - INDEX_MIPS_REG_GP + SHIFT_MIPS_REG_GP)); - else if (n == INDEX_MIPS_REG_PC) - return ContextValidity(1 << SHIFT_MIPS_REG_PC); - - return CONTEXT_VALID_NONE; - } - - StackFrameMIPS() : context(), context_validity(CONTEXT_VALID_NONE) {} - - // Register state. This is only fully valid for the topmost frame in a - // stack. In other frames, which registers are present depends on what - // debugging information were available. Refer to 'context_validity' below. - MDRawContextMIPS context; - - // For each register in context whose value has been recovered, - // the corresponding CONTEXT_VALID_ bit in 'context_validity' is set. - // - // context_validity's type should actually be ContextValidity, but - // type int is used instead because the bitwise inclusive or operator - // yields an int when applied to enum values, and C++ doesn't - // silently convert from ints to enums. - int context_validity; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_symbolizer.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_symbolizer.h deleted file mode 100644 index 074907cb1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stack_frame_symbolizer.h +++ /dev/null @@ -1,108 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Helper class that encapsulates the logic of how symbol supplier interacts -// with source line resolver to fill stack frame information. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/code_module.h" - -namespace google_breakpad { -class CFIFrameInfo; -class CodeModules; -class SymbolSupplier; -class SourceLineResolverInterface; -struct StackFrame; -struct SystemInfo; -struct WindowsFrameInfo; - -class StackFrameSymbolizer { - public: - enum SymbolizerResult { - // Symbol data was found and successfully loaded in resolver. - // This does NOT guarantee source line info is found within symbol file. - kNoError, - // This indicates non-critical error, such as, no code module found for - // frame's instruction, no symbol file, or resolver failed to load symbol. - kError, - // This indicates error for which stack walk should be interrupted - // and retried in future. - kInterrupt, - // Symbol data was found and loaded in resolver however some corruptions - // were detected. - kWarningCorruptSymbols, - }; - - StackFrameSymbolizer(SymbolSupplier* supplier, - SourceLineResolverInterface* resolver); - - virtual ~StackFrameSymbolizer() { } - - // Encapsulate the step of resolving source line info for a stack frame. - // "frame" must not be NULL. - virtual SymbolizerResult FillSourceLineInfo(const CodeModules* modules, - const SystemInfo* system_info, - StackFrame* stack_frame); - - virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame); - - virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame); - - // Reset internal (locally owned) data as if the helper is re-instantiated. - // A typical case is to call Reset() after processing an individual report - // before start to process next one, in order to reset internal information - // about missing symbols found so far. - virtual void Reset() { no_symbol_modules_.clear(); } - - // Returns true if there is valid implementation for stack symbolization. - virtual bool HasImplementation() { return resolver_ && supplier_; } - - SourceLineResolverInterface* resolver() { return resolver_; } - SymbolSupplier* supplier() { return supplier_; } - - protected: - SymbolSupplier* supplier_; - SourceLineResolverInterface* resolver_; - // A list of modules known to have symbols missing. This helps avoid - // repeated lookups for the missing symbols within one minidump. - std::set no_symbol_modules_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h deleted file mode 100644 index a1bd3e7fe..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker.h: Generic stackwalker. -// -// The Stackwalker class is an abstract base class providing common generic -// methods that apply to stacks from all systems. Specific implementations -// will extend this class by providing GetContextFrame and GetCallerFrame -// methods to fill in system-specific data in a StackFrame structure. -// Stackwalker assembles these StackFrame strucutres into a CallStack. -// -// Author: Mark Mentovai - - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ - -#include -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" - -namespace google_breakpad { - -class CallStack; -class DumpContext; -class StackFrameSymbolizer; - -using std::set; -using std::vector; - -class Stackwalker { - public: - virtual ~Stackwalker() {} - - // Populates the given CallStack by calling GetContextFrame and - // GetCallerFrame. The frames are further processed to fill all available - // data. Returns true if the stackwalk completed, or false if it was - // interrupted by SymbolSupplier::GetSymbolFile(). - // Upon return, |modules_without_symbols| will be populated with pointers to - // the code modules (CodeModule*) that DON'T have symbols. - // |modules_with_corrupt_symbols| will be populated with pointers to the - // modules which have corrupt symbols. |modules_without_symbols| and - // |modules_with_corrupt_symbols| DO NOT take ownership of the code modules. - // The lifetime of these code modules is the same as the lifetime of the - // CodeModules passed to the StackWalker constructor (which currently - // happens to be the lifetime of the Breakpad's ProcessingState object). - // There is a check for duplicate modules so no duplicates are expected. - bool Walk(CallStack* stack, - vector* modules_without_symbols, - vector* modules_with_corrupt_symbols); - - // Returns a new concrete subclass suitable for the CPU that a stack was - // generated on, according to the CPU type indicated by the context - // argument. If no suitable concrete subclass exists, returns NULL. - static Stackwalker* StackwalkerForCPU( - const SystemInfo* system_info, - DumpContext* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper); - - static void set_max_frames(uint32_t max_frames) { - max_frames_ = max_frames; - max_frames_set_ = true; - } - static uint32_t max_frames() { return max_frames_; } - - static void set_max_frames_scanned(uint32_t max_frames_scanned) { - max_frames_scanned_ = max_frames_scanned; - } - - protected: - // system_info identifies the operating system, NULL or empty if unknown. - // memory identifies a MemoryRegion that provides the stack memory - // for the stack to walk. modules, if non-NULL, is a CodeModules - // object that is used to look up which code module each stack frame is - // associated with. frame_symbolizer is a StackFrameSymbolizer object that - // encapsulates the logic of how source line resolver interacts with symbol - // supplier to symbolize stack frame and look up caller frame information - // (see stack_frame_symbolizer.h). - // frame_symbolizer MUST NOT be NULL (asserted). - Stackwalker(const SystemInfo* system_info, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - // This can be used to filter out potential return addresses when - // the stack walker resorts to stack scanning. - // Returns true if any of: - // * This address is within a loaded module, but we don't have symbols - // for that module. - // * This address is within a loaded module for which we have symbols, - // and falls inside a function in that module. - // Returns false otherwise. - bool InstructionAddressSeemsValid(uint64_t address); - - // The default number of words to search through on the stack - // for a return address. - static const int kRASearchWords; - - template - bool ScanForReturnAddress(InstructionType location_start, - InstructionType* location_found, - InstructionType* ip_found, - bool is_context_frame) { - // When searching for the caller of the context frame, - // allow the scanner to look farther down the stack. - const int search_words = is_context_frame ? - kRASearchWords * 4 : - kRASearchWords; - - return ScanForReturnAddress(location_start, location_found, ip_found, - search_words); - } - - // Scan the stack starting at location_start, looking for an address - // that looks like a valid instruction pointer. Addresses must - // 1) be contained in the current stack memory - // 2) pass the checks in InstructionAddressSeemsValid - // - // Returns true if a valid-looking instruction pointer was found. - // When returning true, sets location_found to the address at which - // the value was found, and ip_found to the value contained at that - // location in memory. - template - bool ScanForReturnAddress(InstructionType location_start, - InstructionType* location_found, - InstructionType* ip_found, - int searchwords) { - for (InstructionType location = location_start; - location <= location_start + searchwords * sizeof(InstructionType); - location += sizeof(InstructionType)) { - InstructionType ip; - if (!memory_->GetMemoryAtAddress(location, &ip)) - break; - - if (modules_ && modules_->GetModuleForAddress(ip) && - InstructionAddressSeemsValid(ip)) { - *ip_found = ip; - *location_found = location; - return true; - } - } - // nothing found - return false; - } - - // Information about the system that produced the minidump. Subclasses - // and the SymbolSupplier may find this information useful. - const SystemInfo* system_info_; - - // The stack memory to walk. Subclasses will require this region to - // get information from the stack. - MemoryRegion* memory_; - - // A list of modules, for populating each StackFrame's module information. - // This field is optional and may be NULL. - const CodeModules* modules_; - - protected: - // The StackFrameSymbolizer implementation. - StackFrameSymbolizer* frame_symbolizer_; - - private: - // Obtains the context frame, the innermost called procedure in a stack - // trace. Returns NULL on failure. GetContextFrame allocates a new - // StackFrame (or StackFrame subclass), ownership of which is taken by - // the caller. - virtual StackFrame* GetContextFrame() = 0; - - // Obtains a caller frame. Each call to GetCallerFrame should return the - // frame that called the last frame returned by GetContextFrame or - // GetCallerFrame. To aid this purpose, stack contains the CallStack - // made of frames that have already been walked. GetCallerFrame should - // return NULL on failure or when there are no more caller frames (when - // the end of the stack has been reached). GetCallerFrame allocates a new - // StackFrame (or StackFrame subclass), ownership of which is taken by - // the caller. |stack_scan_allowed| controls whether stack scanning is - // an allowable frame-recovery method, since it is desirable to be able to - // disable stack scanning in performance-critical use cases. - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) = 0; - - // The maximum number of frames Stackwalker will walk through. - // This defaults to 1024 to prevent infinite loops. - static uint32_t max_frames_; - - // Keep track of whether max_frames_ has been set by the user, since - // it affects whether or not an error message is printed in the case - // where an unwind got stopped by the limit. - static bool max_frames_set_; - - // The maximum number of stack-scanned and otherwise untrustworthy - // frames allowed. Stack-scanning can be expensive, so the option to - // disable or limit it is helpful in cases where unwind performance is - // important. This defaults to 1024, the same as max_frames_. - static uint32_t max_frames_scanned_; -}; - -} // namespace google_breakpad - - -#endif // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/symbol_supplier.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/symbol_supplier.h deleted file mode 100644 index a042081f3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/symbol_supplier.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The caller may implement the SymbolSupplier abstract base class -// to provide symbols for a given module. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__ - -#include -#include "common/using_std_string.h" - -namespace google_breakpad { - -class CodeModule; -struct SystemInfo; - -class SymbolSupplier { - public: - // Result type for GetSymbolFile - enum SymbolResult { - // no symbols were found, but continue processing - NOT_FOUND, - - // symbols were found, and the path has been placed in symbol_file - FOUND, - - // stops processing the minidump immediately - INTERRUPT - }; - - virtual ~SymbolSupplier() {} - - // Retrieves the symbol file for the given CodeModule, placing the - // path in symbol_file if successful. system_info contains strings - // identifying the operating system and CPU; SymbolSupplier may use - // to help locate the symbol file. system_info may be NULL or its - // fields may be empty if these values are unknown. symbol_file - // must be a pointer to a valid string - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file) = 0; - // Same as above, except also places symbol data into symbol_data. - // If symbol_data is NULL, the data is not returned. - // TODO(nealsid) Once we have symbol data caching behavior implemented - // investigate making all symbol suppliers implement all methods, - // and make this pure virtual - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data) = 0; - - // Same as above, except allocates data buffer on heap and then places the - // symbol data into the buffer as C-string. - // SymbolSupplier is responsible for deleting the data buffer. After the call - // to GetCStringSymbolData(), the caller should call FreeSymbolData(const - // Module *module) once the data buffer is no longer needed. - // If symbol_data is not NULL, symbol supplier won't return FOUND unless it - // returns a valid buffer in symbol_data, e.g., returns INTERRUPT on memory - // allocation failure. - virtual SymbolResult GetCStringSymbolData(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size) = 0; - - // Frees the data buffer allocated for the module in GetCStringSymbolData. - virtual void FreeSymbolData(const CodeModule *module) = 0; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_SYMBOL_SUPPLIER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/system_info.h b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/system_info.h deleted file mode 100644 index 8d2f60be4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/system_info.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// system_info.h: Information about the system that was running a program -// when a crash report was produced. -// -// Author: Mark Mentovai - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__ -#define GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__ - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -struct SystemInfo { - public: - SystemInfo() : os(), os_short(), os_version(), cpu(), cpu_info(), - cpu_count(0), gl_version(), gl_vendor(), gl_renderer() {} - - // Resets the SystemInfo object to its default values. - void Clear() { - os.clear(); - os_short.clear(); - os_version.clear(); - cpu.clear(); - cpu_info.clear(); - cpu_count = 0; - gl_version.clear(); - gl_vendor.clear(); - gl_renderer.clear(); - } - - // A string identifying the operating system, such as "Windows NT", - // "Mac OS X", or "Linux". If the information is present in the dump but - // its value is unknown, this field will contain a numeric value. If - // the information is not present in the dump, this field will be empty. - string os; - - // A short form of the os string, using lowercase letters and no spaces, - // suitable for use in a filesystem. Possible values include "windows", - // "mac", "linux" and "nacl". Empty if the information is not present - // in the dump or if the OS given by the dump is unknown. The values - // stored in this field should match those used by - // MinidumpSystemInfo::GetOS. - string os_short; - - // A string identifying the version of the operating system, such as - // "5.1.2600 Service Pack 2" or "10.4.8 8L2127". If the dump does not - // contain this information, this field will be empty. - string os_version; - - // A string identifying the basic CPU family, such as "x86" or "ppc". - // If this information is present in the dump but its value is unknown, - // this field will contain a numeric value. If the information is not - // present in the dump, this field will be empty. The values stored in - // this field should match those used by MinidumpSystemInfo::GetCPU. - string cpu; - - // A string further identifying the specific CPU, such as - // "GenuineIntel level 6 model 13 stepping 8". If the information is not - // present in the dump, or additional identifying information is not - // defined for the CPU family, this field will be empty. - string cpu_info; - - // The number of processors in the system. Will be greater than one for - // multi-core systems. - int cpu_count; - - // The GPU information. Currently only populated in microdumps. - string gl_version; - string gl_vendor; - string gl_renderer; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_SYSTEM_INFO_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h deleted file mode 100644 index 251c44781..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// address_map-inl.h: Address map implementation. -// -// See address_map.h for documentation. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_ADDRESS_MAP_INL_H__ -#define PROCESSOR_ADDRESS_MAP_INL_H__ - -#include "processor/address_map.h" - -#include - -#include "processor/logging.h" - -namespace google_breakpad { - -template -bool AddressMap::Store(const AddressType &address, - const EntryType &entry) { - // Ensure that the specified address doesn't conflict with something already - // in the map. - if (map_.find(address) != map_.end()) { - BPLOG(INFO) << "Store failed, address " << HexString(address) << - " is already present"; - return false; - } - - map_.insert(MapValue(address, entry)); - return true; -} - -template -bool AddressMap::Retrieve( - const AddressType &address, - EntryType *entry, AddressType *entry_address) const { - BPLOG_IF(ERROR, !entry) << "AddressMap::Retrieve requires |entry|"; - assert(entry); - - // upper_bound gives the first element whose key is greater than address, - // but we want the first element whose key is less than or equal to address. - // Decrement the iterator to get there, but not if the upper_bound already - // points to the beginning of the map - in that case, address is lower than - // the lowest stored key, so return false. - MapConstIterator iterator = map_.upper_bound(address); - if (iterator == map_.begin()) - return false; - --iterator; - - *entry = iterator->second; - if (entry_address) - *entry_address = iterator->first; - - return true; -} - -template -void AddressMap::Clear() { - map_.clear(); -} - -} // namespace google_breakpad - -#endif // PROCESSOR_ADDRESS_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/address_map.h b/toolkit/crashreporter/google-breakpad/src/processor/address_map.h deleted file mode 100644 index 2972cbb9f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/address_map.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// address_map.h: Address maps. -// -// An address map contains a set of objects keyed by address. Objects are -// retrieved from the map by returning the object with the highest key less -// than or equal to the lookup key. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_ADDRESS_MAP_H__ -#define PROCESSOR_ADDRESS_MAP_H__ - -#include - -namespace google_breakpad { - -// Forward declarations (for later friend declarations). -template class AddressMapSerializer; - -template -class AddressMap { - public: - AddressMap() : map_() {} - - // Inserts an entry into the map. Returns false without storing the entry - // if an entry is already stored in the map at the same address as specified - // by the address argument. - bool Store(const AddressType &address, const EntryType &entry); - - // Locates the entry stored at the highest address less than or equal to - // the address argument. If there is no such range, returns false. The - // entry is returned in entry, which is a required argument. If - // entry_address is not NULL, it will be set to the address that the entry - // was stored at. - bool Retrieve(const AddressType &address, - EntryType *entry, AddressType *entry_address) const; - - // Empties the address map, restoring it to the same state as when it was - // initially created. - void Clear(); - - private: - friend class AddressMapSerializer; - friend class ModuleComparer; - - // Convenience types. - typedef std::map AddressToEntryMap; - typedef typename AddressToEntryMap::const_iterator MapConstIterator; - typedef typename AddressToEntryMap::value_type MapValue; - - // Maps the address of each entry to an EntryType. - AddressToEntryMap map_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_ADDRESS_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/address_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/address_map_unittest.cc deleted file mode 100644 index 9b4095b16..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/address_map_unittest.cc +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// address_map_unittest.cc: Unit tests for AddressMap. -// -// Author: Mark Mentovai - -#include -#include - -#include "processor/address_map-inl.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" - -#define ASSERT_TRUE(condition) \ - if (!(condition)) { \ - fprintf(stderr, "FAIL: %s @ %s:%d\n", #condition, __FILE__, __LINE__); \ - return false; \ - } - -#define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition)) - -#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2)) - -namespace { - -using google_breakpad::AddressMap; -using google_breakpad::linked_ptr; - -// A CountedObject holds an int. A global (not thread safe!) count of -// allocated CountedObjects is maintained to help test memory management. -class CountedObject { - public: - explicit CountedObject(int id) : id_(id) { ++count_; } - ~CountedObject() { --count_; } - - static int count() { return count_; } - int id() const { return id_; } - - private: - static int count_; - int id_; -}; - -int CountedObject::count_; - -typedef int AddressType; -typedef AddressMap< AddressType, linked_ptr > TestMap; - -static bool DoAddressMapTest() { - ASSERT_EQ(CountedObject::count(), 0); - - TestMap test_map; - linked_ptr entry; - AddressType address; - - // Check that a new map is truly empty. - ASSERT_FALSE(test_map.Retrieve(0, &entry, &address)); - ASSERT_FALSE(test_map.Retrieve(INT_MIN, &entry, &address)); - ASSERT_FALSE(test_map.Retrieve(INT_MAX, &entry, &address)); - - // Check that Clear clears the map without leaking. - ASSERT_EQ(CountedObject::count(), 0); - ASSERT_TRUE(test_map.Store(1, - linked_ptr(new CountedObject(0)))); - ASSERT_TRUE(test_map.Retrieve(1, &entry, &address)); - ASSERT_EQ(CountedObject::count(), 1); - test_map.Clear(); - ASSERT_EQ(CountedObject::count(), 1); // still holding entry in this scope - - // Check that a cleared map is truly empty. - ASSERT_FALSE(test_map.Retrieve(0, &entry, &address)); - ASSERT_FALSE(test_map.Retrieve(INT_MIN, &entry, &address)); - ASSERT_FALSE(test_map.Retrieve(INT_MAX, &entry, &address)); - - // Check a single-element map. - ASSERT_TRUE(test_map.Store(10, - linked_ptr(new CountedObject(1)))); - ASSERT_FALSE(test_map.Retrieve(9, &entry, &address)); - ASSERT_TRUE(test_map.Retrieve(10, &entry, &address)); - ASSERT_EQ(CountedObject::count(), 1); - ASSERT_EQ(entry->id(), 1); - ASSERT_EQ(address, 10); - ASSERT_TRUE(test_map.Retrieve(11, &entry, &address)); - ASSERT_TRUE(test_map.Retrieve(11, &entry, NULL)); // NULL ok here - - // Add some more elements. - ASSERT_TRUE(test_map.Store(5, - linked_ptr(new CountedObject(2)))); - ASSERT_EQ(CountedObject::count(), 2); - ASSERT_TRUE(test_map.Store(20, - linked_ptr(new CountedObject(3)))); - ASSERT_TRUE(test_map.Store(15, - linked_ptr(new CountedObject(4)))); - ASSERT_FALSE(test_map.Store(10, - linked_ptr(new CountedObject(5)))); // already in map - ASSERT_TRUE(test_map.Store(16, - linked_ptr(new CountedObject(6)))); - ASSERT_TRUE(test_map.Store(14, - linked_ptr(new CountedObject(7)))); - - // Nothing was stored with a key under 5. Don't use ASSERT inside loops - // because it won't show exactly which key/entry/address failed. - for (AddressType key = 0; key < 5; ++key) { - if (test_map.Retrieve(key, &entry, &address)) { - fprintf(stderr, - "FAIL: retrieve %d expected false observed true @ %s:%d\n", - key, __FILE__, __LINE__); - return false; - } - } - - // Check everything that was stored. - const int id_verify[] = { 0, 0, 0, 0, 0, // unused - 2, 2, 2, 2, 2, // 5 - 9 - 1, 1, 1, 1, 7, // 10 - 14 - 4, 6, 6, 6, 6, // 15 - 19 - 3, 3, 3, 3, 3, // 20 - 24 - 3, 3, 3, 3, 3 }; // 25 - 29 - const AddressType address_verify[] = { 0, 0, 0, 0, 0, // unused - 5, 5, 5, 5, 5, // 5 - 9 - 10, 10, 10, 10, 14, // 10 - 14 - 15, 16, 16, 16, 16, // 15 - 19 - 20, 20, 20, 20, 20, // 20 - 24 - 20, 20, 20, 20, 20 }; // 25 - 29 - - for (AddressType key = 5; key < 30; ++key) { - if (!test_map.Retrieve(key, &entry, &address)) { - fprintf(stderr, - "FAIL: retrieve %d expected true observed false @ %s:%d\n", - key, __FILE__, __LINE__); - return false; - } - if (entry->id() != id_verify[key]) { - fprintf(stderr, - "FAIL: retrieve %d expected entry %d observed %d @ %s:%d\n", - key, id_verify[key], entry->id(), __FILE__, __LINE__); - return false; - } - if (address != address_verify[key]) { - fprintf(stderr, - "FAIL: retrieve %d expected address %d observed %d @ %s:%d\n", - key, address_verify[key], address, __FILE__, __LINE__); - return false; - } - } - - // The stored objects should still be in the map. - ASSERT_EQ(CountedObject::count(), 6); - - return true; -} - -static bool RunTests() { - if (!DoAddressMapTest()) - return false; - - // Leak check. - ASSERT_EQ(CountedObject::count(), 0); - - return true; -} - -} // namespace - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h b/toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h deleted file mode 100644 index 0f7b3e431..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// basic_code_module.h: Carries information about code modules that are loaded -// into a process. -// -// This is a basic concrete implementation of CodeModule. It cannot be -// instantiated directly, only based on other objects that implement -// the CodeModule interface. It exists to provide a CodeModule implementation -// a place to store information when the life of the original object (such as -// a MinidumpModule) cannot be guaranteed. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_BASIC_CODE_MODULE_H__ -#define PROCESSOR_BASIC_CODE_MODULE_H__ - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/code_module.h" - -namespace google_breakpad { - -class BasicCodeModule : public CodeModule { - public: - // Creates a new BasicCodeModule given any existing CodeModule - // implementation. This is useful to make a copy of the data relevant to - // the CodeModule interface without requiring all of the resources that - // other CodeModule implementations may require. - explicit BasicCodeModule(const CodeModule *that) - : base_address_(that->base_address()), - size_(that->size()), - shrink_down_delta_(that->shrink_down_delta()), - code_file_(that->code_file()), - code_identifier_(that->code_identifier()), - debug_file_(that->debug_file()), - debug_identifier_(that->debug_identifier()), - version_(that->version()) {} - - BasicCodeModule(uint64_t base_address, uint64_t size, - const string &code_file, - const string &code_identifier, - const string &debug_file, - const string &debug_identifier, - const string &version) - : base_address_(base_address), - size_(size), - shrink_down_delta_(0), - code_file_(code_file), - code_identifier_(code_identifier), - debug_file_(debug_file), - debug_identifier_(debug_identifier), - version_(version) - {} - virtual ~BasicCodeModule() {} - - // See code_module.h for descriptions of these methods and the associated - // members. - virtual uint64_t base_address() const { return base_address_; } - virtual uint64_t size() const { return size_; } - virtual uint64_t shrink_down_delta() const { return shrink_down_delta_; } - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta) { - shrink_down_delta_ = shrink_down_delta; - } - virtual string code_file() const { return code_file_; } - virtual string code_identifier() const { return code_identifier_; } - virtual string debug_file() const { return debug_file_; } - virtual string debug_identifier() const { return debug_identifier_; } - virtual string version() const { return version_; } - virtual CodeModule* Copy() const { return new BasicCodeModule(this); } - - private: - uint64_t base_address_; - uint64_t size_; - uint64_t shrink_down_delta_; - string code_file_; - string code_identifier_; - string debug_file_; - string debug_identifier_; - string version_; - - // Disallow copy constructor and assignment operator. - BasicCodeModule(const BasicCodeModule &that); - void operator=(const BasicCodeModule &that); -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_BASIC_CODE_MODULE_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.cc b/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.cc deleted file mode 100644 index 48d971677..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// basic_code_modules.cc: Contains all of the CodeModule objects that -// were loaded into a single process. -// -// See basic_code_modules.h for documentation. -// -// Author: Mark Mentovai - -#include "processor/basic_code_modules.h" - -#include - -#include - -#include "google_breakpad/processor/code_module.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" -#include "processor/range_map-inl.h" - -namespace google_breakpad { - -using std::vector; - -BasicCodeModules::BasicCodeModules(const CodeModules *that) - : main_address_(0), map_() { - BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires " - "|that|"; - assert(that); - - map_.SetEnableShrinkDown(that->IsModuleShrinkEnabled()); - - const CodeModule *main_module = that->GetMainModule(); - if (main_module) - main_address_ = main_module->base_address(); - - unsigned int count = that->module_count(); - for (unsigned int i = 0; i < count; ++i) { - // Make a copy of the module and insert it into the map. Use - // GetModuleAtIndex because ordering is unimportant when slurping the - // entire list, and GetModuleAtIndex may be faster than - // GetModuleAtSequence. - linked_ptr module(that->GetModuleAtIndex(i)->Copy()); - if (!map_.StoreRange(module->base_address(), module->size(), module)) { - BPLOG(ERROR) << "Module " << module->code_file() - << " could not be stored"; - } - } - - // Report modules with shrunk ranges. - for (unsigned int i = 0; i < count; ++i) { - linked_ptr module(that->GetModuleAtIndex(i)->Copy()); - uint64_t delta = 0; - if (map_.RetrieveRange(module->base_address() + module->size() - 1, - &module, NULL /* base */, &delta, NULL /* size */) && - delta > 0) { - BPLOG(INFO) << "The range for module " << module->code_file() - << " was shrunk down by " << HexString(delta) << " bytes."; - linked_ptr shrunk_range_module(module->Copy()); - shrunk_range_module->SetShrinkDownDelta(delta); - shrunk_range_modules_.push_back(shrunk_range_module); - } - } - - // TODO(ivanpe): Report modules with conflicting ranges. The list of such - // modules should be copied from |that|. -} - -BasicCodeModules::BasicCodeModules() : main_address_(0), map_() { } - -BasicCodeModules::~BasicCodeModules() { -} - -unsigned int BasicCodeModules::module_count() const { - return map_.GetCount(); -} - -const CodeModule* BasicCodeModules::GetModuleForAddress( - uint64_t address) const { - linked_ptr module; - if (!map_.RetrieveRange(address, &module, NULL /* base */, NULL /* delta */, - NULL /* size */)) { - BPLOG(INFO) << "No module at " << HexString(address); - return NULL; - } - - return module.get(); -} - -const CodeModule* BasicCodeModules::GetMainModule() const { - return GetModuleForAddress(main_address_); -} - -const CodeModule* BasicCodeModules::GetModuleAtSequence( - unsigned int sequence) const { - linked_ptr module; - if (!map_.RetrieveRangeAtIndex(sequence, &module, NULL /* base */, - NULL /* delta */, NULL /* size */)) { - BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence; - return NULL; - } - - return module.get(); -} - -const CodeModule* BasicCodeModules::GetModuleAtIndex( - unsigned int index) const { - // This class stores everything in a RangeMap, without any more-efficient - // way to walk the list of CodeModule objects. Implement GetModuleAtIndex - // using GetModuleAtSequence, which meets all of the requirements, and - // in addition, guarantees ordering. - return GetModuleAtSequence(index); -} - -const CodeModules* BasicCodeModules::Copy() const { - return new BasicCodeModules(this); -} - -vector > -BasicCodeModules::GetShrunkRangeModules() const { - return shrunk_range_modules_; -} - -bool BasicCodeModules::IsModuleShrinkEnabled() const { - return map_.IsShrinkDownEnabled(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h b/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h deleted file mode 100644 index 50f8a03d8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// basic_code_modules.h: Contains all of the CodeModule objects that -// were loaded into a single process. -// -// This is a basic concrete implementation of CodeModules. It cannot be -// instantiated directly, only based on other objects that implement -// the CodeModules interface. It exists to provide a CodeModules -// implementation a place to store information when the life of the original -// object (such as a MinidumpModuleList) cannot be guaranteed. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_BASIC_CODE_MODULES_H__ -#define PROCESSOR_BASIC_CODE_MODULES_H__ - -#include - -#include - -#include "google_breakpad/processor/code_modules.h" -#include "processor/linked_ptr.h" -#include "processor/range_map.h" - -namespace google_breakpad { - -class BasicCodeModules : public CodeModules { - public: - // Creates a new BasicCodeModules object given any existing CodeModules - // implementation. This is useful to make a copy of the data relevant to - // the CodeModules and CodeModule interfaces without requiring all of the - // resources that other implementations may require. A copy will be - // made of each contained CodeModule using CodeModule::Copy. - explicit BasicCodeModules(const CodeModules *that); - - virtual ~BasicCodeModules(); - - // See code_modules.h for descriptions of these methods. - virtual unsigned int module_count() const; - virtual const CodeModule* GetModuleForAddress(uint64_t address) const; - virtual const CodeModule* GetMainModule() const; - virtual const CodeModule* GetModuleAtSequence(unsigned int sequence) const; - virtual const CodeModule* GetModuleAtIndex(unsigned int index) const; - virtual const CodeModules* Copy() const; - virtual std::vector > - GetShrunkRangeModules() const; - virtual bool IsModuleShrinkEnabled() const; - - protected: - BasicCodeModules(); - - // The base address of the main module. - uint64_t main_address_; - - // The map used to contain each CodeModule, keyed by each CodeModule's - // address range. - RangeMap > map_; - - // A vector of all CodeModules that were shrunk downs due to - // address range conflicts. - std::vector > shrunk_range_modules_; - - private: - // Disallow copy constructor and assignment operator. - BasicCodeModules(const BasicCodeModules &that); - void operator=(const BasicCodeModules &that); -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_BASIC_CODE_MODULES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver.cc b/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver.cc deleted file mode 100644 index aa66e1599..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver.cc +++ /dev/null @@ -1,612 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// basic_source_line_resolver.cc: BasicSourceLineResolver implementation. -// -// See basic_source_line_resolver.h and basic_source_line_resolver_types.h -// for documentation. - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "processor/basic_source_line_resolver_types.h" -#include "processor/module_factory.h" - -#include "processor/tokenize.h" - -using std::map; -using std::vector; -using std::make_pair; - -namespace google_breakpad { - -#ifdef _WIN32 -#ifdef _MSC_VER -#define strtok_r strtok_s -#endif -#define strtoull _strtoui64 -#endif - -static const char *kWhitespace = " \r\n"; -static const int kMaxErrorsPrinted = 5; -static const int kMaxErrorsBeforeBailing = 100; - -BasicSourceLineResolver::BasicSourceLineResolver() : - SourceLineResolverBase(new BasicModuleFactory) { } - -// static -void BasicSourceLineResolver::Module::LogParseError( - const string &message, - int line_number, - int *num_errors) { - if (++(*num_errors) <= kMaxErrorsPrinted) { - if (line_number > 0) { - BPLOG(ERROR) << "Line " << line_number << ": " << message; - } else { - BPLOG(ERROR) << message; - } - } -} - -bool BasicSourceLineResolver::Module::LoadMapFromMemory( - char *memory_buffer, - size_t memory_buffer_size) { - linked_ptr cur_func; - int line_number = 0; - int num_errors = 0; - char *save_ptr; - - // If the length is 0, we can still pretend we have a symbol file. This is - // for scenarios that want to test symbol lookup, but don't necessarily care - // if certain modules do not have any information, like system libraries. - if (memory_buffer_size == 0) { - return true; - } - - // Make sure the last character is null terminator. - size_t last_null_terminator = memory_buffer_size - 1; - if (memory_buffer[last_null_terminator] != '\0') { - memory_buffer[last_null_terminator] = '\0'; - } - - // Skip any null terminators at the end of the memory buffer, and make sure - // there are no other null terminators in the middle of the memory buffer. - bool has_null_terminator_in_the_middle = false; - while (last_null_terminator > 0 && - memory_buffer[last_null_terminator - 1] == '\0') { - last_null_terminator--; - } - for (size_t i = 0; i < last_null_terminator; i++) { - if (memory_buffer[i] == '\0') { - memory_buffer[i] = '_'; - has_null_terminator_in_the_middle = true; - } - } - if (has_null_terminator_in_the_middle) { - LogParseError( - "Null terminator is not expected in the middle of the symbol data", - line_number, - &num_errors); - } - - char *buffer; - buffer = strtok_r(memory_buffer, "\r\n", &save_ptr); - - while (buffer != NULL) { - ++line_number; - - if (strncmp(buffer, "FILE ", 5) == 0) { - if (!ParseFile(buffer)) { - LogParseError("ParseFile on buffer failed", line_number, &num_errors); - } - } else if (strncmp(buffer, "STACK ", 6) == 0) { - if (!ParseStackInfo(buffer)) { - LogParseError("ParseStackInfo failed", line_number, &num_errors); - } - } else if (strncmp(buffer, "FUNC ", 5) == 0) { - cur_func.reset(ParseFunction(buffer)); - if (!cur_func.get()) { - LogParseError("ParseFunction failed", line_number, &num_errors); - } else { - // StoreRange will fail if the function has an invalid address or size. - // We'll silently ignore this, the function and any corresponding lines - // will be destroyed when cur_func is released. - functions_.StoreRange(cur_func->address, cur_func->size, cur_func); - } - } else if (strncmp(buffer, "PUBLIC ", 7) == 0) { - // Clear cur_func: public symbols don't contain line number information. - cur_func.reset(); - - if (!ParsePublicSymbol(buffer)) { - LogParseError("ParsePublicSymbol failed", line_number, &num_errors); - } - } else if (strncmp(buffer, "MODULE ", 7) == 0) { - // Ignore these. They're not of any use to BasicSourceLineResolver, - // which is fed modules by a SymbolSupplier. These lines are present to - // aid other tools in properly placing symbol files so that they can - // be accessed by a SymbolSupplier. - // - // MODULE - } else if (strncmp(buffer, "INFO ", 5) == 0) { - // Ignore these as well, they're similarly just for housekeeping. - // - // INFO CODE_ID - } else { - if (!cur_func.get()) { - LogParseError("Found source line data without a function", - line_number, &num_errors); - } else { - Line *line = ParseLine(buffer); - if (!line) { - LogParseError("ParseLine failed", line_number, &num_errors); - } else { - cur_func->lines.StoreRange(line->address, line->size, - linked_ptr(line)); - } - } - } - if (num_errors > kMaxErrorsBeforeBailing) { - break; - } - buffer = strtok_r(NULL, "\r\n", &save_ptr); - } - is_corrupt_ = num_errors > 0; - return true; -} - -void BasicSourceLineResolver::Module::LookupAddress(StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - - // First, look for a FUNC record that covers address. Use - // RetrieveNearestRange instead of RetrieveRange so that, if there - // is no such function, we can use the next function to bound the - // extent of the PUBLIC symbol we find, below. This does mean we - // need to check that address indeed falls within the function we - // find; do the range comparison in an overflow-friendly way. - linked_ptr func; - linked_ptr public_symbol; - MemAddr function_base; - MemAddr function_size; - MemAddr public_address; - if (functions_.RetrieveNearestRange(address, &func, &function_base, - NULL /* delta */, &function_size) && - address >= function_base && address - function_base < function_size) { - frame->function_name = func->name; - frame->function_base = frame->module->base_address() + function_base; - - linked_ptr line; - MemAddr line_base; - if (func->lines.RetrieveRange(address, &line, &line_base, NULL /* delta */, - NULL /* size */)) { - FileMap::const_iterator it = files_.find(line->source_file_id); - if (it != files_.end()) { - frame->source_file_name = files_.find(line->source_file_id)->second; - } - frame->source_line = line->line; - frame->source_line_base = frame->module->base_address() + line_base; - } - } else if (public_symbols_.Retrieve(address, - &public_symbol, &public_address) && - (!func.get() || public_address > function_base)) { - frame->function_name = public_symbol->name; - frame->function_base = frame->module->base_address() + public_address; - } -} - -WindowsFrameInfo *BasicSourceLineResolver::Module::FindWindowsFrameInfo( - const StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - scoped_ptr result(new WindowsFrameInfo()); - - // We only know about WindowsFrameInfo::STACK_INFO_FRAME_DATA and - // WindowsFrameInfo::STACK_INFO_FPO. Prefer them in this order. - // WindowsFrameInfo::STACK_INFO_FRAME_DATA is the newer type that - // includes its own program string. - // WindowsFrameInfo::STACK_INFO_FPO is the older type - // corresponding to the FPO_DATA struct. See stackwalker_x86.cc. - linked_ptr frame_info; - if ((windows_frame_info_[WindowsFrameInfo::STACK_INFO_FRAME_DATA] - .RetrieveRange(address, &frame_info)) - || (windows_frame_info_[WindowsFrameInfo::STACK_INFO_FPO] - .RetrieveRange(address, &frame_info))) { - result->CopyFrom(*frame_info.get()); - return result.release(); - } - - // Even without a relevant STACK line, many functions contain - // information about how much space their parameters consume on the - // stack. Use RetrieveNearestRange instead of RetrieveRange, so that - // we can use the function to bound the extent of the PUBLIC symbol, - // below. However, this does mean we need to check that ADDRESS - // falls within the retrieved function's range; do the range - // comparison in an overflow-friendly way. - linked_ptr function; - MemAddr function_base, function_size; - if (functions_.RetrieveNearestRange(address, &function, &function_base, - NULL /* delta */, &function_size) && - address >= function_base && address - function_base < function_size) { - result->parameter_size = function->parameter_size; - result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE; - return result.release(); - } - - // PUBLIC symbols might have a parameter size. Use the function we - // found above to limit the range the public symbol covers. - linked_ptr public_symbol; - MemAddr public_address; - if (public_symbols_.Retrieve(address, &public_symbol, &public_address) && - (!function.get() || public_address > function_base)) { - result->parameter_size = public_symbol->parameter_size; - } - - return NULL; -} - -CFIFrameInfo *BasicSourceLineResolver::Module::FindCFIFrameInfo( - const StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - MemAddr initial_base, initial_size; - string initial_rules; - - // Find the initial rule whose range covers this address. That - // provides an initial set of register recovery rules. Then, walk - // forward from the initial rule's starting address to frame's - // instruction address, applying delta rules. - if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, &initial_base, - NULL /* delta */, &initial_size)) { - return NULL; - } - - // Create a frame info structure, and populate it with the rules from - // the STACK CFI INIT record. - scoped_ptr rules(new CFIFrameInfo()); - if (!ParseCFIRuleSet(initial_rules, rules.get())) - return NULL; - - // Find the first delta rule that falls within the initial rule's range. - map::const_iterator delta = - cfi_delta_rules_.lower_bound(initial_base); - - // Apply delta rules up to and including the frame's address. - while (delta != cfi_delta_rules_.end() && delta->first <= address) { - ParseCFIRuleSet(delta->second, rules.get()); - delta++; - } - - return rules.release(); -} - -bool BasicSourceLineResolver::Module::ParseFile(char *file_line) { - long index; - char *filename; - if (SymbolParseHelper::ParseFile(file_line, &index, &filename)) { - files_.insert(make_pair(index, string(filename))); - return true; - } - return false; -} - -BasicSourceLineResolver::Function* -BasicSourceLineResolver::Module::ParseFunction(char *function_line) { - uint64_t address; - uint64_t size; - long stack_param_size; - char *name; - if (SymbolParseHelper::ParseFunction(function_line, &address, &size, - &stack_param_size, &name)) { - return new Function(name, address, size, stack_param_size); - } - return NULL; -} - -BasicSourceLineResolver::Line* BasicSourceLineResolver::Module::ParseLine( - char *line_line) { - uint64_t address; - uint64_t size; - long line_number; - long source_file; - - if (SymbolParseHelper::ParseLine(line_line, &address, &size, &line_number, - &source_file)) { - return new Line(address, size, source_file, line_number); - } - return NULL; -} - -bool BasicSourceLineResolver::Module::ParsePublicSymbol(char *public_line) { - uint64_t address; - long stack_param_size; - char *name; - - if (SymbolParseHelper::ParsePublicSymbol(public_line, &address, - &stack_param_size, &name)) { - // A few public symbols show up with an address of 0. This has been seen - // in the dumped output of ntdll.pdb for symbols such as _CIlog, _CIpow, - // RtlDescribeChunkLZNT1, and RtlReserveChunkLZNT1. They would conflict - // with one another if they were allowed into the public_symbols_ map, - // but since the address is obviously invalid, gracefully accept them - // as input without putting them into the map. - if (address == 0) { - return true; - } - - linked_ptr symbol(new PublicSymbol(name, address, - stack_param_size)); - return public_symbols_.Store(address, symbol); - } - return false; -} - -bool BasicSourceLineResolver::Module::ParseStackInfo(char *stack_info_line) { - // Skip "STACK " prefix. - stack_info_line += 6; - - // Find the token indicating what sort of stack frame walking - // information this is. - while (*stack_info_line == ' ') - stack_info_line++; - const char *platform = stack_info_line; - while (!strchr(kWhitespace, *stack_info_line)) - stack_info_line++; - *stack_info_line++ = '\0'; - - // MSVC stack frame info. - if (strcmp(platform, "WIN") == 0) { - int type = 0; - uint64_t rva, code_size; - linked_ptr - stack_frame_info(WindowsFrameInfo::ParseFromString(stack_info_line, - type, - rva, - code_size)); - if (stack_frame_info == NULL) - return false; - - // TODO(mmentovai): I wanted to use StoreRange's return value as this - // method's return value, but MSVC infrequently outputs stack info that - // violates the containment rules. This happens with a section of code - // in strncpy_s in test_app.cc (testdata/minidump2). There, problem looks - // like this: - // STACK WIN 4 4242 1a a 0 ... (STACK WIN 4 base size prolog 0 ...) - // STACK WIN 4 4243 2e 9 0 ... - // ContainedRangeMap treats these two blocks as conflicting. In reality, - // when the prolog lengths are taken into account, the actual code of - // these blocks doesn't conflict. However, we can't take the prolog lengths - // into account directly here because we'd wind up with a different set - // of range conflicts when MSVC outputs stack info like this: - // STACK WIN 4 1040 73 33 0 ... - // STACK WIN 4 105a 59 19 0 ... - // because in both of these entries, the beginning of the code after the - // prolog is at 0x1073, and the last byte of contained code is at 0x10b2. - // Perhaps we could get away with storing ranges by rva + prolog_size - // if ContainedRangeMap were modified to allow replacement of - // already-stored values. - - windows_frame_info_[type].StoreRange(rva, code_size, stack_frame_info); - return true; - } else if (strcmp(platform, "CFI") == 0) { - // DWARF CFI stack frame info - return ParseCFIFrameInfo(stack_info_line); - } else { - // Something unrecognized. - return false; - } -} - -bool BasicSourceLineResolver::Module::ParseCFIFrameInfo( - char *stack_info_line) { - char *cursor; - - // Is this an INIT record or a delta record? - char *init_or_address = strtok_r(stack_info_line, " \r\n", &cursor); - if (!init_or_address) - return false; - - if (strcmp(init_or_address, "INIT") == 0) { - // This record has the form "STACK INIT
". - char *address_field = strtok_r(NULL, " \r\n", &cursor); - if (!address_field) return false; - - char *size_field = strtok_r(NULL, " \r\n", &cursor); - if (!size_field) return false; - - char *initial_rules = strtok_r(NULL, "\r\n", &cursor); - if (!initial_rules) return false; - - MemAddr address = strtoul(address_field, NULL, 16); - MemAddr size = strtoul(size_field, NULL, 16); - cfi_initial_rules_.StoreRange(address, size, initial_rules); - return true; - } - - // This record has the form "STACK
". - char *address_field = init_or_address; - char *delta_rules = strtok_r(NULL, "\r\n", &cursor); - if (!delta_rules) return false; - MemAddr address = strtoul(address_field, NULL, 16); - cfi_delta_rules_[address] = delta_rules; - return true; -} - -// static -bool SymbolParseHelper::ParseFile(char *file_line, long *index, - char **filename) { - // FILE - assert(strncmp(file_line, "FILE ", 5) == 0); - file_line += 5; // skip prefix - - vector tokens; - if (!Tokenize(file_line, kWhitespace, 2, &tokens)) { - return false; - } - - char *after_number; - *index = strtol(tokens[0], &after_number, 10); - if (!IsValidAfterNumber(after_number) || *index < 0 || - *index == std::numeric_limits::max()) { - return false; - } - - *filename = tokens[1]; - if (!*filename) { - return false; - } - - return true; -} - -// static -bool SymbolParseHelper::ParseFunction(char *function_line, uint64_t *address, - uint64_t *size, long *stack_param_size, - char **name) { - // FUNC
- assert(strncmp(function_line, "FUNC ", 5) == 0); - function_line += 5; // skip prefix - - vector tokens; - if (!Tokenize(function_line, kWhitespace, 4, &tokens)) { - return false; - } - - char *after_number; - *address = strtoull(tokens[0], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *address == std::numeric_limits::max()) { - return false; - } - *size = strtoull(tokens[1], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *size == std::numeric_limits::max()) { - return false; - } - *stack_param_size = strtol(tokens[2], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *stack_param_size == std::numeric_limits::max() || - *stack_param_size < 0) { - return false; - } - *name = tokens[3]; - - return true; -} - -// static -bool SymbolParseHelper::ParseLine(char *line_line, uint64_t *address, - uint64_t *size, long *line_number, - long *source_file) { - //
- vector tokens; - if (!Tokenize(line_line, kWhitespace, 4, &tokens)) { - return false; - } - - char *after_number; - *address = strtoull(tokens[0], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *address == std::numeric_limits::max()) { - return false; - } - *size = strtoull(tokens[1], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *size == std::numeric_limits::max()) { - return false; - } - *line_number = strtol(tokens[2], &after_number, 10); - if (!IsValidAfterNumber(after_number) || - *line_number == std::numeric_limits::max()) { - return false; - } - *source_file = strtol(tokens[3], &after_number, 10); - if (!IsValidAfterNumber(after_number) || *source_file < 0 || - *source_file == std::numeric_limits::max()) { - return false; - } - - // Valid line numbers normally start from 1, however there are functions that - // are associated with a source file but not associated with any line number - // (block helper function) and for such functions the symbol file contains 0 - // for the line numbers. Hence, 0 should be treated as a valid line number. - // For more information on block helper functions, please, take a look at: - // http://clang.llvm.org/docs/Block-ABI-Apple.html - if (*line_number < 0) { - return false; - } - - return true; -} - -// static -bool SymbolParseHelper::ParsePublicSymbol(char *public_line, - uint64_t *address, - long *stack_param_size, - char **name) { - // PUBLIC
- assert(strncmp(public_line, "PUBLIC ", 7) == 0); - public_line += 7; // skip prefix - - vector tokens; - if (!Tokenize(public_line, kWhitespace, 3, &tokens)) { - return false; - } - - char *after_number; - *address = strtoull(tokens[0], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *address == std::numeric_limits::max()) { - return false; - } - *stack_param_size = strtol(tokens[1], &after_number, 16); - if (!IsValidAfterNumber(after_number) || - *stack_param_size == std::numeric_limits::max() || - *stack_param_size < 0) { - return false; - } - *name = tokens[2]; - - return true; -} - -// static -bool SymbolParseHelper::IsValidAfterNumber(char *after_number) { - if (after_number != NULL && strchr(kWhitespace, *after_number) != NULL) { - return true; - } - return false; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_types.h b/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_types.h deleted file mode 100644 index a022bc0db..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_types.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// basic_source_line_types.h: definition of nested classes/structs in -// BasicSourceLineResolver. It moves the definitions out of -// basic_source_line_resolver.cc, so that other classes could have access -// to these private nested types without including basic_source_line_resolver.cc -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ -#define PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ - -#include -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "processor/source_line_resolver_base_types.h" - -#include "processor/address_map-inl.h" -#include "processor/range_map-inl.h" -#include "processor/contained_range_map-inl.h" - -#include "processor/linked_ptr.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/cfi_frame_info.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -struct -BasicSourceLineResolver::Function : public SourceLineResolverBase::Function { - Function(const string &function_name, - MemAddr function_address, - MemAddr code_size, - int set_parameter_size) : Base(function_name, - function_address, - code_size, - set_parameter_size), - lines() { } - RangeMap< MemAddr, linked_ptr > lines; - private: - typedef SourceLineResolverBase::Function Base; -}; - - -class BasicSourceLineResolver::Module : public SourceLineResolverBase::Module { - public: - explicit Module(const string &name) : name_(name), is_corrupt_(false) { } - virtual ~Module() { } - - // Loads a map from the given buffer in char* type. - // Does NOT have ownership of memory_buffer. - // The passed in |memory buffer| is of size |memory_buffer_size|. If it is - // not null terminated, LoadMapFromMemory() will null terminate it by - // modifying the passed in buffer. - virtual bool LoadMapFromMemory(char *memory_buffer, - size_t memory_buffer_size); - - // Tells whether the loaded symbol data is corrupt. Return value is - // undefined, if the symbol data hasn't been loaded yet. - virtual bool IsCorrupt() const { return is_corrupt_; } - - // Looks up the given relative address, and fills the StackFrame struct - // with the result. - virtual void LookupAddress(StackFrame *frame) const; - - // If Windows stack walking information is available covering ADDRESS, - // return a WindowsFrameInfo structure describing it. If the information - // is not available, returns NULL. A NULL return value does not indicate - // an error. The caller takes ownership of any returned WindowsFrameInfo - // object. - virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) const; - - // If CFI stack walking information is available covering ADDRESS, - // return a CFIFrameInfo structure describing it. If the information - // is not available, return NULL. The caller takes ownership of any - // returned CFIFrameInfo object. - virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) const; - - private: - // Friend declarations. - friend class BasicSourceLineResolver; - friend class ModuleComparer; - friend class ModuleSerializer; - - typedef std::map FileMap; - - // Logs parse errors. |*num_errors| is increased every time LogParseError is - // called. - static void LogParseError( - const string &message, - int line_number, - int *num_errors); - - // Parses a file declaration - bool ParseFile(char *file_line); - - // Parses a function declaration, returning a new Function object. - Function* ParseFunction(char *function_line); - - // Parses a line declaration, returning a new Line object. - Line* ParseLine(char *line_line); - - // Parses a PUBLIC symbol declaration, storing it in public_symbols_. - // Returns false if an error occurs. - bool ParsePublicSymbol(char *public_line); - - // Parses a STACK WIN or STACK CFI frame info declaration, storing - // it in the appropriate table. - bool ParseStackInfo(char *stack_info_line); - - // Parses a STACK CFI record, storing it in cfi_frame_info_. - bool ParseCFIFrameInfo(char *stack_info_line); - - string name_; - FileMap files_; - RangeMap< MemAddr, linked_ptr > functions_; - AddressMap< MemAddr, linked_ptr > public_symbols_; - bool is_corrupt_; - - // Each element in the array is a ContainedRangeMap for a type - // listed in WindowsFrameInfoTypes. These are split by type because - // there may be overlaps between maps of different types, but some - // information is only available as certain types. - ContainedRangeMap< MemAddr, linked_ptr > - windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST]; - - // DWARF CFI stack walking data. The Module stores the initial rule sets - // and rule deltas as strings, just as they appear in the symbol file: - // although the file may contain hundreds of thousands of STACK CFI - // records, walking a stack will only ever use a few of them, so it's - // best to delay parsing a record until it's actually needed. - - // STACK CFI INIT records: for each range, an initial set of register - // recovery rules. The RangeMap's itself gives the starting and ending - // addresses. - RangeMap cfi_initial_rules_; - - // STACK CFI records: at a given address, the changes to the register - // recovery rules that take effect at that address. The map key is the - // starting address; the ending address is the key of the next entry in - // this map, or the end of the range as given by the cfi_initial_rules_ - // entry (which FindCFIFrameInfo looks up first). - std::map cfi_delta_rules_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_unittest.cc deleted file mode 100644 index a75044c74..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_unittest.cc +++ /dev/null @@ -1,682 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/memory_region.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" -#include "processor/windows_frame_info.h" -#include "processor/cfi_frame_info.h" - -namespace { - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CFIFrameInfo; -using google_breakpad::CodeModule; -using google_breakpad::MemoryRegion; -using google_breakpad::StackFrame; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::linked_ptr; -using google_breakpad::scoped_ptr; -using google_breakpad::SymbolParseHelper; - -class TestCodeModule : public CodeModule { - public: - TestCodeModule(string code_file) : code_file_(code_file) {} - virtual ~TestCodeModule() {} - - virtual uint64_t base_address() const { return 0; } - virtual uint64_t size() const { return 0xb000; } - virtual string code_file() const { return code_file_; } - virtual string code_identifier() const { return ""; } - virtual string debug_file() const { return ""; } - virtual string debug_identifier() const { return ""; } - virtual string version() const { return ""; } - virtual CodeModule* Copy() const { - return new TestCodeModule(code_file_); - } - virtual uint64_t shrink_down_delta() const { return 0; } - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta) {} - - private: - string code_file_; -}; - -// A mock memory region object, for use by the STACK CFI tests. -class MockMemoryRegion: public MemoryRegion { - uint64_t GetBase() const { return 0x10000; } - uint32_t GetSize() const { return 0x01000; } - bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { - *value = address & 0xff; - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { - *value = address & 0xffff; - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { - switch (address) { - case 0x10008: *value = 0x98ecadc3; break; // saved %ebx - case 0x1000c: *value = 0x878f7524; break; // saved %esi - case 0x10010: *value = 0x6312f9a5; break; // saved %edi - case 0x10014: *value = 0x10038; break; // caller's %ebp - case 0x10018: *value = 0xf6438648; break; // return address - default: *value = 0xdeadbeef; break; // junk - } - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { - *value = address; - return true; - } - void Print() const { - assert(false); - } -}; - -// Verify that, for every association in ACTUAL, EXPECTED has the same -// association. (That is, ACTUAL's associations should be a subset of -// EXPECTED's.) Also verify that ACTUAL has associations for ".ra" and -// ".cfa". -static bool VerifyRegisters( - const char *file, int line, - const CFIFrameInfo::RegisterValueMap &expected, - const CFIFrameInfo::RegisterValueMap &actual) { - CFIFrameInfo::RegisterValueMap::const_iterator a; - a = actual.find(".cfa"); - if (a == actual.end()) - return false; - a = actual.find(".ra"); - if (a == actual.end()) - return false; - for (a = actual.begin(); a != actual.end(); a++) { - CFIFrameInfo::RegisterValueMap::const_iterator e = - expected.find(a->first); - if (e == expected.end()) { - fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n", - file, line, a->first.c_str(), a->second); - return false; - } - if (e->second != a->second) { - fprintf(stderr, - "%s:%d: register '%s' recovered value was 0x%x, expected 0x%x\n", - file, line, a->first.c_str(), a->second, e->second); - return false; - } - // Don't complain if this doesn't recover all registers. Although - // the DWARF spec says that unmentioned registers are undefined, - // GCC uses omission to mean that they are unchanged. - } - return true; -} - - -static bool VerifyEmpty(const StackFrame &frame) { - if (frame.function_name.empty() && - frame.source_file_name.empty() && - frame.source_line == 0) - return true; - return false; -} - -static void ClearSourceLineInfo(StackFrame *frame) { - frame->function_name.clear(); - frame->module = NULL; - frame->source_file_name.clear(); - frame->source_line = 0; -} - -class TestBasicSourceLineResolver : public ::testing::Test { -public: - void SetUp() { - testdata_dir = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata"; - } - - BasicSourceLineResolver resolver; - string testdata_dir; -}; - -TEST_F(TestBasicSourceLineResolver, TestLoadAndResolve) -{ - TestCodeModule module1("module1"); - ASSERT_TRUE(resolver.LoadModule(&module1, testdata_dir + "/module1.out")); - ASSERT_TRUE(resolver.HasModule(&module1)); - TestCodeModule module2("module2"); - ASSERT_TRUE(resolver.LoadModule(&module2, testdata_dir + "/module2.out")); - ASSERT_TRUE(resolver.HasModule(&module2)); - - - StackFrame frame; - scoped_ptr windows_frame_info; - scoped_ptr cfi_frame_info; - frame.instruction = 0x1000; - frame.module = NULL; - resolver.FillSourceLineInfo(&frame); - ASSERT_FALSE(frame.module); - ASSERT_TRUE(frame.function_name.empty()); - ASSERT_EQ(frame.function_base, 0U); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - ASSERT_EQ(frame.source_line_base, 0U); - - frame.module = &module1; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_1"); - ASSERT_TRUE(frame.module); - ASSERT_EQ(frame.module->code_file(), "module1"); - ASSERT_EQ(frame.function_base, 0x1000U); - ASSERT_EQ(frame.source_file_name, "file1_1.cc"); - ASSERT_EQ(frame.source_line, 44); - ASSERT_EQ(frame.source_line_base, 0x1000U); - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_FRAME_DATA); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_EQ(windows_frame_info->program_string, - "$eip 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ ="); - - ClearSourceLineInfo(&frame); - frame.instruction = 0x800; - frame.module = &module1; - resolver.FillSourceLineInfo(&frame); - ASSERT_TRUE(VerifyEmpty(frame)); - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_FALSE(windows_frame_info.get()); - - frame.instruction = 0x1280; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_3"); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_UNKNOWN); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_TRUE(windows_frame_info->program_string.empty()); - - frame.instruction = 0x1380; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_4"); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_FRAME_DATA); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_FALSE(windows_frame_info->program_string.empty()); - - frame.instruction = 0x2000; - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_FALSE(windows_frame_info.get()); - - // module1 has STACK CFI records covering 3d40..3def; - // module2 has STACK CFI records covering 3df0..3e9f; - // check that FindCFIFrameInfo doesn't claim to find any outside those ranges. - frame.instruction = 0x3d3f; - frame.module = &module1; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_FALSE(cfi_frame_info.get()); - - frame.instruction = 0x3e9f; - frame.module = &module1; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_FALSE(cfi_frame_info.get()); - - CFIFrameInfo::RegisterValueMap current_registers; - CFIFrameInfo::RegisterValueMap caller_registers; - CFIFrameInfo::RegisterValueMap expected_caller_registers; - MockMemoryRegion memory; - - // Regardless of which instruction evaluation takes place at, it - // should produce the same values for the caller's registers. - expected_caller_registers[".cfa"] = 0x1001c; - expected_caller_registers[".ra"] = 0xf6438648; - expected_caller_registers["$ebp"] = 0x10038; - expected_caller_registers["$ebx"] = 0x98ecadc3; - expected_caller_registers["$esi"] = 0x878f7524; - expected_caller_registers["$edi"] = 0x6312f9a5; - - frame.instruction = 0x3d40; - frame.module = &module1; - current_registers.clear(); - current_registers["$esp"] = 0x10018; - current_registers["$ebp"] = 0x10038; - current_registers["$ebx"] = 0x98ecadc3; - current_registers["$esi"] = 0x878f7524; - current_registers["$edi"] = 0x6312f9a5; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers)); - - frame.instruction = 0x3d41; - current_registers["$esp"] = 0x10014; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers)); - - frame.instruction = 0x3d43; - current_registers["$ebp"] = 0x10014; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d54; - current_registers["$ebx"] = 0x6864f054U; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d5a; - current_registers["$esi"] = 0x6285f79aU; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d84; - current_registers["$edi"] = 0x64061449U; - cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x2900; - frame.module = &module1; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, string("PublicSymbol")); - - frame.instruction = 0x4000; - frame.module = &module1; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, string("LargeFunction")); - - frame.instruction = 0x2181; - frame.module = &module2; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function2_2"); - ASSERT_EQ(frame.function_base, 0x2170U); - ASSERT_TRUE(frame.module); - ASSERT_EQ(frame.module->code_file(), "module2"); - ASSERT_EQ(frame.source_file_name, "file2_2.cc"); - ASSERT_EQ(frame.source_line, 21); - ASSERT_EQ(frame.source_line_base, 0x2180U); - windows_frame_info.reset(resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_FRAME_DATA); - ASSERT_EQ(windows_frame_info->prolog_size, 1U); - - frame.instruction = 0x216f; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Public2_1"); - - ClearSourceLineInfo(&frame); - frame.instruction = 0x219f; - frame.module = &module2; - resolver.FillSourceLineInfo(&frame); - ASSERT_TRUE(frame.function_name.empty()); - - frame.instruction = 0x21a0; - frame.module = &module2; - resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Public2_2"); -} - -TEST_F(TestBasicSourceLineResolver, TestInvalidLoads) -{ - TestCodeModule module3("module3"); - ASSERT_TRUE(resolver.LoadModule(&module3, - testdata_dir + "/module3_bad.out")); - ASSERT_TRUE(resolver.HasModule(&module3)); - ASSERT_TRUE(resolver.IsModuleCorrupt(&module3)); - TestCodeModule module4("module4"); - ASSERT_TRUE(resolver.LoadModule(&module4, - testdata_dir + "/module4_bad.out")); - ASSERT_TRUE(resolver.HasModule(&module4)); - ASSERT_TRUE(resolver.IsModuleCorrupt(&module4)); - TestCodeModule module5("module5"); - ASSERT_FALSE(resolver.LoadModule(&module5, - testdata_dir + "/invalid-filename")); - ASSERT_FALSE(resolver.HasModule(&module5)); - TestCodeModule invalidmodule("invalid-module"); - ASSERT_FALSE(resolver.HasModule(&invalidmodule)); -} - -TEST_F(TestBasicSourceLineResolver, TestUnload) -{ - TestCodeModule module1("module1"); - ASSERT_FALSE(resolver.HasModule(&module1)); - ASSERT_TRUE(resolver.LoadModule(&module1, testdata_dir + "/module1.out")); - ASSERT_TRUE(resolver.HasModule(&module1)); - resolver.UnloadModule(&module1); - ASSERT_FALSE(resolver.HasModule(&module1)); - ASSERT_TRUE(resolver.LoadModule(&module1, testdata_dir + "/module1.out")); - ASSERT_TRUE(resolver.HasModule(&module1)); -} - -// Test parsing of valid FILE lines. The format is: -// FILE -TEST(SymbolParseHelper, ParseFileValid) { - long index; - char *filename; - - char kTestLine[] = "FILE 1 file name"; - ASSERT_TRUE(SymbolParseHelper::ParseFile(kTestLine, &index, &filename)); - EXPECT_EQ(1, index); - EXPECT_EQ("file name", string(filename)); - - // 0 is a valid index. - char kTestLine1[] = "FILE 0 file name"; - ASSERT_TRUE(SymbolParseHelper::ParseFile(kTestLine1, &index, &filename)); - EXPECT_EQ(0, index); - EXPECT_EQ("file name", string(filename)); -} - -// Test parsing of invalid FILE lines. The format is: -// FILE -TEST(SymbolParseHelper, ParseFileInvalid) { - long index; - char *filename; - - // Test missing file name. - char kTestLine[] = "FILE 1 "; - ASSERT_FALSE(SymbolParseHelper::ParseFile(kTestLine, &index, &filename)); - - // Test bad index. - char kTestLine1[] = "FILE x1 file name"; - ASSERT_FALSE(SymbolParseHelper::ParseFile(kTestLine1, &index, &filename)); - - // Test large index. - char kTestLine2[] = "FILE 123123123123123123123123 file name"; - ASSERT_FALSE(SymbolParseHelper::ParseFile(kTestLine2, &index, &filename)); - - // Test negative index. - char kTestLine3[] = "FILE -2 file name"; - ASSERT_FALSE(SymbolParseHelper::ParseFile(kTestLine3, &index, &filename)); -} - -// Test parsing of valid FUNC lines. The format is: -// FUNC
-TEST(SymbolParseHelper, ParseFunctionValid) { - uint64_t address; - uint64_t size; - long stack_param_size; - char *name; - - char kTestLine[] = "FUNC 1 2 3 function name"; - ASSERT_TRUE(SymbolParseHelper::ParseFunction(kTestLine, &address, &size, - &stack_param_size, &name)); - EXPECT_EQ(1ULL, address); - EXPECT_EQ(2ULL, size); - EXPECT_EQ(3, stack_param_size); - EXPECT_EQ("function name", string(name)); - - // Test hex address, size, and param size. - char kTestLine1[] = "FUNC a1 a2 a3 function name"; - ASSERT_TRUE(SymbolParseHelper::ParseFunction(kTestLine1, &address, &size, - &stack_param_size, &name)); - EXPECT_EQ(0xa1ULL, address); - EXPECT_EQ(0xa2ULL, size); - EXPECT_EQ(0xa3, stack_param_size); - EXPECT_EQ("function name", string(name)); - - char kTestLine2[] = "FUNC 0 0 0 function name"; - ASSERT_TRUE(SymbolParseHelper::ParseFunction(kTestLine2, &address, &size, - &stack_param_size, &name)); - EXPECT_EQ(0ULL, address); - EXPECT_EQ(0ULL, size); - EXPECT_EQ(0, stack_param_size); - EXPECT_EQ("function name", string(name)); -} - -// Test parsing of invalid FUNC lines. The format is: -// FUNC
-TEST(SymbolParseHelper, ParseFunctionInvalid) { - uint64_t address; - uint64_t size; - long stack_param_size; - char *name; - - // Test missing function name. - char kTestLine[] = "FUNC 1 2 3 "; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine, &address, &size, - &stack_param_size, &name)); - // Test bad address. - char kTestLine1[] = "FUNC 1z 2 3 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine1, &address, &size, - &stack_param_size, &name)); - // Test large address. - char kTestLine2[] = "FUNC 123123123123123123123123123 2 3 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine2, &address, &size, - &stack_param_size, &name)); - // Test bad size. - char kTestLine3[] = "FUNC 1 z2 3 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine3, &address, &size, - &stack_param_size, &name)); - // Test large size. - char kTestLine4[] = "FUNC 1 231231231231231231231231232 3 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine4, &address, &size, - &stack_param_size, &name)); - // Test bad param size. - char kTestLine5[] = "FUNC 1 2 3z function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine5, &address, &size, - &stack_param_size, &name)); - // Test large param size. - char kTestLine6[] = "FUNC 1 2 312312312312312312312312323 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine6, &address, &size, - &stack_param_size, &name)); - // Negative param size. - char kTestLine7[] = "FUNC 1 2 -5 function name"; - ASSERT_FALSE(SymbolParseHelper::ParseFunction(kTestLine7, &address, &size, - &stack_param_size, &name)); -} - -// Test parsing of valid lines. The format is: -//
-TEST(SymbolParseHelper, ParseLineValid) { - uint64_t address; - uint64_t size; - long line_number; - long source_file; - - char kTestLine[] = "1 2 3 4"; - ASSERT_TRUE(SymbolParseHelper::ParseLine(kTestLine, &address, &size, - &line_number, &source_file)); - EXPECT_EQ(1ULL, address); - EXPECT_EQ(2ULL, size); - EXPECT_EQ(3, line_number); - EXPECT_EQ(4, source_file); - - // Test hex size and address. - char kTestLine1[] = "a1 a2 3 4 // some comment"; - ASSERT_TRUE(SymbolParseHelper::ParseLine(kTestLine1, &address, &size, - &line_number, &source_file)); - EXPECT_EQ(0xa1ULL, address); - EXPECT_EQ(0xa2ULL, size); - EXPECT_EQ(3, line_number); - EXPECT_EQ(4, source_file); - - // 0 is a valid line number. - char kTestLine2[] = "a1 a2 0 4 // some comment"; - ASSERT_TRUE(SymbolParseHelper::ParseLine(kTestLine2, &address, &size, - &line_number, &source_file)); - EXPECT_EQ(0xa1ULL, address); - EXPECT_EQ(0xa2ULL, size); - EXPECT_EQ(0, line_number); - EXPECT_EQ(4, source_file); -} - -// Test parsing of invalid lines. The format is: -//
-TEST(SymbolParseHelper, ParseLineInvalid) { - uint64_t address; - uint64_t size; - long line_number; - long source_file; - - // Test missing source file id. - char kTestLine[] = "1 2 3"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine, &address, &size, - &line_number, &source_file)); - // Test bad address. - char kTestLine1[] = "1z 2 3 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine1, &address, &size, - &line_number, &source_file)); - // Test large address. - char kTestLine2[] = "123123123123123123123123 2 3 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine2, &address, &size, - &line_number, &source_file)); - // Test bad size. - char kTestLine3[] = "1 z2 3 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine3, &address, &size, - &line_number, &source_file)); - // Test large size. - char kTestLine4[] = "1 123123123123123123123123 3 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine4, &address, &size, - &line_number, &source_file)); - // Test bad line number. - char kTestLine5[] = "1 2 z3 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine5, &address, &size, - &line_number, &source_file)); - // Test negative line number. - char kTestLine6[] = "1 2 -1 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine6, &address, &size, - &line_number, &source_file)); - // Test large line number. - char kTestLine7[] = "1 2 123123123123123123123 4"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine7, &address, &size, - &line_number, &source_file)); - // Test bad source file id. - char kTestLine8[] = "1 2 3 f"; - ASSERT_FALSE(SymbolParseHelper::ParseLine(kTestLine8, &address, &size, - &line_number, &source_file)); -} - -// Test parsing of valid PUBLIC lines. The format is: -// PUBLIC
-TEST(SymbolParseHelper, ParsePublicSymbolValid) { - uint64_t address; - long stack_param_size; - char *name; - - char kTestLine[] = "PUBLIC 1 2 3"; - ASSERT_TRUE(SymbolParseHelper::ParsePublicSymbol(kTestLine, &address, - &stack_param_size, &name)); - EXPECT_EQ(1ULL, address); - EXPECT_EQ(2, stack_param_size); - EXPECT_EQ("3", string(name)); - - // Test hex size and address. - char kTestLine1[] = "PUBLIC a1 a2 function name"; - ASSERT_TRUE(SymbolParseHelper::ParsePublicSymbol(kTestLine1, &address, - &stack_param_size, &name)); - EXPECT_EQ(0xa1ULL, address); - EXPECT_EQ(0xa2, stack_param_size); - EXPECT_EQ("function name", string(name)); - - // Test 0 is a valid address. - char kTestLine2[] = "PUBLIC 0 a2 function name"; - ASSERT_TRUE(SymbolParseHelper::ParsePublicSymbol(kTestLine2, &address, - &stack_param_size, &name)); - EXPECT_EQ(0ULL, address); - EXPECT_EQ(0xa2, stack_param_size); - EXPECT_EQ("function name", string(name)); -} - -// Test parsing of invalid PUBLIC lines. The format is: -// PUBLIC
-TEST(SymbolParseHelper, ParsePublicSymbolInvalid) { - uint64_t address; - long stack_param_size; - char *name; - - // Test missing source function name. - char kTestLine[] = "PUBLIC 1 2 "; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine, &address, - &stack_param_size, &name)); - // Test bad address. - char kTestLine1[] = "PUBLIC 1z 2 3"; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine1, &address, - &stack_param_size, &name)); - // Test large address. - char kTestLine2[] = "PUBLIC 123123123123123123123123 2 3"; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine2, &address, - &stack_param_size, &name)); - // Test bad param stack size. - char kTestLine3[] = "PUBLIC 1 z2 3"; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine3, &address, - &stack_param_size, &name)); - // Test large param stack size. - char kTestLine4[] = "PUBLIC 1 123123123123123123123123123 3"; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine4, &address, - &stack_param_size, &name)); - // Test negative param stack size. - char kTestLine5[] = "PUBLIC 1 -5 3"; - ASSERT_FALSE(SymbolParseHelper::ParsePublicSymbol(kTestLine5, &address, - &stack_param_size, &name)); -} - -} // namespace - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/call_stack.cc b/toolkit/crashreporter/google-breakpad/src/processor/call_stack.cc deleted file mode 100644 index 925f08469..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/call_stack.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// call_stack.cc: A call stack comprised of stack frames. -// -// See call_stack.h for documentation. -// -// Author: Mark Mentovai - -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/stack_frame.h" - -namespace google_breakpad { - -CallStack::~CallStack() { - Clear(); -} - -void CallStack::Clear() { - for (vector::const_iterator iterator = frames_.begin(); - iterator != frames_.end(); - ++iterator) { - delete *iterator; - } - tid_ = 0; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info-inl.h deleted file mode 100644 index 7e7af0af9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info-inl.h +++ /dev/null @@ -1,119 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_frame_info-inl.h: Definitions for cfi_frame_info.h inlined functions. - -#ifndef PROCESSOR_CFI_FRAME_INFO_INL_H_ -#define PROCESSOR_CFI_FRAME_INFO_INL_H_ - -#include - -namespace google_breakpad { - -template -bool SimpleCFIWalker::FindCallerRegisters( - const MemoryRegion &memory, - const CFIFrameInfo &cfi_frame_info, - const RawContextType &callee_context, - int callee_validity, - RawContextType *caller_context, - int *caller_validity) const { - typedef CFIFrameInfo::RegisterValueMap ValueMap; - ValueMap callee_registers; - ValueMap caller_registers; - // Just for brevity. - typename ValueMap::const_iterator caller_none = caller_registers.end(); - - // Populate callee_registers with register values from callee_context. - for (size_t i = 0; i < map_size_; i++) { - const RegisterSet &r = register_map_[i]; - if (callee_validity & r.validity_flag) - callee_registers[r.name] = callee_context.*r.context_member; - } - - // Apply the rules, and see what register values they yield. - if (!cfi_frame_info.FindCallerRegs(callee_registers, memory, - &caller_registers)) - return false; - - // Populate *caller_context with the values the rules placed in - // caller_registers. - memset(caller_context, 0xda, sizeof(*caller_context)); - *caller_validity = 0; - for (size_t i = 0; i < map_size_; i++) { - const RegisterSet &r = register_map_[i]; - typename ValueMap::const_iterator caller_entry; - - // Did the rules provide a value for this register by its name? - caller_entry = caller_registers.find(r.name); - if (caller_entry != caller_none) { - caller_context->*r.context_member = caller_entry->second; - *caller_validity |= r.validity_flag; - continue; - } - - // Did the rules provide a value for this register under its - // alternate name? - if (r.alternate_name) { - caller_entry = caller_registers.find(r.alternate_name); - if (caller_entry != caller_none) { - caller_context->*r.context_member = caller_entry->second; - *caller_validity |= r.validity_flag; - continue; - } - } - - // Is this a callee-saves register? The walker assumes that these - // still hold the caller's value if the CFI doesn't mention them. - // - // Note that other frame walkers may fail to recover callee-saves - // registers; for example, the x86 "traditional" strategy only - // recovers %eip, %esp, and %ebp, even though %ebx, %esi, and %edi - // are callee-saves, too. It is not correct to blindly set the - // valid bit for all callee-saves registers, without first - // checking its validity bit in the callee. - if (r.callee_saves && (callee_validity & r.validity_flag) != 0) { - caller_context->*r.context_member = callee_context.*r.context_member; - *caller_validity |= r.validity_flag; - continue; - } - - // Otherwise, the register's value is unknown. - } - - return true; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_CFI_FRAME_INFO_INL_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.cc b/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.cc deleted file mode 100644 index 0c4af7ba8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.cc +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_frame_info.cc: Implementation of CFIFrameInfo class. -// See cfi_frame_info.h for details. - -#include "processor/cfi_frame_info.h" - -#include - -#include - -#include "common/scoped_ptr.h" -#include "processor/postfix_evaluator-inl.h" - -namespace google_breakpad { - -#ifdef _MSC_VER -#define strtok_r strtok_s -#endif - -template -bool CFIFrameInfo::FindCallerRegs(const RegisterValueMap ®isters, - const MemoryRegion &memory, - RegisterValueMap *caller_registers) const { - // If there are not rules for both .ra and .cfa in effect at this address, - // don't use this CFI data for stack walking. - if (cfa_rule_.empty() || ra_rule_.empty()) - return false; - - RegisterValueMap working; - PostfixEvaluator evaluator(&working, &memory); - - caller_registers->clear(); - - // First, compute the CFA. - V cfa; - working = registers; - if (!evaluator.EvaluateForValue(cfa_rule_, &cfa)) - return false; - - // Then, compute the return address. - V ra; - working = registers; - working[".cfa"] = cfa; - if (!evaluator.EvaluateForValue(ra_rule_, &ra)) - return false; - - // Now, compute values for all the registers register_rules_ mentions. - for (RuleMap::const_iterator it = register_rules_.begin(); - it != register_rules_.end(); it++) { - V value; - working = registers; - working[".cfa"] = cfa; - if (!evaluator.EvaluateForValue(it->second, &value)) - return false; - (*caller_registers)[it->first] = value; - } - - (*caller_registers)[".ra"] = ra; - (*caller_registers)[".cfa"] = cfa; - - return true; -} - -// Explicit instantiations for 32-bit and 64-bit architectures. -template bool CFIFrameInfo::FindCallerRegs( - const RegisterValueMap ®isters, - const MemoryRegion &memory, - RegisterValueMap *caller_registers) const; -template bool CFIFrameInfo::FindCallerRegs( - const RegisterValueMap ®isters, - const MemoryRegion &memory, - RegisterValueMap *caller_registers) const; - -string CFIFrameInfo::Serialize() const { - std::ostringstream stream; - - if (!cfa_rule_.empty()) { - stream << ".cfa: " << cfa_rule_; - } - if (!ra_rule_.empty()) { - if (static_cast(stream.tellp()) != 0) - stream << " "; - stream << ".ra: " << ra_rule_; - } - for (RuleMap::const_iterator iter = register_rules_.begin(); - iter != register_rules_.end(); - ++iter) { - if (static_cast(stream.tellp()) != 0) - stream << " "; - stream << iter->first << ": " << iter->second; - } - - return stream.str(); -} - -bool CFIRuleParser::Parse(const string &rule_set) { - size_t rule_set_len = rule_set.size(); - scoped_array working_copy(new char[rule_set_len + 1]); - memcpy(working_copy.get(), rule_set.data(), rule_set_len); - working_copy[rule_set_len] = '\0'; - - name_.clear(); - expression_.clear(); - - char *cursor; - static const char token_breaks[] = " \t\r\n"; - char *token = strtok_r(working_copy.get(), token_breaks, &cursor); - - for (;;) { - // End of rule set? - if (!token) return Report(); - - // Register/pseudoregister name? - size_t token_len = strlen(token); - if (token_len >= 1 && token[token_len - 1] == ':') { - // Names can't be empty. - if (token_len < 2) return false; - // If there is any pending content, report it. - if (!name_.empty() || !expression_.empty()) { - if (!Report()) return false; - } - name_.assign(token, token_len - 1); - expression_.clear(); - } else { - // Another expression component. - assert(token_len > 0); // strtok_r guarantees this, I think. - if (!expression_.empty()) - expression_ += ' '; - expression_ += token; - } - token = strtok_r(NULL, token_breaks, &cursor); - } -} - -bool CFIRuleParser::Report() { - if (name_.empty() || expression_.empty()) return false; - if (name_ == ".cfa") handler_->CFARule(expression_); - else if (name_ == ".ra") handler_->RARule(expression_); - else handler_->RegisterRule(name_, expression_); - return true; -} - -void CFIFrameInfoParseHandler::CFARule(const string &expression) { - frame_info_->SetCFARule(expression); -} - -void CFIFrameInfoParseHandler::RARule(const string &expression) { - frame_info_->SetRARule(expression); -} - -void CFIFrameInfoParseHandler::RegisterRule(const string &name, - const string &expression) { - frame_info_->SetRegisterRule(name, expression); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.h b/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.h deleted file mode 100644 index 90a1b3d74..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.h +++ /dev/null @@ -1,275 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_frame_info.h: Define the CFIFrameInfo class, which holds the -// set of 'STACK CFI'-derived register recovery rules that apply at a -// given instruction. - -#ifndef PROCESSOR_CFI_FRAME_INFO_H_ -#define PROCESSOR_CFI_FRAME_INFO_H_ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -using std::map; - -class MemoryRegion; - -// A set of rules for recovering the calling frame's registers' -// values, when the PC is at a given address in the current frame's -// function. See the description of 'STACK CFI' records at: -// -// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md -// -// To prepare an instance of CFIFrameInfo for use at a given -// instruction, first populate it with the rules from the 'STACK CFI -// INIT' record that covers that instruction, and then apply the -// changes given by the 'STACK CFI' records up to our instruction's -// address. Then, use the FindCallerRegs member function to apply the -// rules to the callee frame's register values, yielding the caller -// frame's register values. -class CFIFrameInfo { - public: - // A map from register names onto values. - template class RegisterValueMap: - public map { }; - - // Set the expression for computing a call frame address, return - // address, or register's value. At least the CFA rule and the RA - // rule must be set before calling FindCallerRegs. - void SetCFARule(const string &expression) { cfa_rule_ = expression; } - void SetRARule(const string &expression) { ra_rule_ = expression; } - void SetRegisterRule(const string ®ister_name, const string &expression) { - register_rules_[register_name] = expression; - } - - // Compute the values of the calling frame's registers, according to - // this rule set. Use ValueType in expression evaluation; this - // should be uint32_t on machines with 32-bit addresses, or - // uint64_t on machines with 64-bit addresses. - // - // Return true on success, false otherwise. - // - // MEMORY provides access to the contents of the stack. REGISTERS is - // a dictionary mapping the names of registers whose values are - // known in the current frame to their values. CALLER_REGISTERS is - // populated with the values of the recoverable registers in the - // frame that called the current frame. - // - // In addition, CALLER_REGISTERS[".ra"] will be the return address, - // and CALLER_REGISTERS[".cfa"] will be the call frame address. - // These may be helpful in computing the caller's PC and stack - // pointer, if their values are not explicitly specified. - template - bool FindCallerRegs(const RegisterValueMap ®isters, - const MemoryRegion &memory, - RegisterValueMap *caller_registers) const; - - // Serialize the rules in this object into a string in the format - // of STACK CFI records. - string Serialize() const; - - private: - - // A map from register names onto evaluation rules. - typedef map RuleMap; - - // In this type, a "postfix expression" is an expression of the sort - // interpreted by google_breakpad::PostfixEvaluator. - - // A postfix expression for computing the current frame's CFA (call - // frame address). The CFA is a reference address for the frame that - // remains unchanged throughout the frame's lifetime. You should - // evaluate this expression with a dictionary initially populated - // with the values of the current frame's known registers. - string cfa_rule_; - - // The following expressions should be evaluated with a dictionary - // initially populated with the values of the current frame's known - // registers, and with ".cfa" set to the result of evaluating the - // cfa_rule expression, above. - - // A postfix expression for computing the current frame's return - // address. - string ra_rule_; - - // For a register named REG, rules[REG] is a postfix expression - // which leaves the value of REG in the calling frame on the top of - // the stack. You should evaluate this expression - RuleMap register_rules_; -}; - -// A parser for STACK CFI-style rule sets. -// This may seem bureaucratic: there's no legitimate run-time reason -// to use a parser/handler pattern for this, as it's not a likely -// reuse boundary. But doing so makes finer-grained unit testing -// possible. -class CFIRuleParser { - public: - - class Handler { - public: - Handler() { } - virtual ~Handler() { } - - // The input specifies EXPRESSION as the CFA/RA computation rule. - virtual void CFARule(const string &expression) = 0; - virtual void RARule(const string &expression) = 0; - - // The input specifies EXPRESSION as the recovery rule for register NAME. - virtual void RegisterRule(const string &name, const string &expression) = 0; - }; - - // Construct a parser which feeds its results to HANDLER. - CFIRuleParser(Handler *handler) : handler_(handler) { } - - // Parse RULE_SET as a set of CFA computation and RA/register - // recovery rules, as appearing in STACK CFI records. Report the - // results of parsing by making the appropriate calls to handler_. - // Return true if parsing was successful, false otherwise. - bool Parse(const string &rule_set); - - private: - // Report any accumulated rule to handler_ - bool Report(); - - // The handler to which the parser reports its findings. - Handler *handler_; - - // Working data. - string name_, expression_; -}; - -// A handler for rule set parsing that populates a CFIFrameInfo with -// the results. -class CFIFrameInfoParseHandler: public CFIRuleParser::Handler { - public: - // Populate FRAME_INFO with the results of parsing. - CFIFrameInfoParseHandler(CFIFrameInfo *frame_info) - : frame_info_(frame_info) { } - - void CFARule(const string &expression); - void RARule(const string &expression); - void RegisterRule(const string &name, const string &expression); - - private: - CFIFrameInfo *frame_info_; -}; - -// A utility class template for simple 'STACK CFI'-driven stack walkers. -// Given a CFIFrameInfo instance, a table describing the architecture's -// register set, and a context holding the last frame's registers, an -// instance of this class can populate a new context with the caller's -// registers. -// -// This class template doesn't use any internal knowledge of CFIFrameInfo -// or the other stack walking structures; it just uses the public interface -// of CFIFrameInfo to do the usual things. But the logic it handles should -// be common to many different architectures' stack walkers, so wrapping it -// up in a class should allow the walkers to share code. -// -// RegisterType should be the type of this architecture's registers, either -// uint32_t or uint64_t. RawContextType should be the raw context -// structure type for this architecture. -template -class SimpleCFIWalker { - public: - // A structure describing one architecture register. - struct RegisterSet { - // The register name, as it appears in STACK CFI rules. - const char *name; - - // An alternate name that the register's value might be found - // under in a register value dictionary, or NULL. When generating - // names, prefer NAME to this value. It's common to list ".cfa" as - // an alternative name for the stack pointer, and ".ra" as an - // alternative name for the instruction pointer. - const char *alternate_name; - - // True if the callee is expected to preserve the value of this - // register. If this flag is true for some register R, and the STACK - // CFI records provide no rule to recover R, then SimpleCFIWalker - // assumes that the callee has not changed R's value, and the caller's - // value for R is that currently in the callee's context. - bool callee_saves; - - // The ContextValidity flag representing the register's presence. - int validity_flag; - - // A pointer to the RawContextType member that holds the - // register's value. - RegisterType RawContextType::*context_member; - }; - - // Create a simple CFI-based frame walker, given a description of the - // architecture's register set. REGISTER_MAP is an array of - // RegisterSet structures; MAP_SIZE is the number of elements in the - // array. - SimpleCFIWalker(const RegisterSet *register_map, size_t map_size) - : register_map_(register_map), map_size_(map_size) { } - - // Compute the calling frame's raw context given the callee's raw - // context. - // - // Given: - // - // - MEMORY, holding the stack's contents, - // - CFI_FRAME_INFO, describing the called function, - // - CALLEE_CONTEXT, holding the called frame's registers, and - // - CALLEE_VALIDITY, indicating which registers in CALLEE_CONTEXT are valid, - // - // fill in CALLER_CONTEXT with the caller's register values, and set - // CALLER_VALIDITY to indicate which registers are valid in - // CALLER_CONTEXT. Return true on success, or false on failure. - bool FindCallerRegisters(const MemoryRegion &memory, - const CFIFrameInfo &cfi_frame_info, - const RawContextType &callee_context, - int callee_validity, - RawContextType *caller_context, - int *caller_validity) const; - - private: - const RegisterSet *register_map_; - size_t map_size_; -}; - -} // namespace google_breakpad - -#include "cfi_frame_info-inl.h" - -#endif // PROCESSOR_CFI_FRAME_INFO_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info_unittest.cc deleted file mode 100644 index 542b28492..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info_unittest.cc +++ /dev/null @@ -1,546 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// cfi_frame_info_unittest.cc: Unit tests for CFIFrameInfo, -// CFIRuleParser, CFIFrameInfoParseHandler, and SimpleCFIWalker. - -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "processor/cfi_frame_info.h" -#include "google_breakpad/processor/memory_region.h" - -using google_breakpad::CFIFrameInfo; -using google_breakpad::CFIFrameInfoParseHandler; -using google_breakpad::CFIRuleParser; -using google_breakpad::MemoryRegion; -using google_breakpad::SimpleCFIWalker; -using testing::_; -using testing::A; -using testing::AtMost; -using testing::DoAll; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class MockMemoryRegion: public MemoryRegion { - public: - MOCK_CONST_METHOD0(GetBase, uint64_t()); - MOCK_CONST_METHOD0(GetSize, uint32_t()); - MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint8_t *)); - MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint16_t *)); - MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint32_t *)); - MOCK_CONST_METHOD2(GetMemoryAtAddress, bool(uint64_t, uint64_t *)); - MOCK_CONST_METHOD0(Print, void()); -}; - -// Handy definitions for all tests. -struct CFIFixture { - - // Set up the mock memory object to expect no references. - void ExpectNoMemoryReferences() { - EXPECT_CALL(memory, GetBase()).Times(0); - EXPECT_CALL(memory, GetSize()).Times(0); - EXPECT_CALL(memory, GetMemoryAtAddress(_, A())).Times(0); - EXPECT_CALL(memory, GetMemoryAtAddress(_, A())).Times(0); - EXPECT_CALL(memory, GetMemoryAtAddress(_, A())).Times(0); - EXPECT_CALL(memory, GetMemoryAtAddress(_, A())).Times(0); - } - - CFIFrameInfo cfi; - MockMemoryRegion memory; - CFIFrameInfo::RegisterValueMap registers, caller_registers; -}; - -class Simple: public CFIFixture, public Test { }; - -// FindCallerRegs should fail if no .cfa rule is provided. -TEST_F(Simple, NoCFA) { - ExpectNoMemoryReferences(); - - cfi.SetRARule("0"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(".ra: 0", cfi.Serialize()); -} - -// FindCallerRegs should fail if no .ra rule is provided. -TEST_F(Simple, NoRA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("0"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(".cfa: 0", cfi.Serialize()); -} - -TEST_F(Simple, SetCFAAndRARule) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("330903416631436410"); - cfi.SetRARule("5870666104170902211"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(2U, caller_registers.size()); - ASSERT_EQ(330903416631436410ULL, caller_registers[".cfa"]); - ASSERT_EQ(5870666104170902211ULL, caller_registers[".ra"]); - - ASSERT_EQ(".cfa: 330903416631436410 .ra: 5870666104170902211", - cfi.Serialize()); -} - -TEST_F(Simple, SetManyRules) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("$temp1 68737028 = $temp2 61072337 = $temp1 $temp2 -"); - cfi.SetRARule(".cfa 99804755 +"); - cfi.SetRegisterRule("register1", ".cfa 54370437 *"); - cfi.SetRegisterRule("vodkathumbscrewingly", "24076308 .cfa +"); - cfi.SetRegisterRule("pubvexingfjordschmaltzy", ".cfa 29801007 -"); - cfi.SetRegisterRule("uncopyrightables", "92642917 .cfa /"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(6U, caller_registers.size()); - ASSERT_EQ(7664691U, caller_registers[".cfa"]); - ASSERT_EQ(107469446U, caller_registers[".ra"]); - ASSERT_EQ(416732599139967ULL, caller_registers["register1"]); - ASSERT_EQ(31740999U, caller_registers["vodkathumbscrewingly"]); - ASSERT_EQ(-22136316ULL, caller_registers["pubvexingfjordschmaltzy"]); - ASSERT_EQ(12U, caller_registers["uncopyrightables"]); - ASSERT_EQ(".cfa: $temp1 68737028 = $temp2 61072337 = $temp1 $temp2 - " - ".ra: .cfa 99804755 + " - "pubvexingfjordschmaltzy: .cfa 29801007 - " - "register1: .cfa 54370437 * " - "uncopyrightables: 92642917 .cfa / " - "vodkathumbscrewingly: 24076308 .cfa +", - cfi.Serialize()); -} - -TEST_F(Simple, RulesOverride) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("330903416631436410"); - cfi.SetRARule("5870666104170902211"); - cfi.SetCFARule("2828089117179001"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(2U, caller_registers.size()); - ASSERT_EQ(2828089117179001ULL, caller_registers[".cfa"]); - ASSERT_EQ(5870666104170902211ULL, caller_registers[".ra"]); - ASSERT_EQ(".cfa: 2828089117179001 .ra: 5870666104170902211", - cfi.Serialize()); -} - -class Scope: public CFIFixture, public Test { }; - -// There should be no value for .cfa in scope when evaluating the CFA rule. -TEST_F(Scope, CFALacksCFA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule(".cfa"); - cfi.SetRARule("0"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); -} - -// There should be no value for .ra in scope when evaluating the CFA rule. -TEST_F(Scope, CFALacksRA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule(".ra"); - cfi.SetRARule("0"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); -} - -// The current frame's registers should be in scope when evaluating -// the CFA rule. -TEST_F(Scope, CFASeesCurrentRegs) { - ExpectNoMemoryReferences(); - - registers[".baraminology"] = 0x06a7bc63e4f13893ULL; - registers[".ornithorhynchus"] = 0x5e0bf850bafce9d2ULL; - cfi.SetCFARule(".baraminology .ornithorhynchus +"); - cfi.SetRARule("0"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(2U, caller_registers.size()); - ASSERT_EQ(0x06a7bc63e4f13893ULL + 0x5e0bf850bafce9d2ULL, - caller_registers[".cfa"]); -} - -// .cfa should be in scope in the return address expression. -TEST_F(Scope, RASeesCFA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("48364076"); - cfi.SetRARule(".cfa"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(2U, caller_registers.size()); - ASSERT_EQ(48364076U, caller_registers[".ra"]); -} - -// There should be no value for .ra in scope when evaluating the CFA rule. -TEST_F(Scope, RALacksRA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("0"); - cfi.SetRARule(".ra"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); -} - -// The current frame's registers should be in scope in the return -// address expression. -TEST_F(Scope, RASeesCurrentRegs) { - ExpectNoMemoryReferences(); - - registers["noachian"] = 0x54dc4a5d8e5eb503ULL; - cfi.SetCFARule("10359370"); - cfi.SetRARule("noachian"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(2U, caller_registers.size()); - ASSERT_EQ(0x54dc4a5d8e5eb503ULL, caller_registers[".ra"]); -} - -// .cfa should be in scope for register rules. -TEST_F(Scope, RegistersSeeCFA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("6515179"); - cfi.SetRARule(".cfa"); - cfi.SetRegisterRule("rogerian", ".cfa"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(3U, caller_registers.size()); - ASSERT_EQ(6515179U, caller_registers["rogerian"]); -} - -// The return address should not be in scope for register rules. -TEST_F(Scope, RegsLackRA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("42740329"); - cfi.SetRARule("27045204"); - cfi.SetRegisterRule("$r1", ".ra"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); -} - -// Register rules can see the current frame's register values. -TEST_F(Scope, RegsSeeRegs) { - ExpectNoMemoryReferences(); - - registers["$r1"] = 0x6ed3582c4bedb9adULL; - registers["$r2"] = 0xd27d9e742b8df6d0ULL; - cfi.SetCFARule("88239303"); - cfi.SetRARule("30503835"); - cfi.SetRegisterRule("$r1", "$r1 42175211 = $r2"); - cfi.SetRegisterRule("$r2", "$r2 21357221 = $r1"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(4U, caller_registers.size()); - ASSERT_EQ(0xd27d9e742b8df6d0ULL, caller_registers["$r1"]); - ASSERT_EQ(0x6ed3582c4bedb9adULL, caller_registers["$r2"]); -} - -// Each rule's temporaries are separate. -TEST_F(Scope, SeparateTempsRA) { - ExpectNoMemoryReferences(); - - cfi.SetCFARule("$temp1 76569129 = $temp1"); - cfi.SetRARule("0"); - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - - cfi.SetCFARule("$temp1 76569129 = $temp1"); - cfi.SetRARule("$temp1"); - ASSERT_FALSE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); -} - -class MockCFIRuleParserHandler: public CFIRuleParser::Handler { - public: - MOCK_METHOD1(CFARule, void(const string &)); - MOCK_METHOD1(RARule, void(const string &)); - MOCK_METHOD2(RegisterRule, void(const string &, const string &)); -}; - -// A fixture class for testing CFIRuleParser. -class CFIParserFixture { - public: - CFIParserFixture() : parser(&mock_handler) { - // Expect no parsing results to be reported to mock_handler. Individual - // tests can override this. - EXPECT_CALL(mock_handler, CFARule(_)).Times(0); - EXPECT_CALL(mock_handler, RARule(_)).Times(0); - EXPECT_CALL(mock_handler, RegisterRule(_, _)).Times(0); - } - - MockCFIRuleParserHandler mock_handler; - CFIRuleParser parser; -}; - -class Parser: public CFIParserFixture, public Test { }; - -TEST_F(Parser, Empty) { - EXPECT_FALSE(parser.Parse("")); -} - -TEST_F(Parser, LoneColon) { - EXPECT_FALSE(parser.Parse(":")); -} - -TEST_F(Parser, CFANoExpr) { - EXPECT_FALSE(parser.Parse(".cfa:")); -} - -TEST_F(Parser, CFANoColonNoExpr) { - EXPECT_FALSE(parser.Parse(".cfa")); -} - -TEST_F(Parser, RANoExpr) { - EXPECT_FALSE(parser.Parse(".ra:")); -} - -TEST_F(Parser, RANoColonNoExpr) { - EXPECT_FALSE(parser.Parse(".ra")); -} - -TEST_F(Parser, RegNoExpr) { - EXPECT_FALSE(parser.Parse("reg:")); -} - -TEST_F(Parser, NoName) { - EXPECT_FALSE(parser.Parse("expr")); -} - -TEST_F(Parser, NoNameTwo) { - EXPECT_FALSE(parser.Parse("expr1 expr2")); -} - -TEST_F(Parser, StartsWithExpr) { - EXPECT_FALSE(parser.Parse("expr1 reg: expr2")); -} - -TEST_F(Parser, CFA) { - EXPECT_CALL(mock_handler, CFARule("spleen")).WillOnce(Return()); - EXPECT_TRUE(parser.Parse(".cfa: spleen")); -} - -TEST_F(Parser, RA) { - EXPECT_CALL(mock_handler, RARule("notoriety")).WillOnce(Return()); - EXPECT_TRUE(parser.Parse(".ra: notoriety")); -} - -TEST_F(Parser, Reg) { - EXPECT_CALL(mock_handler, RegisterRule("nemo", "mellifluous")) - .WillOnce(Return()); - EXPECT_TRUE(parser.Parse("nemo: mellifluous")); -} - -TEST_F(Parser, CFARARegs) { - EXPECT_CALL(mock_handler, CFARule("cfa expression")).WillOnce(Return()); - EXPECT_CALL(mock_handler, RARule("ra expression")).WillOnce(Return()); - EXPECT_CALL(mock_handler, RegisterRule("galba", "praetorian")) - .WillOnce(Return()); - EXPECT_CALL(mock_handler, RegisterRule("otho", "vitellius")) - .WillOnce(Return()); - EXPECT_TRUE(parser.Parse(".cfa: cfa expression .ra: ra expression " - "galba: praetorian otho: vitellius")); -} - -TEST_F(Parser, Whitespace) { - EXPECT_CALL(mock_handler, RegisterRule("r1", "r1 expression")) - .WillOnce(Return()); - EXPECT_CALL(mock_handler, RegisterRule("r2", "r2 expression")) - .WillOnce(Return()); - EXPECT_TRUE(parser.Parse(" r1:\tr1\nexpression \tr2:\t\rr2\r\n " - "expression \n")); -} - -TEST_F(Parser, WhitespaceLoneColon) { - EXPECT_FALSE(parser.Parse(" \n:\t ")); -} - -TEST_F(Parser, EmptyName) { - EXPECT_CALL(mock_handler, RegisterRule("reg", _)) - .Times(AtMost(1)) - .WillRepeatedly(Return()); - EXPECT_FALSE(parser.Parse("reg: expr1 : expr2")); -} - -TEST_F(Parser, RuleLoneColon) { - EXPECT_CALL(mock_handler, RegisterRule("r1", "expr")) - .Times(AtMost(1)) - .WillRepeatedly(Return()); - EXPECT_FALSE(parser.Parse(" r1: expr :")); -} - -TEST_F(Parser, RegNoExprRule) { - EXPECT_CALL(mock_handler, RegisterRule("r1", "expr")) - .Times(AtMost(1)) - .WillRepeatedly(Return()); - EXPECT_FALSE(parser.Parse("r0: r1: expr")); -} - -class ParseHandlerFixture: public CFIFixture { - public: - ParseHandlerFixture() : CFIFixture(), handler(&cfi) { } - CFIFrameInfoParseHandler handler; -}; - -class ParseHandler: public ParseHandlerFixture, public Test { }; - -TEST_F(ParseHandler, CFARARule) { - handler.CFARule("reg-for-cfa"); - handler.RARule("reg-for-ra"); - registers["reg-for-cfa"] = 0x268a9a4a3821a797ULL; - registers["reg-for-ra"] = 0x6301b475b8b91c02ULL; - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]); - ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]); -} - -TEST_F(ParseHandler, RegisterRules) { - handler.CFARule("reg-for-cfa"); - handler.RARule("reg-for-ra"); - handler.RegisterRule("reg1", "reg-for-reg1"); - handler.RegisterRule("reg2", "reg-for-reg2"); - registers["reg-for-cfa"] = 0x268a9a4a3821a797ULL; - registers["reg-for-ra"] = 0x6301b475b8b91c02ULL; - registers["reg-for-reg1"] = 0x06cde8e2ff062481ULL; - registers["reg-for-reg2"] = 0xff0c4f76403173e2ULL; - ASSERT_TRUE(cfi.FindCallerRegs(registers, memory, - &caller_registers)); - ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]); - ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]); - ASSERT_EQ(0x06cde8e2ff062481ULL, caller_registers["reg1"]); - ASSERT_EQ(0xff0c4f76403173e2ULL, caller_registers["reg2"]); -} - -struct SimpleCFIWalkerFixture { - struct RawContext { - uint64_t r0, r1, r2, r3, r4, sp, pc; - }; - enum Validity { - R0_VALID = 0x01, - R1_VALID = 0x02, - R2_VALID = 0x04, - R3_VALID = 0x08, - R4_VALID = 0x10, - SP_VALID = 0x20, - PC_VALID = 0x40 - }; - typedef SimpleCFIWalker CFIWalker; - - SimpleCFIWalkerFixture() - : walker(register_map, - sizeof(register_map) / sizeof(register_map[0])) { } - - static CFIWalker::RegisterSet register_map[7]; - CFIFrameInfo call_frame_info; - CFIWalker walker; - MockMemoryRegion memory; - RawContext callee_context, caller_context; -}; - -SimpleCFIWalkerFixture::CFIWalker::RegisterSet -SimpleCFIWalkerFixture::register_map[7] = { - { "r0", NULL, true, R0_VALID, &RawContext::r0 }, - { "r1", NULL, true, R1_VALID, &RawContext::r1 }, - { "r2", NULL, false, R2_VALID, &RawContext::r2 }, - { "r3", NULL, false, R3_VALID, &RawContext::r3 }, - { "r4", NULL, true, R4_VALID, &RawContext::r4 }, - { "sp", ".cfa", true, SP_VALID, &RawContext::sp }, - { "pc", ".ra", true, PC_VALID, &RawContext::pc }, -}; - -class SimpleWalker: public SimpleCFIWalkerFixture, public Test { }; - -TEST_F(SimpleWalker, Walk) { - // Stack_top is the current stack pointer, pointing to the lowest - // address of a frame that looks like this (all 64-bit words): - // - // sp -> saved r0 - // garbage - // return address - // cfa -> - // - // r0 has been saved on the stack. - // r1 has been saved in r2. - // r2 and r3 are not recoverable. - // r4 is not recoverable, even though it is a callee-saves register. - // Some earlier frame's unwinder must have failed to recover it. - - uint64_t stack_top = 0x83254944b20d5512ULL; - - // Saved r0. - EXPECT_CALL(memory, - GetMemoryAtAddress(stack_top, A())) - .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xdc1975eba8602302ULL), - Return(true))); - // Saved return address. - EXPECT_CALL(memory, - GetMemoryAtAddress(stack_top + 16, A())) - .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xba5ad6d9acce28deULL), - Return(true))); - - call_frame_info.SetCFARule("sp 24 +"); - call_frame_info.SetRARule(".cfa 8 - ^"); - call_frame_info.SetRegisterRule("r0", ".cfa 24 - ^"); - call_frame_info.SetRegisterRule("r1", "r2"); - - callee_context.r0 = 0x94e030ca79edd119ULL; - callee_context.r1 = 0x937b4d7e95ce52d9ULL; - callee_context.r2 = 0x5fe0027416b8b62aULL; // caller's r1 - // callee_context.r3 is not valid in callee. - // callee_context.r4 is not valid in callee. - callee_context.sp = stack_top; - callee_context.pc = 0x25b21b224311d280ULL; - int callee_validity = R0_VALID | R1_VALID | R2_VALID | SP_VALID | PC_VALID; - - memset(&caller_context, 0, sizeof(caller_context)); - - int caller_validity; - EXPECT_TRUE(walker.FindCallerRegisters(memory, call_frame_info, - callee_context, callee_validity, - &caller_context, &caller_validity)); - EXPECT_EQ(R0_VALID | R1_VALID | SP_VALID | PC_VALID, caller_validity); - EXPECT_EQ(0xdc1975eba8602302ULL, caller_context.r0); - EXPECT_EQ(0x5fe0027416b8b62aULL, caller_context.r1); - EXPECT_EQ(stack_top + 24, caller_context.sp); - EXPECT_EQ(0xba5ad6d9acce28deULL, caller_context.pc); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h deleted file mode 100644 index 4c0ad41f9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// contained_range_map-inl.h: Hierarchically-organized range map implementation. -// -// See contained_range_map.h for documentation. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_CONTAINED_RANGE_MAP_INL_H__ -#define PROCESSOR_CONTAINED_RANGE_MAP_INL_H__ - -#include "processor/contained_range_map.h" - -#include - -#include "processor/logging.h" - - -namespace google_breakpad { - - -template -ContainedRangeMap::~ContainedRangeMap() { - // Clear frees the children pointed to by the map, and frees the map itself. - Clear(); -} - - -template -bool ContainedRangeMap::StoreRange( - const AddressType &base, const AddressType &size, const EntryType &entry) { - AddressType high = base + size - 1; - - // Check for undersize or overflow. - if (size <= 0 || high < base) { - //TODO(nealsid) We are commenting this out in order to prevent - // excessive logging. We plan to move to better logging as this - // failure happens quite often and is expected(see comment in - // basic_source_line_resolver.cc:671). - // BPLOG(INFO) << "StoreRange failed, " << HexString(base) << "+" - // << HexString(size) << ", " << HexString(high); - return false; - } - - if (!map_) - map_ = new AddressToRangeMap(); - - MapIterator iterator_base = map_->lower_bound(base); - MapIterator iterator_high = map_->lower_bound(high); - MapIterator iterator_end = map_->end(); - - if (iterator_base == iterator_high && iterator_base != iterator_end && - base >= iterator_base->second->base_) { - // The new range is entirely within an existing child range. - - // If the new range's geometry is exactly equal to an existing child - // range's, it violates the containment rules, and an attempt to store - // it must fail. iterator_base->first contains the key, which was the - // containing child's high address. - if (iterator_base->second->base_ == base && iterator_base->first == high) { - // TODO(nealsid): See the TODO above on why this is commented out. -// BPLOG(INFO) << "StoreRange failed, identical range is already " -// "present: " << HexString(base) << "+" << HexString(size); - return false; - } - - // Pass the new range on to the child to attempt to store. - return iterator_base->second->StoreRange(base, size, entry); - } - - // iterator_high might refer to an irrelevant range: one whose base address - // is higher than the new range's high address. Set contains_high to true - // only if iterator_high refers to a range that is at least partially - // within the new range. - bool contains_high = iterator_high != iterator_end && - high >= iterator_high->second->base_; - - // If the new range encompasses any existing child ranges, it must do so - // fully. Partial containment isn't allowed. - if ((iterator_base != iterator_end && base > iterator_base->second->base_) || - (contains_high && high < iterator_high->first)) { - // TODO(mmentovai): Some symbol files will trip this check frequently - // on STACK lines. Too many messages will be produced. These are more - // suitable for a DEBUG channel than an INFO channel. - // BPLOG(INFO) << "StoreRange failed, new range partially contains " - // "existing range: " << HexString(base) << "+" << - // HexString(size); - return false; - } - - // When copying and erasing contained ranges, the "end" iterator needs to - // point one past the last item of the range to copy. If contains_high is - // false, the iterator's already in the right place; the increment is safe - // because contains_high can't be true if iterator_high == iterator_end. - if (contains_high) - ++iterator_high; - - // Optimization: if the iterators are equal, no child ranges would be - // moved. Create the new child range with a NULL map to conserve space - // in leaf nodes, of which there will be many. - AddressToRangeMap *child_map = NULL; - - if (iterator_base != iterator_high) { - // The children of this range that are contained by the new range must - // be transferred over to the new range. Create the new child range map - // and copy the pointers to range maps it should contain into it. - child_map = new AddressToRangeMap(iterator_base, iterator_high); - - // Remove the copied child pointers from this range's map of children. - map_->erase(iterator_base, iterator_high); - } - - // Store the new range in the map by its high address. Any children that - // the new child range contains were formerly children of this range but - // are now this range's grandchildren. Ownership of these is transferred - // to the new child range. - map_->insert(MapValue(high, - new ContainedRangeMap(base, entry, child_map))); - return true; -} - - -template -bool ContainedRangeMap::RetrieveRange( - const AddressType &address, EntryType *entry) const { - BPLOG_IF(ERROR, !entry) << "ContainedRangeMap::RetrieveRange requires " - "|entry|"; - assert(entry); - - // If nothing was ever stored, then there's nothing to retrieve. - if (!map_) - return false; - - // Get an iterator to the child range whose high address is equal to or - // greater than the supplied address. If the supplied address is higher - // than all of the high addresses in the range, then this range does not - // contain a child at address, so return false. If the supplied address - // is lower than the base address of the child range, then it is not within - // the child range, so return false. - MapConstIterator iterator = map_->lower_bound(address); - if (iterator == map_->end() || address < iterator->second->base_) - return false; - - // The child in iterator->second contains the specified address. Find out - // if it has a more-specific descendant that also contains it. If it does, - // it will set |entry| appropriately. If not, set |entry| to the child. - if (!iterator->second->RetrieveRange(address, entry)) - *entry = iterator->second->entry_; - - return true; -} - - -template -void ContainedRangeMap::Clear() { - if (map_) { - MapConstIterator end = map_->end(); - for (MapConstIterator child = map_->begin(); child != end; ++child) - delete child->second; - - delete map_; - map_ = NULL; - } -} - - -} // namespace google_breakpad - - -#endif // PROCESSOR_CONTAINED_RANGE_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map.h b/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map.h deleted file mode 100644 index 1015ae8cf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// contained_range_map.h: Hierarchically-organized range maps. -// -// A contained range map is similar to a standard range map, except it allows -// objects to be organized hierarchically. A contained range map allows -// objects to contain other objects. It is not sensitive to the order that -// objects are added to the map: larger, more general, containing objects -// may be added either before or after smaller, more specific, contained -// ones. -// -// Contained range maps guarantee that each object may only contain smaller -// objects than itself, and that a parent object may only contain child -// objects located entirely within the parent's address space. Attempts -// to introduce objects (via StoreRange) that violate these rules will fail. -// Retrieval (via RetrieveRange) always returns the most specific (smallest) -// object that contains the address being queried. Note that while it is -// not possible to insert two objects into a map that have exactly the same -// geometry (base address and size), it is possible to completely mask a -// larger object by inserting smaller objects that entirely fill the larger -// object's address space. -// -// Internally, contained range maps are implemented as a tree. Each tree -// node except for the root node describes an object in the map. Each node -// maintains its list of children in a map similar to a standard range map, -// keyed by the highest address that each child occupies. Each node's -// children occupy address ranges entirely within the node. The root node -// is the only node directly accessible to the user, and represents the -// entire address space. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_CONTAINED_RANGE_MAP_H__ -#define PROCESSOR_CONTAINED_RANGE_MAP_H__ - - -#include - - -namespace google_breakpad { - -// Forward declarations (for later friend declarations of specialized template). -template class ContainedRangeMapSerializer; - -template -class ContainedRangeMap { - public: - // The default constructor creates a ContainedRangeMap with no geometry - // and no entry, and as such is only suitable for the root node of a - // ContainedRangeMap tree. - ContainedRangeMap() : base_(), entry_(), map_(NULL) {} - - ~ContainedRangeMap(); - - // Inserts a range into the map. If the new range is encompassed by - // an existing child range, the new range is passed into the child range's - // StoreRange method. If the new range encompasses any existing child - // ranges, those child ranges are moved to the new range, becoming - // grandchildren of this ContainedRangeMap. Returns false for a - // parameter error, or if the ContainedRangeMap hierarchy guarantees - // would be violated. - bool StoreRange(const AddressType &base, - const AddressType &size, - const EntryType &entry); - - // Retrieves the most specific (smallest) descendant range encompassing - // the specified address. This method will only return entries held by - // child ranges, and not the entry contained by |this|. This is necessary - // to support a sparsely-populated root range. If no descendant range - // encompasses the address, returns false. - bool RetrieveRange(const AddressType &address, EntryType *entry) const; - - // Removes all children. Note that Clear only removes descendants, - // leaving the node on which it is called intact. Because the only - // meaningful things contained by a root node are descendants, this - // is sufficient to restore an entire ContainedRangeMap to its initial - // empty state when called on the root node. - void Clear(); - - private: - friend class ContainedRangeMapSerializer; - friend class ModuleComparer; - - // AddressToRangeMap stores pointers. This makes reparenting simpler in - // StoreRange, because it doesn't need to copy entire objects. - typedef std::map AddressToRangeMap; - typedef typename AddressToRangeMap::const_iterator MapConstIterator; - typedef typename AddressToRangeMap::iterator MapIterator; - typedef typename AddressToRangeMap::value_type MapValue; - - // Creates a new ContainedRangeMap with the specified base address, entry, - // and initial child map, which may be NULL. This is only used internally - // by ContainedRangeMap when it creates a new child. - ContainedRangeMap(const AddressType &base, const EntryType &entry, - AddressToRangeMap *map) - : base_(base), entry_(entry), map_(map) {} - - // The base address of this range. The high address does not need to - // be stored, because it is used as the key to an object in its parent's - // map, and all ContainedRangeMaps except for the root range are contained - // within maps. The root range does not actually contain an entry, so its - // base_ field is meaningless, and the fact that it has no parent and thus - // no key is unimportant. For this reason, the base_ field should only be - // is accessed on child ContainedRangeMap objects, and never on |this|. - const AddressType base_; - - // The entry corresponding to this range. The root range does not - // actually contain an entry, so its entry_ field is meaningless. For - // this reason, the entry_ field should only be accessed on child - // ContainedRangeMap objects, and never on |this|. - const EntryType entry_; - - // The map containing child ranges, keyed by each child range's high - // address. This is a pointer to avoid allocating map structures for - // leaf nodes, where they are not needed. - AddressToRangeMap *map_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_CONTAINED_RANGE_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map_unittest.cc deleted file mode 100644 index e5910da0d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map_unittest.cc +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// contained_range_map_unittest.cc: Unit tests for ContainedRangeMap -// -// Author: Mark Mentovai - -#include - -#include "processor/contained_range_map-inl.h" - -#include "processor/logging.h" - - -#define ASSERT_TRUE(condition) \ - if (!(condition)) { \ - fprintf(stderr, "FAIL: %s @ %s:%d\n", #condition, __FILE__, __LINE__); \ - return false; \ - } - -#define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition)) - - -namespace { - - -using google_breakpad::ContainedRangeMap; - - -static bool RunTests() { - ContainedRangeMap crm; - - // First, do the StoreRange tests. This validates the containment - // rules. - ASSERT_TRUE (crm.StoreRange(10, 10, 1)); - ASSERT_FALSE(crm.StoreRange(10, 10, 2)); // exactly equal to 1 - ASSERT_FALSE(crm.StoreRange(11, 10, 3)); // begins inside 1 and extends up - ASSERT_FALSE(crm.StoreRange( 9, 10, 4)); // begins below 1 and ends inside - ASSERT_TRUE (crm.StoreRange(11, 9, 5)); // contained by existing - ASSERT_TRUE (crm.StoreRange(12, 7, 6)); - ASSERT_TRUE (crm.StoreRange( 9, 12, 7)); // contains existing - ASSERT_TRUE (crm.StoreRange( 9, 13, 8)); - ASSERT_TRUE (crm.StoreRange( 8, 14, 9)); - ASSERT_TRUE (crm.StoreRange(30, 3, 10)); - ASSERT_TRUE (crm.StoreRange(33, 3, 11)); - ASSERT_TRUE (crm.StoreRange(30, 6, 12)); // storable but totally masked - ASSERT_TRUE (crm.StoreRange(40, 8, 13)); // will be totally masked - ASSERT_TRUE (crm.StoreRange(40, 4, 14)); - ASSERT_TRUE (crm.StoreRange(44, 4, 15)); - ASSERT_FALSE(crm.StoreRange(32, 10, 16)); // begins in #10, ends in #14 - ASSERT_FALSE(crm.StoreRange(50, 0, 17)); // zero length - ASSERT_TRUE (crm.StoreRange(50, 10, 18)); - ASSERT_TRUE (crm.StoreRange(50, 1, 19)); - ASSERT_TRUE (crm.StoreRange(59, 1, 20)); - ASSERT_TRUE (crm.StoreRange(60, 1, 21)); - ASSERT_TRUE (crm.StoreRange(69, 1, 22)); - ASSERT_TRUE (crm.StoreRange(60, 10, 23)); - ASSERT_TRUE (crm.StoreRange(68, 1, 24)); - ASSERT_TRUE (crm.StoreRange(61, 1, 25)); - ASSERT_TRUE (crm.StoreRange(61, 8, 26)); - ASSERT_FALSE(crm.StoreRange(59, 9, 27)); - ASSERT_FALSE(crm.StoreRange(59, 10, 28)); - ASSERT_FALSE(crm.StoreRange(59, 11, 29)); - ASSERT_TRUE (crm.StoreRange(70, 10, 30)); - ASSERT_TRUE (crm.StoreRange(74, 2, 31)); - ASSERT_TRUE (crm.StoreRange(77, 2, 32)); - ASSERT_FALSE(crm.StoreRange(72, 6, 33)); - ASSERT_TRUE (crm.StoreRange(80, 3, 34)); - ASSERT_TRUE (crm.StoreRange(81, 1, 35)); - ASSERT_TRUE (crm.StoreRange(82, 1, 36)); - ASSERT_TRUE (crm.StoreRange(83, 3, 37)); - ASSERT_TRUE (crm.StoreRange(84, 1, 38)); - ASSERT_TRUE (crm.StoreRange(83, 1, 39)); - ASSERT_TRUE (crm.StoreRange(86, 5, 40)); - ASSERT_TRUE (crm.StoreRange(88, 1, 41)); - ASSERT_TRUE (crm.StoreRange(90, 1, 42)); - ASSERT_TRUE (crm.StoreRange(86, 1, 43)); - ASSERT_TRUE (crm.StoreRange(87, 1, 44)); - ASSERT_TRUE (crm.StoreRange(89, 1, 45)); - ASSERT_TRUE (crm.StoreRange(87, 4, 46)); - ASSERT_TRUE (crm.StoreRange(87, 3, 47)); - ASSERT_FALSE(crm.StoreRange(86, 2, 48)); - - // Each element in test_data contains the expected result when calling - // RetrieveRange on an address. - const int test_data[] = { - 0, // 0 - 0, // 1 - 0, // 2 - 0, // 3 - 0, // 4 - 0, // 5 - 0, // 6 - 0, // 7 - 9, // 8 - 7, // 9 - 1, // 10 - 5, // 11 - 6, // 12 - 6, // 13 - 6, // 14 - 6, // 15 - 6, // 16 - 6, // 17 - 6, // 18 - 5, // 19 - 7, // 20 - 8, // 21 - 0, // 22 - 0, // 23 - 0, // 24 - 0, // 25 - 0, // 26 - 0, // 27 - 0, // 28 - 0, // 29 - 10, // 30 - 10, // 31 - 10, // 32 - 11, // 33 - 11, // 34 - 11, // 35 - 0, // 36 - 0, // 37 - 0, // 38 - 0, // 39 - 14, // 40 - 14, // 41 - 14, // 42 - 14, // 43 - 15, // 44 - 15, // 45 - 15, // 46 - 15, // 47 - 0, // 48 - 0, // 49 - 19, // 50 - 18, // 51 - 18, // 52 - 18, // 53 - 18, // 54 - 18, // 55 - 18, // 56 - 18, // 57 - 18, // 58 - 20, // 59 - 21, // 60 - 25, // 61 - 26, // 62 - 26, // 63 - 26, // 64 - 26, // 65 - 26, // 66 - 26, // 67 - 24, // 68 - 22, // 69 - 30, // 70 - 30, // 71 - 30, // 72 - 30, // 73 - 31, // 74 - 31, // 75 - 30, // 76 - 32, // 77 - 32, // 78 - 30, // 79 - 34, // 80 - 35, // 81 - 36, // 82 - 39, // 83 - 38, // 84 - 37, // 85 - 43, // 86 - 44, // 87 - 41, // 88 - 45, // 89 - 42, // 90 - 0, // 91 - 0, // 92 - 0, // 93 - 0, // 94 - 0, // 95 - 0, // 96 - 0, // 97 - 0, // 98 - 0 // 99 - }; - unsigned int test_high = sizeof(test_data) / sizeof(int); - - // Now, do the RetrieveRange tests. This further validates that the - // objects were stored properly and that retrieval returns the correct - // object. - // If GENERATE_TEST_DATA is defined, instead of the retrieval tests, a - // new test_data array will be printed. Exercise caution when doing this. - // Be sure to verify the results manually! -#ifdef GENERATE_TEST_DATA - printf(" const int test_data[] = {\n"); -#endif // GENERATE_TEST_DATA - - for (unsigned int address = 0; address < test_high; ++address) { - int value; - if (!crm.RetrieveRange(address, &value)) - value = 0; - -#ifndef GENERATE_TEST_DATA - // Don't use ASSERT inside the loop because it won't show the failed - // |address|, and the line number will always be the same. That makes - // it difficult to figure out which test failed. - if (value != test_data[address]) { - fprintf(stderr, "FAIL: retrieve %d expected %d observed %d @ %s:%d\n", - address, test_data[address], value, __FILE__, __LINE__); - return false; - } -#else // !GENERATE_TEST_DATA - printf(" %d%c%s // %d\n", value, - address == test_high - 1 ? ' ' : ',', - value < 10 ? " " : "", - address); -#endif // !GENERATE_TEST_DATA - } - -#ifdef GENERATE_TEST_DATA - printf(" };\n"); -#endif // GENERATE_TEST_DATA - - return true; -} - - -} // namespace - - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.cc b/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.cc deleted file mode 100644 index 559022404..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.cc +++ /dev/null @@ -1,240 +0,0 @@ -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// disassembler_x86.cc: simple x86 disassembler. -// -// Provides single step disassembly of x86 bytecode and flags instructions -// that utilize known bad register values. -// -// Author: Cris Neckar - -#include "processor/disassembler_x86.h" - -#include - -namespace google_breakpad { - -DisassemblerX86::DisassemblerX86(const uint8_t *bytecode, - uint32_t size, - uint32_t virtual_address) : - bytecode_(bytecode), - size_(size), - virtual_address_(virtual_address), - current_byte_offset_(0), - current_inst_offset_(0), - instr_valid_(false), - register_valid_(false), - pushed_bad_value_(false), - end_of_block_(false), - flags_(0) { - libdis::x86_init(libdis::opt_none, NULL, NULL); -} - -DisassemblerX86::~DisassemblerX86() { - if (instr_valid_) - libdis::x86_oplist_free(¤t_instr_); - - libdis::x86_cleanup(); -} - -uint32_t DisassemblerX86::NextInstruction() { - if (instr_valid_) - libdis::x86_oplist_free(¤t_instr_); - - if (current_byte_offset_ >= size_) { - instr_valid_ = false; - return 0; - } - uint32_t instr_size = 0; - instr_size = libdis::x86_disasm((unsigned char *)bytecode_, size_, - virtual_address_, current_byte_offset_, - ¤t_instr_); - if (instr_size == 0) { - instr_valid_ = false; - return 0; - } - - current_byte_offset_ += instr_size; - current_inst_offset_++; - instr_valid_ = libdis::x86_insn_is_valid(¤t_instr_); - if (!instr_valid_) - return 0; - - if (current_instr_.type == libdis::insn_return) - end_of_block_ = true; - libdis::x86_op_t *src = libdis::x86_get_src_operand(¤t_instr_); - libdis::x86_op_t *dest = libdis::x86_get_dest_operand(¤t_instr_); - - if (register_valid_) { - switch (current_instr_.group) { - // Flag branches based off of bad registers and calls that occur - // after pushing bad values. - case libdis::insn_controlflow: - switch (current_instr_.type) { - case libdis::insn_jmp: - case libdis::insn_jcc: - case libdis::insn_call: - case libdis::insn_callcc: - if (dest) { - switch (dest->type) { - case libdis::op_expression: - if (dest->data.expression.base.id == bad_register_.id) - flags_ |= DISX86_BAD_BRANCH_TARGET; - break; - case libdis::op_register: - if (dest->data.reg.id == bad_register_.id) - flags_ |= DISX86_BAD_BRANCH_TARGET; - break; - default: - if (pushed_bad_value_ && - (current_instr_.type == libdis::insn_call || - current_instr_.type == libdis::insn_callcc)) - flags_ |= DISX86_BAD_ARGUMENT_PASSED; - break; - } - } - break; - default: - break; - } - break; - - // Flag block data operations that use bad registers for src or dest. - case libdis::insn_string: - if (dest && dest->type == libdis::op_expression && - dest->data.expression.base.id == bad_register_.id) - flags_ |= DISX86_BAD_BLOCK_WRITE; - if (src && src->type == libdis::op_expression && - src->data.expression.base.id == bad_register_.id) - flags_ |= DISX86_BAD_BLOCK_READ; - break; - - // Flag comparisons based on bad data. - case libdis::insn_comparison: - if ((dest && dest->type == libdis::op_expression && - dest->data.expression.base.id == bad_register_.id) || - (src && src->type == libdis::op_expression && - src->data.expression.base.id == bad_register_.id) || - (dest && dest->type == libdis::op_register && - dest->data.reg.id == bad_register_.id) || - (src && src->type == libdis::op_register && - src->data.reg.id == bad_register_.id)) - flags_ |= DISX86_BAD_COMPARISON; - break; - - // Flag any other instruction which derefs a bad register for - // src or dest. - default: - if (dest && dest->type == libdis::op_expression && - dest->data.expression.base.id == bad_register_.id) - flags_ |= DISX86_BAD_WRITE; - if (src && src->type == libdis::op_expression && - src->data.expression.base.id == bad_register_.id) - flags_ |= DISX86_BAD_READ; - break; - } - } - - // When a register is marked as tainted check if it is pushed. - // TODO(cdn): may also want to check for MOVs into EBP offsets. - if (register_valid_ && dest && current_instr_.type == libdis::insn_push) { - switch (dest->type) { - case libdis::op_expression: - if (dest->data.expression.base.id == bad_register_.id || - dest->data.expression.index.id == bad_register_.id) - pushed_bad_value_ = true; - break; - case libdis::op_register: - if (dest->data.reg.id == bad_register_.id) - pushed_bad_value_ = true; - break; - default: - break; - } - } - - // Check if a tainted register value is clobbered. - // For conditional MOVs and XCHGs assume that - // there is a hit. - if (register_valid_) { - switch (current_instr_.type) { - case libdis::insn_xor: - if (src && src->type == libdis::op_register && - dest && dest->type == libdis::op_register && - src->data.reg.id == bad_register_.id && - src->data.reg.id == dest->data.reg.id) - register_valid_ = false; - break; - case libdis::insn_pop: - case libdis::insn_mov: - case libdis::insn_movcc: - if (dest && dest->type == libdis::op_register && - dest->data.reg.id == bad_register_.id) - register_valid_ = false; - break; - case libdis::insn_popregs: - register_valid_ = false; - break; - case libdis::insn_xchg: - case libdis::insn_xchgcc: - if (dest && dest->type == libdis::op_register && - src && src->type == libdis::op_register) { - if (dest->data.reg.id == bad_register_.id) - memcpy(&bad_register_, &src->data.reg, sizeof(libdis::x86_reg_t)); - else if (src->data.reg.id == bad_register_.id) - memcpy(&bad_register_, &dest->data.reg, sizeof(libdis::x86_reg_t)); - } - break; - default: - break; - } - } - - return instr_size; -} - -bool DisassemblerX86::setBadRead() { - if (!instr_valid_) - return false; - - libdis::x86_op_t *operand = libdis::x86_get_src_operand(¤t_instr_); - if (!operand || operand->type != libdis::op_expression) - return false; - - memcpy(&bad_register_, &operand->data.expression.base, - sizeof(libdis::x86_reg_t)); - register_valid_ = true; - return true; -} - -bool DisassemblerX86::setBadWrite() { - if (!instr_valid_) - return false; - - libdis::x86_op_t *operand = libdis::x86_get_dest_operand(¤t_instr_); - if (!operand || operand->type != libdis::op_expression) - return false; - - memcpy(&bad_register_, &operand->data.expression.base, - sizeof(libdis::x86_reg_t)); - register_valid_ = true; - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h b/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h deleted file mode 100644 index 710694107..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h +++ /dev/null @@ -1,127 +0,0 @@ -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// disassembler_x86.h: Basic x86 bytecode disassembler -// -// Provides a simple disassembler which wraps libdisasm. This allows simple -// tests to be run against bytecode to test for various properties. -// -// Author: Cris Neckar - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ - -#include -#include - -#include "google_breakpad/common/breakpad_types.h" - -namespace libdis { -#include "third_party/libdisasm/libdis.h" -} - -namespace google_breakpad { - -enum { - DISX86_NONE = 0x0, - DISX86_BAD_BRANCH_TARGET = 0x1, - DISX86_BAD_ARGUMENT_PASSED = 0x2, - DISX86_BAD_WRITE = 0x4, - DISX86_BAD_BLOCK_WRITE = 0x8, - DISX86_BAD_READ = 0x10, - DISX86_BAD_BLOCK_READ = 0x20, - DISX86_BAD_COMPARISON = 0x40 -}; - -class DisassemblerX86 { - public: - // TODO(cdn): Modify this class to take a MemoryRegion instead of just - // a raw buffer. This will make it easier to use this on arbitrary - // minidumps without first copying out the code segment. - DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t); - ~DisassemblerX86(); - - // This walks to the next instruction in the memory region and - // sets flags based on the type of instruction and previous state - // including any registers marked as bad through setBadRead() - // or setBadWrite(). This method can be called in a loop to - // disassemble until the end of a region. - uint32_t NextInstruction(); - - // Indicates whether the current disassembled instruction was valid. - bool currentInstructionValid() { return instr_valid_; } - - // Returns the current instruction as defined in libdis.h, - // or NULL if the current instruction is not valid. - const libdis::x86_insn_t* currentInstruction() { - return instr_valid_ ? ¤t_instr_ : NULL; - } - - // Returns the type of the current instruction as defined in libdis.h. - libdis::x86_insn_group currentInstructionGroup() { - return current_instr_.group; - } - - // Indicates whether a return instruction has been encountered. - bool endOfBlock() { return end_of_block_; } - - // The flags set so far for the disassembly. - uint16_t flags() { return flags_; } - - // This sets an indicator that the register used to determine - // src or dest for the current instruction is tainted. These can - // be used after examining the current instruction to indicate, - // for example that a bad read or write occurred and the pointer - // stored in the register is currently invalid. - bool setBadRead(); - bool setBadWrite(); - - protected: - const uint8_t *bytecode_; - uint32_t size_; - uint32_t virtual_address_; - uint32_t current_byte_offset_; - uint32_t current_inst_offset_; - - bool instr_valid_; - libdis::x86_insn_t current_instr_; - - // TODO(cdn): Maybe also track an expression's index register. - // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index. - bool register_valid_; - libdis::x86_reg_t bad_register_; - - bool pushed_bad_value_; - bool end_of_block_; - - uint16_t flags_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc deleted file mode 100644 index 352905f20..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - -#include - -#include "breakpad_googletest_includes.h" -#include "processor/disassembler_x86.h" -#include "third_party/libdisasm/libdis.h" - -namespace { - -using google_breakpad::DisassemblerX86; - -unsigned char just_return[] = "\xc3"; // retn - -unsigned char invalid_instruction[] = "\x00"; // invalid - -unsigned char read_eax_jmp_eax[] = - "\x8b\x18" // mov ebx, [eax]; - "\x33\xc9" // xor ebx, ebx; - "\xff\x20" // jmp eax; - "\xc3"; // retn; - -unsigned char write_eax_arg_to_call[] = - "\x89\xa8\x00\x02\x00\x00" // mov [eax+200], ebp; - "\xc1\xeb\x02" // shr ebx, 2; - "\x50" // push eax; - "\xe8\xd1\x24\x77\x88" // call something; - "\xc3"; // retn; - -unsigned char read_edi_stosb[] = - "\x8b\x07" // mov eax, [edi]; - "\x8b\xc8" // mov ecx, eax; - "\xf3\xaa" // rep stosb; - "\xc3"; // retn; - -unsigned char read_clobber_write[] = - "\x03\x18" // add ebx, [eax]; - "\x8b\xc1" // mov eax, ecx; - "\x89\x10" // mov [eax], edx; - "\xc3"; // retn; - -unsigned char read_xchg_write[] = - "\x03\x18" // add ebx, [eax]; - "\x91" // xchg eax, ecx; - "\x89\x18" // mov [eax], ebx; - "\x89\x11" // mov [ecx], edx; - "\xc3"; // retn; - -unsigned char read_cmp[] = - "\x03\x18" // add ebx, [eax]; - "\x83\xf8\x00" // cmp eax, 0; - "\x74\x04" // je +4; - "\xc3"; // retn; - -TEST(DisassemblerX86Test, SimpleReturnInstruction) { - DisassemblerX86 dis(just_return, sizeof(just_return)-1, 0); - EXPECT_EQ(1U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_TRUE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); - const libdis::x86_insn_t* instruction = dis.currentInstruction(); - EXPECT_EQ(libdis::insn_controlflow, instruction->group); - EXPECT_EQ(libdis::insn_return, instruction->type); - EXPECT_EQ(0U, dis.NextInstruction()); - EXPECT_FALSE(dis.currentInstructionValid()); - EXPECT_EQ(NULL, dis.currentInstruction()); -} - -TEST(DisassemblerX86Test, SimpleInvalidInstruction) { - DisassemblerX86 dis(invalid_instruction, sizeof(invalid_instruction)-1, 0); - EXPECT_EQ(0U, dis.NextInstruction()); - EXPECT_FALSE(dis.currentInstructionValid()); -} - -TEST(DisassemblerX86Test, BadReadLeadsToBranch) { - DisassemblerX86 dis(read_eax_jmp_eax, sizeof(read_eax_jmp_eax)-1, 0); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadRead()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_logic, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_BRANCH_TARGET, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); -} - -TEST(DisassemblerX86Test, BadWriteLeadsToPushedArg) { - DisassemblerX86 dis(write_eax_arg_to_call, - sizeof(write_eax_arg_to_call)-1, 0); - EXPECT_EQ(6U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadWrite()); - EXPECT_EQ(3U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); - EXPECT_EQ(1U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(5U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_ARGUMENT_PASSED, dis.flags()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); - EXPECT_FALSE(dis.endOfBlock()); -} - - -TEST(DisassemblerX86Test, BadReadLeadsToBlockWrite) { - DisassemblerX86 dis(read_edi_stosb, sizeof(read_edi_stosb)-1, 0); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadRead()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_BLOCK_WRITE, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_string, dis.currentInstructionGroup()); -} - -TEST(DisassemblerX86Test, BadReadClobberThenWrite) { - DisassemblerX86 dis(read_clobber_write, sizeof(read_clobber_write)-1, 0); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadRead()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); -} - -TEST(DisassemblerX86Test, BadReadXCHGThenWrite) { - DisassemblerX86 dis(read_xchg_write, sizeof(read_xchg_write)-1, 0); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadRead()); - EXPECT_EQ(1U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_WRITE, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); -} - -TEST(DisassemblerX86Test, BadReadThenCMP) { - DisassemblerX86 dis(read_cmp, sizeof(read_cmp)-1, 0); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(0U, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); - EXPECT_TRUE(dis.setBadRead()); - EXPECT_EQ(3U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_comparison, dis.currentInstructionGroup()); - EXPECT_EQ(2U, dis.NextInstruction()); - EXPECT_TRUE(dis.currentInstructionValid()); - EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags()); - EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); -} -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/dump_context.cc b/toolkit/crashreporter/google-breakpad/src/processor/dump_context.cc deleted file mode 100644 index 762d4fe21..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/dump_context.cc +++ /dev/null @@ -1,659 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_context.cc: A (mini/micro)dump context. -// -// See dump_context.h for documentation. - -#include "google_breakpad/processor/dump_context.h" - -#include - -#ifdef _WIN32 -#include -#else // _WIN32 -#include -#endif // _WIN32 - -#include "common/stdio_wrapper.h" -#include "processor/logging.h" - -namespace google_breakpad { - -DumpContext::DumpContext() : context_(), - context_flags_(0) { } - -DumpContext::~DumpContext() { - FreeContext(); -} - -uint32_t DumpContext::GetContextCPU() const { - if (!valid_) { - // Don't log a message, GetContextCPU can be legitimately called with - // valid_ false by FreeContext, which is called by Read. - return 0; - } - - return context_flags_ & MD_CONTEXT_CPU_MASK; -} - -uint32_t DumpContext::GetContextFlags() const { - return context_flags_; -} - -const MDRawContextX86* DumpContext::GetContextX86() const { - if (GetContextCPU() != MD_CONTEXT_X86) { - BPLOG(ERROR) << "DumpContext cannot get x86 context"; - return NULL; - } - - return context_.x86; -} - -const MDRawContextPPC* DumpContext::GetContextPPC() const { - if (GetContextCPU() != MD_CONTEXT_PPC) { - BPLOG(ERROR) << "DumpContext cannot get ppc context"; - return NULL; - } - - return context_.ppc; -} - -const MDRawContextPPC64* DumpContext::GetContextPPC64() const { - if (GetContextCPU() != MD_CONTEXT_PPC64) { - BPLOG(ERROR) << "DumpContext cannot get ppc64 context"; - return NULL; - } - - return context_.ppc64; -} - -const MDRawContextAMD64* DumpContext::GetContextAMD64() const { - if (GetContextCPU() != MD_CONTEXT_AMD64) { - BPLOG(ERROR) << "DumpContext cannot get amd64 context"; - return NULL; - } - - return context_.amd64; -} - -const MDRawContextSPARC* DumpContext::GetContextSPARC() const { - if (GetContextCPU() != MD_CONTEXT_SPARC) { - BPLOG(ERROR) << "DumpContext cannot get sparc context"; - return NULL; - } - - return context_.ctx_sparc; -} - -const MDRawContextARM* DumpContext::GetContextARM() const { - if (GetContextCPU() != MD_CONTEXT_ARM) { - BPLOG(ERROR) << "DumpContext cannot get arm context"; - return NULL; - } - - return context_.arm; -} - -const MDRawContextARM64* DumpContext::GetContextARM64() const { - if (GetContextCPU() != MD_CONTEXT_ARM64) { - BPLOG(ERROR) << "DumpContext cannot get arm64 context"; - return NULL; - } - - return context_.arm64; -} - -const MDRawContextMIPS* DumpContext::GetContextMIPS() const { - if ((GetContextCPU() != MD_CONTEXT_MIPS) && - (GetContextCPU() != MD_CONTEXT_MIPS64)) { - BPLOG(ERROR) << "DumpContext cannot get MIPS context"; - return NULL; - } - - return context_.ctx_mips; -} - -bool DumpContext::GetInstructionPointer(uint64_t* ip) const { - BPLOG_IF(ERROR, !ip) << "DumpContext::GetInstructionPointer requires |ip|"; - assert(ip); - *ip = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid DumpContext for GetInstructionPointer"; - return false; - } - - switch (GetContextCPU()) { - case MD_CONTEXT_AMD64: - *ip = GetContextAMD64()->rip; - break; - case MD_CONTEXT_ARM: - *ip = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_PC]; - break; - case MD_CONTEXT_ARM64: - *ip = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_PC]; - break; - case MD_CONTEXT_PPC: - *ip = GetContextPPC()->srr0; - break; - case MD_CONTEXT_PPC64: - *ip = GetContextPPC64()->srr0; - break; - case MD_CONTEXT_SPARC: - *ip = GetContextSPARC()->pc; - break; - case MD_CONTEXT_X86: - *ip = GetContextX86()->eip; - break; - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: - *ip = GetContextMIPS()->epc; - break; - default: - // This should never happen. - BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer"; - return false; - } - return true; -} - -bool DumpContext::GetStackPointer(uint64_t* sp) const { - BPLOG_IF(ERROR, !sp) << "DumpContext::GetStackPointer requires |sp|"; - assert(sp); - *sp = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid DumpContext for GetStackPointer"; - return false; - } - - switch (GetContextCPU()) { - case MD_CONTEXT_AMD64: - *sp = GetContextAMD64()->rsp; - break; - case MD_CONTEXT_ARM: - *sp = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_SP]; - break; - case MD_CONTEXT_ARM64: - *sp = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_SP]; - break; - case MD_CONTEXT_PPC: - *sp = GetContextPPC()->gpr[MD_CONTEXT_PPC_REG_SP]; - break; - case MD_CONTEXT_PPC64: - *sp = GetContextPPC64()->gpr[MD_CONTEXT_PPC64_REG_SP]; - break; - case MD_CONTEXT_SPARC: - *sp = GetContextSPARC()->g_r[MD_CONTEXT_SPARC_REG_SP]; - break; - case MD_CONTEXT_X86: - *sp = GetContextX86()->esp; - break; - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: - *sp = GetContextMIPS()->iregs[MD_CONTEXT_MIPS_REG_SP]; - break; - default: - // This should never happen. - BPLOG(ERROR) << "Unknown CPU architecture in GetStackPointer"; - return false; - } - return true; -} - -void DumpContext::SetContextFlags(uint32_t context_flags) { - context_flags_ = context_flags; -} - -void DumpContext::SetContextX86(MDRawContextX86* x86) { - context_.x86 = x86; -} - -void DumpContext::SetContextPPC(MDRawContextPPC* ppc) { - context_.ppc = ppc; -} - -void DumpContext::SetContextPPC64(MDRawContextPPC64* ppc64) { - context_.ppc64 = ppc64; -} - -void DumpContext::SetContextAMD64(MDRawContextAMD64* amd64) { - context_.amd64 = amd64; -} - -void DumpContext::SetContextSPARC(MDRawContextSPARC* ctx_sparc) { - context_.ctx_sparc = ctx_sparc; -} - -void DumpContext::SetContextARM(MDRawContextARM* arm) { - context_.arm = arm; -} - -void DumpContext::SetContextARM64(MDRawContextARM64* arm64) { - context_.arm64 = arm64; -} - -void DumpContext::SetContextMIPS(MDRawContextMIPS* ctx_mips) { - context_.ctx_mips = ctx_mips; -} - -void DumpContext::FreeContext() { - switch (GetContextCPU()) { - case MD_CONTEXT_X86: - delete context_.x86; - break; - - case MD_CONTEXT_PPC: - delete context_.ppc; - break; - - case MD_CONTEXT_PPC64: - delete context_.ppc64; - break; - - case MD_CONTEXT_AMD64: - delete context_.amd64; - break; - - case MD_CONTEXT_SPARC: - delete context_.ctx_sparc; - break; - - case MD_CONTEXT_ARM: - delete context_.arm; - break; - - case MD_CONTEXT_ARM64: - delete context_.arm64; - break; - - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: - delete context_.ctx_mips; - break; - - default: - // There is no context record (valid_ is false) or there's a - // context record for an unknown CPU (shouldn't happen, only known - // records are stored by Read). - break; - } - - context_flags_ = 0; - context_.base = NULL; -} - -void DumpContext::Print() { - if (!valid_) { - BPLOG(ERROR) << "DumpContext cannot print invalid data"; - return; - } - - switch (GetContextCPU()) { - case MD_CONTEXT_X86: { - const MDRawContextX86* context_x86 = GetContextX86(); - printf("MDRawContextX86\n"); - printf(" context_flags = 0x%x\n", - context_x86->context_flags); - printf(" dr0 = 0x%x\n", context_x86->dr0); - printf(" dr1 = 0x%x\n", context_x86->dr1); - printf(" dr2 = 0x%x\n", context_x86->dr2); - printf(" dr3 = 0x%x\n", context_x86->dr3); - printf(" dr6 = 0x%x\n", context_x86->dr6); - printf(" dr7 = 0x%x\n", context_x86->dr7); - printf(" float_save.control_word = 0x%x\n", - context_x86->float_save.control_word); - printf(" float_save.status_word = 0x%x\n", - context_x86->float_save.status_word); - printf(" float_save.tag_word = 0x%x\n", - context_x86->float_save.tag_word); - printf(" float_save.error_offset = 0x%x\n", - context_x86->float_save.error_offset); - printf(" float_save.error_selector = 0x%x\n", - context_x86->float_save.error_selector); - printf(" float_save.data_offset = 0x%x\n", - context_x86->float_save.data_offset); - printf(" float_save.data_selector = 0x%x\n", - context_x86->float_save.data_selector); - printf(" float_save.register_area[%2d] = 0x", - MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE); - for (unsigned int register_index = 0; - register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE; - ++register_index) { - printf("%02x", context_x86->float_save.register_area[register_index]); - } - printf("\n"); - printf(" float_save.cr0_npx_state = 0x%x\n", - context_x86->float_save.cr0_npx_state); - printf(" gs = 0x%x\n", context_x86->gs); - printf(" fs = 0x%x\n", context_x86->fs); - printf(" es = 0x%x\n", context_x86->es); - printf(" ds = 0x%x\n", context_x86->ds); - printf(" edi = 0x%x\n", context_x86->edi); - printf(" esi = 0x%x\n", context_x86->esi); - printf(" ebx = 0x%x\n", context_x86->ebx); - printf(" edx = 0x%x\n", context_x86->edx); - printf(" ecx = 0x%x\n", context_x86->ecx); - printf(" eax = 0x%x\n", context_x86->eax); - printf(" ebp = 0x%x\n", context_x86->ebp); - printf(" eip = 0x%x\n", context_x86->eip); - printf(" cs = 0x%x\n", context_x86->cs); - printf(" eflags = 0x%x\n", context_x86->eflags); - printf(" esp = 0x%x\n", context_x86->esp); - printf(" ss = 0x%x\n", context_x86->ss); - printf(" extended_registers[%3d] = 0x", - MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE); - for (unsigned int register_index = 0; - register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE; - ++register_index) { - printf("%02x", context_x86->extended_registers[register_index]); - } - printf("\n\n"); - - break; - } - - case MD_CONTEXT_PPC: { - const MDRawContextPPC* context_ppc = GetContextPPC(); - printf("MDRawContextPPC\n"); - printf(" context_flags = 0x%x\n", - context_ppc->context_flags); - printf(" srr0 = 0x%x\n", context_ppc->srr0); - printf(" srr1 = 0x%x\n", context_ppc->srr1); - for (unsigned int gpr_index = 0; - gpr_index < MD_CONTEXT_PPC_GPR_COUNT; - ++gpr_index) { - printf(" gpr[%2d] = 0x%x\n", - gpr_index, context_ppc->gpr[gpr_index]); - } - printf(" cr = 0x%x\n", context_ppc->cr); - printf(" xer = 0x%x\n", context_ppc->xer); - printf(" lr = 0x%x\n", context_ppc->lr); - printf(" ctr = 0x%x\n", context_ppc->ctr); - printf(" mq = 0x%x\n", context_ppc->mq); - printf(" vrsave = 0x%x\n", context_ppc->vrsave); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; - ++fpr_index) { - printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", - fpr_index, context_ppc->float_save.fpregs[fpr_index]); - } - printf(" float_save.fpscr = 0x%x\n", - context_ppc->float_save.fpscr); - // TODO(mmentovai): print the 128-bit quantities in - // context_ppc->vector_save. This isn't done yet because printf - // doesn't support 128-bit quantities, and printing them using - // PRIx64 as two 64-bit quantities requires knowledge of the CPU's - // byte ordering. - printf(" vector_save.save_vrvalid = 0x%x\n", - context_ppc->vector_save.save_vrvalid); - printf("\n"); - - break; - } - - case MD_CONTEXT_PPC64: { - const MDRawContextPPC64* context_ppc64 = GetContextPPC64(); - printf("MDRawContextPPC64\n"); - printf(" context_flags = 0x%" PRIx64 "\n", - context_ppc64->context_flags); - printf(" srr0 = 0x%" PRIx64 "\n", - context_ppc64->srr0); - printf(" srr1 = 0x%" PRIx64 "\n", - context_ppc64->srr1); - for (unsigned int gpr_index = 0; - gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; - ++gpr_index) { - printf(" gpr[%2d] = 0x%" PRIx64 "\n", - gpr_index, context_ppc64->gpr[gpr_index]); - } - printf(" cr = 0x%" PRIx64 "\n", context_ppc64->cr); - printf(" xer = 0x%" PRIx64 "\n", - context_ppc64->xer); - printf(" lr = 0x%" PRIx64 "\n", context_ppc64->lr); - printf(" ctr = 0x%" PRIx64 "\n", - context_ppc64->ctr); - printf(" vrsave = 0x%" PRIx64 "\n", - context_ppc64->vrsave); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; - ++fpr_index) { - printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", - fpr_index, context_ppc64->float_save.fpregs[fpr_index]); - } - printf(" float_save.fpscr = 0x%x\n", - context_ppc64->float_save.fpscr); - // TODO(mmentovai): print the 128-bit quantities in - // context_ppc64->vector_save. This isn't done yet because printf - // doesn't support 128-bit quantities, and printing them using - // PRIx64 as two 64-bit quantities requires knowledge of the CPU's - // byte ordering. - printf(" vector_save.save_vrvalid = 0x%x\n", - context_ppc64->vector_save.save_vrvalid); - printf("\n"); - - break; - } - - case MD_CONTEXT_AMD64: { - const MDRawContextAMD64* context_amd64 = GetContextAMD64(); - printf("MDRawContextAMD64\n"); - printf(" p1_home = 0x%" PRIx64 "\n", - context_amd64->p1_home); - printf(" p2_home = 0x%" PRIx64 "\n", - context_amd64->p2_home); - printf(" p3_home = 0x%" PRIx64 "\n", - context_amd64->p3_home); - printf(" p4_home = 0x%" PRIx64 "\n", - context_amd64->p4_home); - printf(" p5_home = 0x%" PRIx64 "\n", - context_amd64->p5_home); - printf(" p6_home = 0x%" PRIx64 "\n", - context_amd64->p6_home); - printf(" context_flags = 0x%x\n", - context_amd64->context_flags); - printf(" mx_csr = 0x%x\n", - context_amd64->mx_csr); - printf(" cs = 0x%x\n", context_amd64->cs); - printf(" ds = 0x%x\n", context_amd64->ds); - printf(" es = 0x%x\n", context_amd64->es); - printf(" fs = 0x%x\n", context_amd64->fs); - printf(" gs = 0x%x\n", context_amd64->gs); - printf(" ss = 0x%x\n", context_amd64->ss); - printf(" eflags = 0x%x\n", context_amd64->eflags); - printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0); - printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1); - printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2); - printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3); - printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6); - printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7); - printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax); - printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx); - printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx); - printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx); - printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp); - printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp); - printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi); - printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi); - printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8); - printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9); - printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10); - printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11); - printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12); - printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13); - printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14); - printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15); - printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip); - // TODO: print xmm, vector, debug registers - printf("\n"); - break; - } - - case MD_CONTEXT_SPARC: { - const MDRawContextSPARC* context_sparc = GetContextSPARC(); - printf("MDRawContextSPARC\n"); - printf(" context_flags = 0x%x\n", - context_sparc->context_flags); - for (unsigned int g_r_index = 0; - g_r_index < MD_CONTEXT_SPARC_GPR_COUNT; - ++g_r_index) { - printf(" g_r[%2d] = 0x%" PRIx64 "\n", - g_r_index, context_sparc->g_r[g_r_index]); - } - printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr); - printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc); - printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc); - printf(" y = 0x%" PRIx64 "\n", context_sparc->y); - printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi); - printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs); - - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; - ++fpr_index) { - printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", - fpr_index, context_sparc->float_save.regs[fpr_index]); - } - printf(" float_save.filler = 0x%" PRIx64 "\n", - context_sparc->float_save.filler); - printf(" float_save.fsr = 0x%" PRIx64 "\n", - context_sparc->float_save.fsr); - break; - } - - case MD_CONTEXT_ARM: { - const MDRawContextARM* context_arm = GetContextARM(); - printf("MDRawContextARM\n"); - printf(" context_flags = 0x%x\n", - context_arm->context_flags); - for (unsigned int ireg_index = 0; - ireg_index < MD_CONTEXT_ARM_GPR_COUNT; - ++ireg_index) { - printf(" iregs[%2d] = 0x%x\n", - ireg_index, context_arm->iregs[ireg_index]); - } - printf(" cpsr = 0x%x\n", context_arm->cpsr); - printf(" float_save.fpscr = 0x%" PRIx64 "\n", - context_arm->float_save.fpscr); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; - ++fpr_index) { - printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", - fpr_index, context_arm->float_save.regs[fpr_index]); - } - for (unsigned int fpe_index = 0; - fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; - ++fpe_index) { - printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n", - fpe_index, context_arm->float_save.extra[fpe_index]); - } - - break; - } - - case MD_CONTEXT_ARM64: { - const MDRawContextARM64* context_arm64 = GetContextARM64(); - printf("MDRawContextARM64\n"); - printf(" context_flags = 0x%" PRIx64 "\n", - context_arm64->context_flags); - for (unsigned int ireg_index = 0; - ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; - ++ireg_index) { - printf(" iregs[%2d] = 0x%" PRIx64 "\n", - ireg_index, context_arm64->iregs[ireg_index]); - } - printf(" cpsr = 0x%x\n", context_arm64->cpsr); - printf(" float_save.fpsr = 0x%x\n", context_arm64->float_save.fpsr); - printf(" float_save.fpcr = 0x%x\n", context_arm64->float_save.fpcr); - - for (unsigned int freg_index = 0; - freg_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; - ++freg_index) { - uint128_struct fp_value = context_arm64->float_save.regs[freg_index]; - printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n", - freg_index, fp_value.high, fp_value.low); - } - break; - } - - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: { - const MDRawContextMIPS* context_mips = GetContextMIPS(); - printf("MDRawContextMIPS\n"); - printf(" context_flags = 0x%x\n", - context_mips->context_flags); - for (int ireg_index = 0; - ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; - ++ireg_index) { - printf(" iregs[%2d] = 0x%" PRIx64 "\n", - ireg_index, context_mips->iregs[ireg_index]); - } - printf(" mdhi = 0x%" PRIx64 "\n", - context_mips->mdhi); - printf(" mdlo = 0x%" PRIx64 "\n", - context_mips->mdhi); - for (int dsp_index = 0; - dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; - ++dsp_index) { - printf(" hi[%1d] = 0x%" PRIx32 "\n", - dsp_index, context_mips->hi[dsp_index]); - printf(" lo[%1d] = 0x%" PRIx32 "\n", - dsp_index, context_mips->lo[dsp_index]); - } - printf(" dsp_control = 0x%" PRIx32 "\n", - context_mips->dsp_control); - printf(" epc = 0x%" PRIx64 "\n", - context_mips->epc); - printf(" badvaddr = 0x%" PRIx64 "\n", - context_mips->badvaddr); - printf(" status = 0x%" PRIx32 "\n", - context_mips->status); - printf(" cause = 0x%" PRIx32 "\n", - context_mips->cause); - - for (int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; - ++fpr_index) { - printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", - fpr_index, context_mips->float_save.regs[fpr_index]); - } - printf(" float_save.fpcsr = 0x%" PRIx32 "\n", - context_mips->float_save.fpcsr); - printf(" float_save.fir = 0x%" PRIx32 "\n", - context_mips->float_save.fir); - break; - } - - default: { - break; - } - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/dump_object.cc b/toolkit/crashreporter/google-breakpad/src/processor/dump_object.cc deleted file mode 100644 index 2c82b200b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/dump_object.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_object.cc: A base class for all mini/micro dump object. - -#include "google_breakpad/processor/dump_object.h" - -namespace google_breakpad { - -DumpObject::DumpObject() : valid_(false) { -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability.cc deleted file mode 100644 index 6ee1e9622..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_engine.cc: Generic exploitability engine. -// -// See exploitable_engine.h for documentation. -// -// Author: Cris Neckar - - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/exploitability.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/process_state.h" -#include "processor/exploitability_linux.h" -#include "processor/exploitability_win.h" -#include "processor/logging.h" - -namespace google_breakpad { - -Exploitability::Exploitability(Minidump *dump, - ProcessState *process_state) - : dump_(dump), - process_state_(process_state) {} - -ExploitabilityRating Exploitability::CheckExploitability() { - return CheckPlatformExploitability(); -} - -Exploitability *Exploitability::ExploitabilityForPlatform( - Minidump *dump, - ProcessState *process_state) { - return ExploitabilityForPlatform(dump, process_state, false); -} - -Exploitability *Exploitability::ExploitabilityForPlatform( - Minidump *dump, - ProcessState *process_state, - bool enable_objdump) { - Exploitability *platform_exploitability = NULL; - MinidumpSystemInfo *minidump_system_info = dump->GetSystemInfo(); - if (!minidump_system_info) - return NULL; - - const MDRawSystemInfo *raw_system_info = - minidump_system_info->system_info(); - if (!raw_system_info) - return NULL; - - switch (raw_system_info->platform_id) { - case MD_OS_WIN32_NT: - case MD_OS_WIN32_WINDOWS: { - platform_exploitability = new ExploitabilityWin(dump, process_state); - break; - } - case MD_OS_LINUX: { - platform_exploitability = new ExploitabilityLinux(dump, - process_state, - enable_objdump); - break; - } - case MD_OS_MAC_OS_X: - case MD_OS_IOS: - case MD_OS_UNIX: - case MD_OS_SOLARIS: - case MD_OS_ANDROID: - case MD_OS_PS3: - default: { - platform_exploitability = NULL; - break; - } - } - - BPLOG_IF(ERROR, !platform_exploitability) << - "No Exploitability module for platform: " << - process_state->system_info()->os; - return platform_exploitability; -} - -bool Exploitability::AddressIsAscii(uint64_t address) { - for (int i = 0; i < 8; i++) { - uint8_t byte = (address >> (8*i)) & 0xff; - if ((byte >= ' ' && byte <= '~') || byte == 0) - continue; - return false; - } - return true; -} - -} // namespace google_breakpad - diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc deleted file mode 100644 index 63056c438..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_linux.cc: Linux specific exploitability engine. -// -// Provides a guess at the exploitability of the crash for the Linux -// platform given a minidump and process_state. -// -// Author: Matthew Riley - -#include "processor/exploitability_linux.h" - -#ifndef _WIN32 -#include -#include -#include -#include - -#include -#include -#endif // _WIN32 - -#include "google_breakpad/common/minidump_exception_linux.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/logging.h" - -namespace { - -// Prefixes for memory mapping names. -constexpr char kHeapPrefix[] = "[heap"; -constexpr char kStackPrefix[] = "[stack"; - -// This function in libc is called if the program was compiled with -// -fstack-protector and a function's stack canary changes. -constexpr char kStackCheckFailureFunction[] = "__stack_chk_fail"; - -// This function in libc is called if the program was compiled with -// -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime -// can determine that the call would overflow the target buffer. -constexpr char kBoundsCheckFailureFunction[] = "__chk_fail"; - -#ifndef _WIN32 -const unsigned int MAX_INSTRUCTION_LEN = 15; -const unsigned int MAX_OBJDUMP_BUFFER_LEN = 4096; -#endif // _WIN32 - -} // namespace - -namespace google_breakpad { - -ExploitabilityLinux::ExploitabilityLinux(Minidump *dump, - ProcessState *process_state) - : Exploitability(dump, process_state), - enable_objdump_(false) { } - -ExploitabilityLinux::ExploitabilityLinux(Minidump *dump, - ProcessState *process_state, - bool enable_objdump) - : Exploitability(dump, process_state), - enable_objdump_(enable_objdump) { } - - -ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { - // Check the crashing thread for functions suggesting a buffer overflow or - // stack smash. - if (process_state_->requesting_thread() != -1) { - CallStack* crashing_thread = - process_state_->threads()->at(process_state_->requesting_thread()); - const vector& crashing_thread_frames = - *crashing_thread->frames(); - for (size_t i = 0; i < crashing_thread_frames.size(); ++i) { - if (crashing_thread_frames[i]->function_name == - kStackCheckFailureFunction) { - return EXPLOITABILITY_HIGH; - } - - if (crashing_thread_frames[i]->function_name == - kBoundsCheckFailureFunction) { - return EXPLOITABILITY_HIGH; - } - } - } - - // Getting exception data. (It should exist for all minidumps.) - MinidumpException *exception = dump_->GetException(); - if (exception == NULL) { - BPLOG(INFO) << "No exception record."; - return EXPLOITABILITY_ERR_PROCESSING; - } - const MDRawExceptionStream *raw_exception_stream = exception->exception(); - if (raw_exception_stream == NULL) { - BPLOG(INFO) << "No raw exception stream."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Checking for benign exceptions that caused the crash. - if (this->BenignCrashTrigger(raw_exception_stream)) { - return EXPLOITABILITY_NONE; - } - - // Check if the instruction pointer is in a valid instruction region - // by finding if it maps to an executable part of memory. - uint64_t instruction_ptr = 0; - uint64_t stack_ptr = 0; - - const MinidumpContext *context = exception->GetContext(); - if (context == NULL) { - BPLOG(INFO) << "No exception context."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Getting the instruction pointer. - if (!context->GetInstructionPointer(&instruction_ptr)) { - BPLOG(INFO) << "Failed to retrieve instruction pointer."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Getting the stack pointer. - if (!context->GetStackPointer(&stack_ptr)) { - BPLOG(INFO) << "Failed to retrieve stack pointer."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Checking for the instruction pointer in a valid instruction region, - // a misplaced stack pointer, and an executable stack or heap. - if (!this->InstructionPointerInCode(instruction_ptr) || - this->StackPointerOffStack(stack_ptr) || - this->ExecutableStackOrHeap()) { - return EXPLOITABILITY_HIGH; - } - - // Check for write to read only memory or invalid memory, shelling out - // to objdump is enabled. - if (enable_objdump_ && this->EndedOnIllegalWrite(instruction_ptr)) { - return EXPLOITABILITY_HIGH; - } - - // There was no strong evidence suggesting exploitability, but the minidump - // does not appear totally benign either. - return EXPLOITABILITY_INTERESTING; -} - -bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) { -#ifdef _WIN32 - BPLOG(INFO) << "MinGW does not support fork and exec. Terminating method."; -#else - // Get memory region containing instruction pointer. - MinidumpMemoryList *memory_list = dump_->GetMemoryList(); - MinidumpMemoryRegion *memory_region = - memory_list ? - memory_list->GetMemoryRegionForAddress(instruction_ptr) : NULL; - if (!memory_region) { - BPLOG(INFO) << "No memory region around instruction pointer."; - return false; - } - - // Get exception data to find architecture. - string architecture = ""; - MinidumpException *exception = dump_->GetException(); - // This should never evaluate to true, since this should not be reachable - // without checking for exception data earlier. - if (!exception) { - BPLOG(INFO) << "No exception data."; - return false; - } - const MDRawExceptionStream *raw_exception_stream = exception->exception(); - const MinidumpContext *context = exception->GetContext(); - // This should not evaluate to true, for the same reason mentioned above. - if (!raw_exception_stream || !context) { - BPLOG(INFO) << "No exception or architecture data."; - return false; - } - // Check architecture and set architecture variable to corresponding flag - // in objdump. - switch (context->GetContextCPU()) { - case MD_CONTEXT_X86: - architecture = "i386"; - break; - case MD_CONTEXT_AMD64: - architecture = "i386:x86-64"; - break; - default: - // Unsupported architecture. Note that ARM architectures are not - // supported because objdump does not support ARM. - return false; - break; - } - - // Get memory region around instruction pointer and the number of bytes - // before and after the instruction pointer in the memory region. - const uint8_t *raw_memory = memory_region->GetMemory(); - const uint64_t base = memory_region->GetBase(); - if (base > instruction_ptr) { - BPLOG(ERROR) << "Memory region base value exceeds instruction pointer."; - return false; - } - const uint64_t offset = instruction_ptr - base; - if (memory_region->GetSize() < MAX_INSTRUCTION_LEN + offset) { - BPLOG(INFO) << "Not enough bytes left to guarantee complete instruction."; - return false; - } - - // Convert bytes into objdump output. - char objdump_output_buffer[MAX_OBJDUMP_BUFFER_LEN] = {0}; - DisassembleBytes(architecture, - raw_memory + offset, - MAX_OBJDUMP_BUFFER_LEN, - objdump_output_buffer); - - string line; - if (!GetObjdumpInstructionLine(objdump_output_buffer, &line)) { - return false; - } - - // Convert objdump instruction line into the operation and operands. - string instruction = ""; - string dest = ""; - string src = ""; - TokenizeObjdumpInstruction(line, &instruction, &dest, &src); - - // Check if the operation is a write to memory. First, the instruction - // must one that can write to memory. Second, the write destination - // must be a spot in memory rather than a register. Since there are no - // symbols from objdump, the destination will be enclosed by brackets. - if (dest.size() > 2 && dest.at(0) == '[' && dest.at(dest.size() - 1) == ']' && - (!instruction.compare("mov") || !instruction.compare("inc") || - !instruction.compare("dec") || !instruction.compare("and") || - !instruction.compare("or") || !instruction.compare("xor") || - !instruction.compare("not") || !instruction.compare("neg") || - !instruction.compare("add") || !instruction.compare("sub") || - !instruction.compare("shl") || !instruction.compare("shr"))) { - // Strip away enclosing brackets from the destination address. - dest = dest.substr(1, dest.size() - 2); - uint64_t write_address = 0; - CalculateAddress(dest, *context, &write_address); - - // If the program crashed as a result of a write, the destination of - // the write must have been an address that did not permit writing. - // However, if the address is under 4k, due to program protections, - // the crash does not suggest exploitability for writes with such a - // low target address. - return write_address > 4096; - } -#endif // _WIN32 - return false; -} - -#ifndef _WIN32 -bool ExploitabilityLinux::CalculateAddress(const string &address_expression, - const DumpContext &context, - uint64_t *write_address) { - // The destination should be the format reg+a or reg-a, where reg - // is a register and a is a hexadecimal constant. Although more complex - // expressions can make valid instructions, objdump's disassembly outputs - // it in this simpler format. - // TODO(liuandrew): Handle more complex formats, should they arise. - - if (!write_address) { - BPLOG(ERROR) << "Null parameter."; - return false; - } - - // Clone parameter into a non-const string. - string expression = address_expression; - - // Parse out the constant that is added to the address (if it exists). - size_t delim = expression.find('+'); - bool positive_add_constant = true; - // Check if constant is subtracted instead of added. - if (delim == string::npos) { - positive_add_constant = false; - delim = expression.find('-'); - } - uint32_t add_constant = 0; - // Save constant and remove it from the expression. - if (delim != string::npos) { - if (!sscanf(expression.substr(delim + 1).c_str(), "%x", &add_constant)) { - BPLOG(ERROR) << "Failed to scan constant."; - return false; - } - expression = expression.substr(0, delim); - } - - // Set the the write address to the corresponding register. - // TODO(liuandrew): Add support for partial registers, such as - // the rax/eax/ax/ah/al chain. - switch (context.GetContextCPU()) { - case MD_CONTEXT_X86: - if (!expression.compare("eax")) { - *write_address = context.GetContextX86()->eax; - } else if (!expression.compare("ebx")) { - *write_address = context.GetContextX86()->ebx; - } else if (!expression.compare("ecx")) { - *write_address = context.GetContextX86()->ecx; - } else if (!expression.compare("edx")) { - *write_address = context.GetContextX86()->edx; - } else if (!expression.compare("edi")) { - *write_address = context.GetContextX86()->edi; - } else if (!expression.compare("esi")) { - *write_address = context.GetContextX86()->esi; - } else if (!expression.compare("ebp")) { - *write_address = context.GetContextX86()->ebp; - } else if (!expression.compare("esp")) { - *write_address = context.GetContextX86()->esp; - } else if (!expression.compare("eip")) { - *write_address = context.GetContextX86()->eip; - } else { - BPLOG(ERROR) << "Unsupported register"; - return false; - } - break; - case MD_CONTEXT_AMD64: - if (!expression.compare("rax")) { - *write_address = context.GetContextAMD64()->rax; - } else if (!expression.compare("rbx")) { - *write_address = context.GetContextAMD64()->rbx; - } else if (!expression.compare("rcx")) { - *write_address = context.GetContextAMD64()->rcx; - } else if (!expression.compare("rdx")) { - *write_address = context.GetContextAMD64()->rdx; - } else if (!expression.compare("rdi")) { - *write_address = context.GetContextAMD64()->rdi; - } else if (!expression.compare("rsi")) { - *write_address = context.GetContextAMD64()->rsi; - } else if (!expression.compare("rbp")) { - *write_address = context.GetContextAMD64()->rbp; - } else if (!expression.compare("rsp")) { - *write_address = context.GetContextAMD64()->rsp; - } else if (!expression.compare("rip")) { - *write_address = context.GetContextAMD64()->rip; - } else if (!expression.compare("r8")) { - *write_address = context.GetContextAMD64()->r8; - } else if (!expression.compare("r9")) { - *write_address = context.GetContextAMD64()->r9; - } else if (!expression.compare("r10")) { - *write_address = context.GetContextAMD64()->r10; - } else if (!expression.compare("r11")) { - *write_address = context.GetContextAMD64()->r11; - } else if (!expression.compare("r12")) { - *write_address = context.GetContextAMD64()->r12; - } else if (!expression.compare("r13")) { - *write_address = context.GetContextAMD64()->r13; - } else if (!expression.compare("r14")) { - *write_address = context.GetContextAMD64()->r14; - } else if (!expression.compare("r15")) { - *write_address = context.GetContextAMD64()->r15; - } else { - BPLOG(ERROR) << "Unsupported register"; - return false; - } - break; - default: - // This should not occur since the same switch condition - // should have terminated this method. - return false; - break; - } - - // Add or subtract constant from write address (if applicable). - *write_address = - positive_add_constant ? - *write_address + add_constant : *write_address - add_constant; - - return true; -} - -// static -bool ExploitabilityLinux::GetObjdumpInstructionLine( - const char *objdump_output_buffer, - string *instruction_line) { - // Put buffer data into stream to output line-by-line. - std::stringstream objdump_stream; - objdump_stream.str(string(objdump_output_buffer)); - - // Pipe each output line into the string until the string contains the first - // instruction from objdump. All lines before the "<.data>:" section are - // skipped. Loop until the line shows the first instruction or there are no - // lines left. - bool data_section_seen = false; - do { - if (!getline(objdump_stream, *instruction_line)) { - BPLOG(INFO) << "Objdump instructions not found"; - return false; - } - if (instruction_line->find("<.data>:") != string::npos) { - data_section_seen = true; - } - } while (!data_section_seen || instruction_line->find("0:") == string::npos); - // This first instruction contains the above substring. - - return true; -} - -bool ExploitabilityLinux::TokenizeObjdumpInstruction(const string &line, - string *operation, - string *dest, - string *src) { - if (!operation || !dest || !src) { - BPLOG(ERROR) << "Null parameters passed."; - return false; - } - - // Set all pointer values to empty strings. - *operation = ""; - *dest = ""; - *src = ""; - - // Tokenize the objdump line. - vector tokens; - std::istringstream line_stream(line); - copy(std::istream_iterator(line_stream), - std::istream_iterator(), - std::back_inserter(tokens)); - - // Regex for the data in hex form. Each byte is two hex digits. - regex_t regex; - regcomp(®ex, "^[[:xdigit:]]{2}$", REG_EXTENDED | REG_NOSUB); - - // Find and set the location of the operator. The operator appears - // directly after the chain of bytes that define the instruction. The - // operands will be the last token, given that the instruction has operands. - // If not, the operator is the last token. The loop skips the first token - // because the first token is the instruction number (namely "0:"). - string operands = ""; - for (size_t i = 1; i < tokens.size(); i++) { - // Check if current token no longer is in byte format. - if (regexec(®ex, tokens[i].c_str(), 0, NULL, 0)) { - // instruction = tokens[i]; - *operation = tokens[i]; - // If the operator is the last token, there are no operands. - if (i != tokens.size() - 1) { - operands = tokens[tokens.size() - 1]; - } - break; - } - } - regfree(®ex); - - if (operation->empty()) { - BPLOG(ERROR) << "Failed to parse out operation from objdump instruction."; - return false; - } - - // Split operands into source and destination (if applicable). - if (!operands.empty()) { - size_t delim = operands.find(','); - if (delim == string::npos) { - *dest = operands; - } else { - *dest = operands.substr(0, delim); - *src = operands.substr(delim + 1); - } - } - return true; -} - -bool ExploitabilityLinux::DisassembleBytes(const string &architecture, - const uint8_t *raw_bytes, - const unsigned int buffer_len, - char *objdump_output_buffer) { - if (!raw_bytes || !objdump_output_buffer) { - BPLOG(ERROR) << "Bad input parameters."; - return false; - } - - // Write raw bytes around instruction pointer to a temporary file to - // pass as an argument to objdump. - char raw_bytes_tmpfile[] = "/tmp/breakpad_mem_region-raw_bytes-XXXXXX"; - int raw_bytes_fd = mkstemp(raw_bytes_tmpfile); - if (raw_bytes_fd < 0) { - BPLOG(ERROR) << "Failed to create tempfile."; - unlink(raw_bytes_tmpfile); - return false; - } - if (write(raw_bytes_fd, raw_bytes, MAX_INSTRUCTION_LEN) - != MAX_INSTRUCTION_LEN) { - BPLOG(ERROR) << "Writing of raw bytes failed."; - unlink(raw_bytes_tmpfile); - return false; - } - - char cmd[1024] = {0}; - snprintf(cmd, - 1024, - "objdump -D -b binary -M intel -m %s %s", - architecture.c_str(), - raw_bytes_tmpfile); - FILE *objdump_fp = popen(cmd, "r"); - if (!objdump_fp) { - fclose(objdump_fp); - unlink(raw_bytes_tmpfile); - BPLOG(ERROR) << "Failed to call objdump."; - return false; - } - if (fread(objdump_output_buffer, 1, buffer_len, objdump_fp) <= 0) { - fclose(objdump_fp); - unlink(raw_bytes_tmpfile); - BPLOG(ERROR) << "Failed to read objdump output."; - return false; - } - fclose(objdump_fp); - unlink(raw_bytes_tmpfile); - return true; -} -#endif // _WIN32 - -bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) { - MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList(); - // Inconclusive if there are no mappings available. - if (!linux_maps_list) { - return false; - } - const MinidumpLinuxMaps *linux_maps = - linux_maps_list->GetLinuxMapsForAddress(stack_ptr); - // Checks if the stack pointer maps to a valid mapping and if the mapping - // is not the stack. If the mapping has no name, it is inconclusive whether - // it is off the stack. - return !linux_maps || (linux_maps->GetPathname().compare("") && - linux_maps->GetPathname().compare( - 0, strlen(kStackPrefix), kStackPrefix)); -} - -bool ExploitabilityLinux::ExecutableStackOrHeap() { - MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList(); - if (linux_maps_list) { - for (size_t i = 0; i < linux_maps_list->get_maps_count(); i++) { - const MinidumpLinuxMaps *linux_maps = - linux_maps_list->GetLinuxMapsAtIndex(i); - // Check for executable stack or heap for each mapping. - if (linux_maps && (!linux_maps->GetPathname().compare( - 0, strlen(kStackPrefix), kStackPrefix) || - !linux_maps->GetPathname().compare( - 0, strlen(kHeapPrefix), kHeapPrefix)) && - linux_maps->IsExecutable()) { - return true; - } - } - } - return false; -} - -bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) { - // Get Linux memory mapping from /proc/self/maps. Checking whether the - // region the instruction pointer is in has executable permission can tell - // whether it is in a valid code region. If there is no mapping for the - // instruction pointer, it is indicative that the instruction pointer is - // not within a module, which implies that it is outside a valid area. - MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList(); - const MinidumpLinuxMaps *linux_maps = - linux_maps_list ? - linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : NULL; - return linux_maps ? linux_maps->IsExecutable() : false; -} - -bool ExploitabilityLinux::BenignCrashTrigger(const MDRawExceptionStream - *raw_exception_stream) { - // Check the cause of crash. - // If the exception of the crash is a benign exception, - // it is probably not exploitable. - switch (raw_exception_stream->exception_record.exception_code) { - case MD_EXCEPTION_CODE_LIN_SIGHUP: - case MD_EXCEPTION_CODE_LIN_SIGINT: - case MD_EXCEPTION_CODE_LIN_SIGQUIT: - case MD_EXCEPTION_CODE_LIN_SIGTRAP: - case MD_EXCEPTION_CODE_LIN_SIGABRT: - case MD_EXCEPTION_CODE_LIN_SIGFPE: - case MD_EXCEPTION_CODE_LIN_SIGKILL: - case MD_EXCEPTION_CODE_LIN_SIGUSR1: - case MD_EXCEPTION_CODE_LIN_SIGUSR2: - case MD_EXCEPTION_CODE_LIN_SIGPIPE: - case MD_EXCEPTION_CODE_LIN_SIGALRM: - case MD_EXCEPTION_CODE_LIN_SIGTERM: - case MD_EXCEPTION_CODE_LIN_SIGCHLD: - case MD_EXCEPTION_CODE_LIN_SIGCONT: - case MD_EXCEPTION_CODE_LIN_SIGSTOP: - case MD_EXCEPTION_CODE_LIN_SIGTSTP: - case MD_EXCEPTION_CODE_LIN_SIGTTIN: - case MD_EXCEPTION_CODE_LIN_SIGTTOU: - case MD_EXCEPTION_CODE_LIN_SIGURG: - case MD_EXCEPTION_CODE_LIN_SIGXCPU: - case MD_EXCEPTION_CODE_LIN_SIGXFSZ: - case MD_EXCEPTION_CODE_LIN_SIGVTALRM: - case MD_EXCEPTION_CODE_LIN_SIGPROF: - case MD_EXCEPTION_CODE_LIN_SIGWINCH: - case MD_EXCEPTION_CODE_LIN_SIGIO: - case MD_EXCEPTION_CODE_LIN_SIGPWR: - case MD_EXCEPTION_CODE_LIN_SIGSYS: - case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED: - return true; - break; - default: - return false; - break; - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.h b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.h deleted file mode 100644 index e3ff13b6e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_linux.h: Linux specific exploitability engine. -// -// Provides a guess at the exploitability of the crash for the Linux -// platform given a minidump and process_state. -// -// Author: Matthew Riley - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/exploitability.h" - -namespace google_breakpad { - -class ExploitabilityLinux : public Exploitability { - public: - ExploitabilityLinux(Minidump *dump, - ProcessState *process_state); - - // Parameters are the minidump to analyze, the object representing process - // state, and whether to enable objdump disassembly. - // Enabling objdump will allow exploitability analysis to call out to - // objdump for diassembly. It is used to check the identity of the - // instruction that caused the program to crash. If there are any - // portability concerns, this should not be enabled. - ExploitabilityLinux(Minidump *dump, - ProcessState *process_state, - bool enable_objdump); - - virtual ExploitabilityRating CheckPlatformExploitability(); - - private: - friend class ExploitabilityLinuxTest; - - // Takes the address of the instruction pointer and returns - // whether the instruction pointer lies in a valid instruction region. - bool InstructionPointerInCode(uint64_t instruction_ptr); - - // Checks the exception that triggered the creation of the - // minidump and reports whether the exception suggests no exploitability. - bool BenignCrashTrigger(const MDRawExceptionStream *raw_exception_stream); - - // This method checks if the crash occurred during a write to read-only or - // invalid memory. It does so by checking if the instruction at the - // instruction pointer is a write instruction, and if the target of the - // instruction is at a spot in memory that prohibits writes. - bool EndedOnIllegalWrite(uint64_t instruction_ptr); - -#ifndef _WIN32 - // Disassembles raw bytes via objdump and pipes the output into the provided - // buffer, given the desired architecture, the file from which objdump will - // read, and the buffer length. The method returns whether the disassembly - // was a success, and the caller owns all pointers. - static bool DisassembleBytes(const string &architecture, - const uint8_t *raw_bytes, - const unsigned int MAX_OBJDUMP_BUFFER_LEN, - char *objdump_output_buffer); - - // Parses the objdump output given in |objdump_output_buffer| and extracts - // the line of the first instruction into |instruction_line|. Returns true - // when the instruction line is successfully extracted. - static bool GetObjdumpInstructionLine( - const char *objdump_output_buffer, - string *instruction_line); - - // Tokenizes out the operation and operands from a line of instruction - // disassembled by objdump. This method modifies the pointers to match the - // tokens of the instruction, and returns if the tokenizing was a success. - // The caller owns all pointers. - static bool TokenizeObjdumpInstruction(const string &line, - string *operation, - string *dest, - string *src); - - // Calculates the effective address of an expression in the form reg+a or - // reg-a, where 'reg' is a register and 'a' is a constant, and writes the - // result in the pointer. The method returns whether the calculation was - // a success. The caller owns the pointer. - static bool CalculateAddress(const string &address_expression, - const DumpContext &context, - uint64_t *write_address); -#endif // _WIN32 - - // Checks if the stack pointer points to a memory mapping that is not - // labelled as the stack. - bool StackPointerOffStack(uint64_t stack_ptr); - - // Checks if the stack or heap are marked executable according - // to the memory mappings. - bool ExecutableStackOrHeap(); - - // Whether this exploitability engine is permitted to shell out to objdump - // to disassemble raw bytes. - bool enable_objdump_; -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_unittest.cc deleted file mode 100644 index 528ee5f21..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_unittest.cc +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - -#include -#include - -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/minidump_processor.h" -#include "google_breakpad/processor/process_state.h" -#ifndef _WIN32 -#include "processor/exploitability_linux.h" -#endif // _WIN32 -#include "processor/simple_symbol_supplier.h" - -#ifndef _WIN32 -namespace google_breakpad { - -class ExploitabilityLinuxTest : public ExploitabilityLinux { - public: - using ExploitabilityLinux::CalculateAddress; - using ExploitabilityLinux::DisassembleBytes; - using ExploitabilityLinux::GetObjdumpInstructionLine; - using ExploitabilityLinux::TokenizeObjdumpInstruction; -}; - -class ExploitabilityLinuxTestMinidumpContext : public MinidumpContext { - public: - explicit ExploitabilityLinuxTestMinidumpContext( - const MDRawContextAMD64& context) : MinidumpContext(NULL) { - valid_ = true; - SetContextAMD64(new MDRawContextAMD64(context)); - SetContextFlags(MD_CONTEXT_AMD64); - } -}; - -} // namespace google_breakpad -#endif // _WIN32 - -namespace { - -using google_breakpad::BasicSourceLineResolver; -#ifndef _WIN32 -using google_breakpad::ExploitabilityLinuxTest; -using google_breakpad::ExploitabilityLinuxTestMinidumpContext; -#endif // _WIN32 -using google_breakpad::MinidumpProcessor; -using google_breakpad::ProcessState; -using google_breakpad::SimpleSymbolSupplier; - -string TestDataDir() { - return string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata"; -} - -// Find the given dump file in /src/processor/testdata, process it, -// and get the exploitability rating. Returns EXPLOITABILITY_ERR_PROCESSING -// if the crash dump can't be processed. -google_breakpad::ExploitabilityRating -ExploitabilityFor(const string& filename) { - SimpleSymbolSupplier supplier(TestDataDir() + "/symbols"); - BasicSourceLineResolver resolver; - MinidumpProcessor processor(&supplier, &resolver, true); - processor.set_enable_objdump(true); - ProcessState state; - - string minidump_file = TestDataDir() + "/" + filename; - - if (processor.Process(minidump_file, &state) != - google_breakpad::PROCESS_OK) { - return google_breakpad::EXPLOITABILITY_ERR_PROCESSING; - } - - return state.exploitability(); -} - -TEST(ExploitabilityTest, TestWindowsEngine) { - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av_block_write.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av_clobber_write.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av_conditional.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av_then_jmp.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_read_av_xchg_write.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_write_av.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("ascii_write_av_arg_to_call.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, - ExploitabilityFor("null_read_av.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, - ExploitabilityFor("null_write_av.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, - ExploitabilityFor("stack_exhaustion.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("exec_av_on_stack.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_MEDIUM, - ExploitabilityFor("write_av_non_null.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, - ExploitabilityFor("read_av_non_null.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, - ExploitabilityFor("read_av_clobber_write.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, - ExploitabilityFor("read_av_conditional.dmp")); -} - -TEST(ExploitabilityTest, TestLinuxEngine) { - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_null_read_av.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_overflow.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_stacksmash.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, - ExploitabilityFor("linux_divide_by_zero.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_null_dereference.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_jmp_to_0.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_outside_module.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, - ExploitabilityFor("linux_raise_sigabrt.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_inside_module_exe_region1.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_inside_module_exe_region2.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_stack_pointer_in_stack.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_stack_pointer_in_stack_alt_name.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_stack_pointer_in_module.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_executable_stack.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_executable_heap.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_jmp_to_module_not_exe_region.dmp")); -#ifndef _WIN32 - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_write_to_nonwritable_module.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_write_to_nonwritable_region_math.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_write_to_outside_module.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, - ExploitabilityFor("linux_write_to_outside_module_via_math.dmp")); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, - ExploitabilityFor("linux_write_to_under_4k.dmp")); -#endif // _WIN32 -} - -#ifndef _WIN32 -TEST(ExploitabilityLinuxUtilsTest, DisassembleBytesTest) { - ASSERT_FALSE(ExploitabilityLinuxTest::DisassembleBytes("", NULL, 5, NULL)); - uint8_t bytes[6] = {0xc7, 0x0, 0x5, 0x0, 0x0, 0x0}; - char buffer[1024] = {0}; - ASSERT_TRUE(ExploitabilityLinuxTest::DisassembleBytes("i386:x86-64", - bytes, - 1024, - buffer)); - std::stringstream objdump_stream; - objdump_stream.str(string(buffer)); - string line = ""; - while (line.find("<.data>") == string::npos) - getline(objdump_stream, line); - getline(objdump_stream, line); - ASSERT_EQ(line, " 0:\tc7 00 05 00 00 00 \tmov DWORD PTR [rax],0x5"); -} - -TEST(ExploitabilityLinuxUtilsTest, GetObjdumpInstructionLine) { - string disassebly = - "\n" - "/tmp/breakpad_mem_region-raw_bytes-tMmMo0: file format binary\n" - "// Trying to confuse the parser 0:\n" - "\n" - "Disassembly of section .data:\n" - "\n" - "0000000000000000 <.data>:\n" - " 0:\tc7 00 01 00 00 00 \tmov DWORD PTR [rax],0x1\n" - " 6:\t5d \tpop rbp\n" - " 7:\tc3 \tret \n" - " 8:\t55 \tpush rbp\n" - " 9:\t48 89 e5 \tmov rbp,rsp\n" - " c:\t53 \tpush rbx\n" - " d:\t48 \trex.W\n" - " e:\t81 \t.byte 0x81\n"; - string line; - EXPECT_TRUE(ExploitabilityLinuxTest::GetObjdumpInstructionLine( - disassebly.c_str(), &line)); - EXPECT_EQ(" 0:\tc7 00 01 00 00 00 \tmov DWORD PTR [rax],0x1", line); - - // There is no "0:" after "<.data>:". Expected to return false. - disassebly = - "\n" - "/tmp/breakpad_mem_region-raw_bytes-tMmMo0: file format binary\n" - "// Trying to confuse the parser 0:\n" - "\n" - "Disassembly of section .data:\n" - "\n" - " 0:\tc7 00 01 00 00 00 \tmov DWORD PTR [rax],0x1\n" - " 6:\t5d \tpop rbp\n" - " 7:\tc3 \tret \n" - " 8:\t55 \tpush rbp\n" - " 9:\t48 89 e5 \tmov rbp,rsp\n" - " d:\t48 \trex.W\n" - "0000000000000000 <.data>:\n" - " c:\t53 \tpush rbx\n"; - EXPECT_FALSE(ExploitabilityLinuxTest::GetObjdumpInstructionLine( - disassebly.c_str(), &line)); -} - -TEST(ExploitabilityLinuxUtilsTest, TokenizeObjdumpInstructionTest) { - ASSERT_FALSE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction("", - NULL, - NULL, - NULL)); - string line = "0: c7 00 05 00 00 00 mov DWORD PTR [rax],0x5"; - string operation = ""; - string dest = ""; - string src = ""; - ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, - &operation, - &dest, - &src)); - ASSERT_EQ(operation, "mov"); - ASSERT_EQ(dest, "[rax]"); - ASSERT_EQ(src, "0x5"); - line = "0: c3 ret"; - ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, - &operation, - &dest, - &src)); - ASSERT_EQ(operation, "ret"); - ASSERT_EQ(dest, ""); - ASSERT_EQ(src, ""); - line = "0: 5f pop rdi"; - ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, - &operation, - &dest, - &src)); - ASSERT_EQ(operation, "pop"); - ASSERT_EQ(dest, "rdi"); - ASSERT_EQ(src, ""); -} - -TEST(ExploitabilityLinuxUtilsTest, CalculateAddressTest) { - MDRawContextAMD64 raw_context; - raw_context.rdx = 12345; - ExploitabilityLinuxTestMinidumpContext context(raw_context); - ASSERT_EQ(context.GetContextAMD64()->rdx, 12345U); - ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("", context, NULL)); - uint64_t write_address = 0; - ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx-0x4D2", - context, - &write_address)); - ASSERT_EQ(write_address, 11111U); - ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx+0x4D2", - context, - &write_address)); - ASSERT_EQ(write_address, 13579U); - ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("rdx+rax", - context, - &write_address)); - ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("0x3482+0x4D2", - context, - &write_address)); -} -#endif // _WIN32 - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc deleted file mode 100644 index a1f8703a6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_win.cc: Windows specific exploitability engine. -// -// Provides a guess at the exploitability of the crash for the Windows -// platform given a minidump and process_state. -// -// Author: Cris Neckar - -#include - -#include "processor/exploitability_win.h" - -#include "common/scoped_ptr.h" -#include "google_breakpad/common/minidump_exception_win32.h" -#include "google_breakpad/processor/minidump.h" -#include "processor/disassembler_x86.h" -#include "processor/logging.h" - -#include "third_party/libdisasm/libdis.h" - -namespace google_breakpad { - -// The cutoff that we use to judge if and address is likely an offset -// from various interesting addresses. -static const uint64_t kProbableNullOffset = 4096; -static const uint64_t kProbableStackOffset = 8192; - -// The various cutoffs for the different ratings. -static const size_t kHighCutoff = 100; -static const size_t kMediumCutoff = 80; -static const size_t kLowCutoff = 50; -static const size_t kInterestingCutoff = 25; - -// Predefined incremental values for conditional weighting. -static const size_t kTinyBump = 5; -static const size_t kSmallBump = 20; -static const size_t kMediumBump = 50; -static const size_t kLargeBump = 70; -static const size_t kHugeBump = 90; - -// The maximum number of bytes to disassemble past the program counter. -static const size_t kDisassembleBytesBeyondPC = 2048; - -ExploitabilityWin::ExploitabilityWin(Minidump *dump, - ProcessState *process_state) - : Exploitability(dump, process_state) { } - -ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() { - MinidumpException *exception = dump_->GetException(); - if (!exception) { - BPLOG(INFO) << "Minidump does not have exception record."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - const MDRawExceptionStream *raw_exception = exception->exception(); - if (!raw_exception) { - BPLOG(INFO) << "Could not obtain raw exception info."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - const MinidumpContext *context = exception->GetContext(); - if (!context) { - BPLOG(INFO) << "Could not obtain exception context."; - return EXPLOITABILITY_ERR_PROCESSING; - } - - MinidumpMemoryList *memory_list = dump_->GetMemoryList(); - bool memory_available = true; - if (!memory_list) { - BPLOG(INFO) << "Minidump memory segments not available."; - memory_available = false; - } - uint64_t address = process_state_->crash_address(); - uint32_t exception_code = raw_exception->exception_record.exception_code; - - uint32_t exploitability_weight = 0; - - uint64_t stack_ptr = 0; - uint64_t instruction_ptr = 0; - - // Getting the instruction pointer. - if (!context->GetInstructionPointer(&instruction_ptr)) { - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Getting the stack pointer. - if (!context->GetStackPointer(&stack_ptr)) { - return EXPLOITABILITY_ERR_PROCESSING; - } - - // Check if we are executing on the stack. - if (instruction_ptr <= (stack_ptr + kProbableStackOffset) && - instruction_ptr >= (stack_ptr - kProbableStackOffset)) - exploitability_weight += kHugeBump; - - switch (exception_code) { - // This is almost certainly recursion. - case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW: - exploitability_weight += kTinyBump; - break; - - // These exceptions tend to be benign and we can generally ignore them. - case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO: - case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW: - case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO: - case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT: - case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW: - case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW: - case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR: - exploitability_weight += kTinyBump; - break; - - // These exceptions will typically mean that we have jumped where we - // shouldn't. - case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION: - case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION: - case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION: - exploitability_weight += kLargeBump; - break; - - // These represent bugs in exception handlers. - case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION: - case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION: - exploitability_weight += kSmallBump; - break; - - case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION: - case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN: - exploitability_weight += kHugeBump; - break; - - case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION: - exploitability_weight += kLargeBump; - break; - - case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION: - bool near_null = (address <= kProbableNullOffset); - bool bad_read = false; - bool bad_write = false; - if (raw_exception->exception_record.number_parameters >= 1) { - MDAccessViolationTypeWin av_type = - static_cast - (raw_exception->exception_record.exception_information[0]); - switch (av_type) { - case MD_ACCESS_VIOLATION_WIN_READ: - bad_read = true; - if (near_null) - exploitability_weight += kSmallBump; - else - exploitability_weight += kMediumBump; - break; - case MD_ACCESS_VIOLATION_WIN_WRITE: - bad_write = true; - if (near_null) - exploitability_weight += kSmallBump; - else - exploitability_weight += kHugeBump; - break; - case MD_ACCESS_VIOLATION_WIN_EXEC: - if (near_null) - exploitability_weight += kSmallBump; - else - exploitability_weight += kHugeBump; - break; - default: - BPLOG(INFO) << "Unrecognized access violation type."; - return EXPLOITABILITY_ERR_PROCESSING; - break; - } - MinidumpMemoryRegion *instruction_region = 0; - if (memory_available) { - instruction_region = - memory_list->GetMemoryRegionForAddress(instruction_ptr); - } - if (!near_null && instruction_region && - context->GetContextCPU() == MD_CONTEXT_X86 && - (bad_read || bad_write)) { - // Perform checks related to memory around instruction pointer. - uint32_t memory_offset = - instruction_ptr - instruction_region->GetBase(); - uint32_t available_memory = - instruction_region->GetSize() - memory_offset; - available_memory = available_memory > kDisassembleBytesBeyondPC ? - kDisassembleBytesBeyondPC : available_memory; - if (available_memory) { - const uint8_t *raw_memory = - instruction_region->GetMemory() + memory_offset; - DisassemblerX86 disassembler(raw_memory, - available_memory, - instruction_ptr); - disassembler.NextInstruction(); - if (bad_read) - disassembler.setBadRead(); - else - disassembler.setBadWrite(); - if (disassembler.currentInstructionValid()) { - // Check if the faulting instruction falls into one of - // several interesting groups. - switch (disassembler.currentInstructionGroup()) { - case libdis::insn_controlflow: - exploitability_weight += kLargeBump; - break; - case libdis::insn_string: - exploitability_weight += kHugeBump; - break; - default: - break; - } - // Loop the disassembler through the code and check if it - // IDed any interesting conditions in the near future. - // Multiple flags may be set so treat each equally. - while (disassembler.NextInstruction() && - disassembler.currentInstructionValid() && - !disassembler.endOfBlock()) - continue; - if (disassembler.flags() & DISX86_BAD_BRANCH_TARGET) - exploitability_weight += kLargeBump; - if (disassembler.flags() & DISX86_BAD_ARGUMENT_PASSED) - exploitability_weight += kTinyBump; - if (disassembler.flags() & DISX86_BAD_WRITE) - exploitability_weight += kMediumBump; - if (disassembler.flags() & DISX86_BAD_BLOCK_WRITE) - exploitability_weight += kMediumBump; - if (disassembler.flags() & DISX86_BAD_READ) - exploitability_weight += kTinyBump; - if (disassembler.flags() & DISX86_BAD_BLOCK_READ) - exploitability_weight += kTinyBump; - if (disassembler.flags() & DISX86_BAD_COMPARISON) - exploitability_weight += kTinyBump; - } - } - } - if (!near_null && AddressIsAscii(address)) - exploitability_weight += kMediumBump; - } else { - BPLOG(INFO) << "Access violation type parameter missing."; - return EXPLOITABILITY_ERR_PROCESSING; - } - } - - // Based on the calculated weight we return a simplified classification. - BPLOG(INFO) << "Calculated exploitability weight: " << exploitability_weight; - if (exploitability_weight >= kHighCutoff) - return EXPLOITABILITY_HIGH; - if (exploitability_weight >= kMediumCutoff) - return EXPLOITABLITY_MEDIUM; - if (exploitability_weight >= kLowCutoff) - return EXPLOITABILITY_LOW; - if (exploitability_weight >= kInterestingCutoff) - return EXPLOITABILITY_INTERESTING; - - return EXPLOITABILITY_NONE; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.h b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.h deleted file mode 100644 index 4e08aef03..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// exploitability_win.h: Windows specific exploitability engine. -// -// Provides a guess at the exploitability of the crash for the Windows -// platform given a minidump and process_state. -// -// Author: Cris Neckar - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/exploitability.h" - -namespace google_breakpad { - -class ExploitabilityWin : public Exploitability { - public: - ExploitabilityWin(Minidump *dump, - ProcessState *process_state); - - virtual ExploitabilityRating CheckPlatformExploitability(); -}; - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver.cc b/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver.cc deleted file mode 100644 index 4a3d00071..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver.cc +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// fast_source_line_resolver.cc: FastSourceLineResolver is a concrete class that -// implements SourceLineResolverInterface. Both FastSourceLineResolver and -// BasicSourceLineResolver inherit from SourceLineResolverBase class to reduce -// code redundancy. -// -// See fast_source_line_resolver.h and fast_source_line_resolver_types.h -// for more documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include "google_breakpad/processor/fast_source_line_resolver.h" -#include "processor/fast_source_line_resolver_types.h" - -#include -#include -#include - -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "processor/module_factory.h" -#include "processor/simple_serializer-inl.h" - -using std::map; -using std::make_pair; - -namespace google_breakpad { - -FastSourceLineResolver::FastSourceLineResolver() - : SourceLineResolverBase(new FastModuleFactory) { } - -bool FastSourceLineResolver::ShouldDeleteMemoryBufferAfterLoadModule() { - return false; -} - -void FastSourceLineResolver::Module::LookupAddress(StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - - // First, look for a FUNC record that covers address. Use - // RetrieveNearestRange instead of RetrieveRange so that, if there - // is no such function, we can use the next function to bound the - // extent of the PUBLIC symbol we find, below. This does mean we - // need to check that address indeed falls within the function we - // find; do the range comparison in an overflow-friendly way. - scoped_ptr func(new Function); - const Function* func_ptr = 0; - scoped_ptr public_symbol(new PublicSymbol); - const PublicSymbol* public_symbol_ptr = 0; - MemAddr function_base; - MemAddr function_size; - MemAddr public_address; - - if (functions_.RetrieveNearestRange(address, func_ptr, - &function_base, &function_size) && - address >= function_base && address - function_base < function_size) { - func.get()->CopyFrom(func_ptr); - frame->function_name = func->name; - frame->function_base = frame->module->base_address() + function_base; - - scoped_ptr line(new Line); - const Line* line_ptr = 0; - MemAddr line_base; - if (func->lines.RetrieveRange(address, line_ptr, &line_base, NULL)) { - line.get()->CopyFrom(line_ptr); - FileMap::iterator it = files_.find(line->source_file_id); - if (it != files_.end()) { - frame->source_file_name = - files_.find(line->source_file_id).GetValuePtr(); - } - frame->source_line = line->line; - frame->source_line_base = frame->module->base_address() + line_base; - } - } else if (public_symbols_.Retrieve(address, - public_symbol_ptr, &public_address) && - (!func_ptr || public_address > function_base)) { - public_symbol.get()->CopyFrom(public_symbol_ptr); - frame->function_name = public_symbol->name; - frame->function_base = frame->module->base_address() + public_address; - } -} - -// WFI: WindowsFrameInfo. -// Returns a WFI object reading from a raw memory chunk of data -WindowsFrameInfo FastSourceLineResolver::CopyWFI(const char *raw) { - const WindowsFrameInfo::StackInfoTypes type = - static_cast( - *reinterpret_cast(raw)); - - // The first 8 bytes of int data are unused. - // They correspond to "StackInfoTypes type_;" and "int valid;" - // data member of WFI. - const uint32_t *para_uint32 = reinterpret_cast( - raw + 2 * sizeof(int32_t)); - - uint32_t prolog_size = para_uint32[0];; - uint32_t epilog_size = para_uint32[1]; - uint32_t parameter_size = para_uint32[2]; - uint32_t saved_register_size = para_uint32[3]; - uint32_t local_size = para_uint32[4]; - uint32_t max_stack_size = para_uint32[5]; - const char *boolean = reinterpret_cast(para_uint32 + 6); - bool allocates_base_pointer = (*boolean != 0); - string program_string = boolean + 1; - - return WindowsFrameInfo(type, - prolog_size, - epilog_size, - parameter_size, - saved_register_size, - local_size, - max_stack_size, - allocates_base_pointer, - program_string); -} - -// Loads a map from the given buffer in char* type. -// Does NOT take ownership of mem_buffer. -// In addition, treat mem_buffer as const char*. -bool FastSourceLineResolver::Module::LoadMapFromMemory( - char *memory_buffer, - size_t memory_buffer_size) { - if (!memory_buffer) return false; - - // Read the "is_corrupt" flag. - const char *mem_buffer = memory_buffer; - mem_buffer = SimpleSerializer::Read(mem_buffer, &is_corrupt_); - - const uint32_t *map_sizes = reinterpret_cast(mem_buffer); - - unsigned int header_size = kNumberMaps_ * sizeof(unsigned int); - - // offsets[]: an array of offset addresses (with respect to mem_buffer), - // for each "Static***Map" component of Module. - // "Static***Map": static version of std::map or map wrapper, i.e., StaticMap, - // StaticAddressMap, StaticContainedRangeMap, and StaticRangeMap. - unsigned int offsets[kNumberMaps_]; - offsets[0] = header_size; - for (int i = 1; i < kNumberMaps_; ++i) { - offsets[i] = offsets[i - 1] + map_sizes[i - 1]; - } - - // Use pointers to construct Static*Map data members in Module: - int map_id = 0; - files_ = StaticMap(mem_buffer + offsets[map_id++]); - functions_ = - StaticRangeMap(mem_buffer + offsets[map_id++]); - public_symbols_ = - StaticAddressMap(mem_buffer + offsets[map_id++]); - for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) - windows_frame_info_[i] = - StaticContainedRangeMap(mem_buffer + offsets[map_id++]); - - cfi_initial_rules_ = - StaticRangeMap(mem_buffer + offsets[map_id++]); - cfi_delta_rules_ = StaticMap(mem_buffer + offsets[map_id++]); - - return true; -} - -WindowsFrameInfo *FastSourceLineResolver::Module::FindWindowsFrameInfo( - const StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - scoped_ptr result(new WindowsFrameInfo()); - - // We only know about WindowsFrameInfo::STACK_INFO_FRAME_DATA and - // WindowsFrameInfo::STACK_INFO_FPO. Prefer them in this order. - // WindowsFrameInfo::STACK_INFO_FRAME_DATA is the newer type that - // includes its own program string. - // WindowsFrameInfo::STACK_INFO_FPO is the older type - // corresponding to the FPO_DATA struct. See stackwalker_x86.cc. - const char* frame_info_ptr; - if ((windows_frame_info_[WindowsFrameInfo::STACK_INFO_FRAME_DATA] - .RetrieveRange(address, frame_info_ptr)) - || (windows_frame_info_[WindowsFrameInfo::STACK_INFO_FPO] - .RetrieveRange(address, frame_info_ptr))) { - result->CopyFrom(CopyWFI(frame_info_ptr)); - return result.release(); - } - - // Even without a relevant STACK line, many functions contain - // information about how much space their parameters consume on the - // stack. Use RetrieveNearestRange instead of RetrieveRange, so that - // we can use the function to bound the extent of the PUBLIC symbol, - // below. However, this does mean we need to check that ADDRESS - // falls within the retrieved function's range; do the range - // comparison in an overflow-friendly way. - scoped_ptr function(new Function); - const Function* function_ptr = 0; - MemAddr function_base, function_size; - if (functions_.RetrieveNearestRange(address, function_ptr, - &function_base, &function_size) && - address >= function_base && address - function_base < function_size) { - function.get()->CopyFrom(function_ptr); - result->parameter_size = function->parameter_size; - result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE; - return result.release(); - } - - // PUBLIC symbols might have a parameter size. Use the function we - // found above to limit the range the public symbol covers. - scoped_ptr public_symbol(new PublicSymbol); - const PublicSymbol* public_symbol_ptr = 0; - MemAddr public_address; - if (public_symbols_.Retrieve(address, public_symbol_ptr, &public_address) && - (!function_ptr || public_address > function_base)) { - public_symbol.get()->CopyFrom(public_symbol_ptr); - result->parameter_size = public_symbol->parameter_size; - } - - return NULL; -} - -CFIFrameInfo *FastSourceLineResolver::Module::FindCFIFrameInfo( - const StackFrame *frame) const { - MemAddr address = frame->instruction - frame->module->base_address(); - MemAddr initial_base, initial_size; - const char* initial_rules = NULL; - - // Find the initial rule whose range covers this address. That - // provides an initial set of register recovery rules. Then, walk - // forward from the initial rule's starting address to frame's - // instruction address, applying delta rules. - if (!cfi_initial_rules_.RetrieveRange(address, initial_rules, - &initial_base, &initial_size)) { - return NULL; - } - - // Create a frame info structure, and populate it with the rules from - // the STACK CFI INIT record. - scoped_ptr rules(new CFIFrameInfo()); - if (!ParseCFIRuleSet(initial_rules, rules.get())) - return NULL; - - // Find the first delta rule that falls within the initial rule's range. - StaticMap::iterator delta = - cfi_delta_rules_.lower_bound(initial_base); - - // Apply delta rules up to and including the frame's address. - while (delta != cfi_delta_rules_.end() && delta.GetKey() <= address) { - ParseCFIRuleSet(delta.GetValuePtr(), rules.get()); - delta++; - } - - return rules.release(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_types.h b/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_types.h deleted file mode 100644 index 2c010470f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_types.h +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// fast_source_line_resolver_types.h: definition of nested classes/structs in -// FastSourceLineResolver. It moves the definitions out of -// fast_source_line_resolver.cc, so that other classes could have access -// to these private nested types without including fast_source_line_resolver.cc -// -// Author: lambxsy@google.com (Siyang Xie) - -#ifndef PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ -#define PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ - -#include "google_breakpad/processor/fast_source_line_resolver.h" -#include "processor/source_line_resolver_base_types.h" - -#include -#include - -#include "google_breakpad/processor/stack_frame.h" -#include "processor/cfi_frame_info.h" -#include "processor/static_address_map-inl.h" -#include "processor/static_contained_range_map-inl.h" -#include "processor/static_map.h" -#include "processor/static_range_map-inl.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -struct FastSourceLineResolver::Line : public SourceLineResolverBase::Line { - void CopyFrom(const Line *line_ptr) { - const char *raw = reinterpret_cast(line_ptr); - CopyFrom(raw); - } - - // De-serialize the memory data of a Line. - void CopyFrom(const char *raw) { - address = *(reinterpret_cast(raw)); - size = *(reinterpret_cast(raw + sizeof(address))); - source_file_id = *(reinterpret_cast( - raw + 2 * sizeof(address))); - line = *(reinterpret_cast( - raw + 2 * sizeof(address) + sizeof(source_file_id))); - } -}; - -struct FastSourceLineResolver::Function : -public SourceLineResolverBase::Function { - void CopyFrom(const Function *func_ptr) { - const char *raw = reinterpret_cast(func_ptr); - CopyFrom(raw); - } - - // De-serialize the memory data of a Function. - void CopyFrom(const char *raw) { - size_t name_size = strlen(raw) + 1; - name = raw; - address = *(reinterpret_cast(raw + name_size)); - size = *(reinterpret_cast( - raw + name_size + sizeof(MemAddr))); - parameter_size = *(reinterpret_cast( - raw + name_size + 2 * sizeof(MemAddr))); - lines = StaticRangeMap( - raw + name_size + 2 * sizeof(MemAddr) + sizeof(int32_t)); - } - - StaticRangeMap lines; -}; - -struct FastSourceLineResolver::PublicSymbol : -public SourceLineResolverBase::PublicSymbol { - void CopyFrom(const PublicSymbol *public_symbol_ptr) { - const char *raw = reinterpret_cast(public_symbol_ptr); - CopyFrom(raw); - } - - // De-serialize the memory data of a PublicSymbol. - void CopyFrom(const char *raw) { - size_t name_size = strlen(raw) + 1; - name = raw; - address = *(reinterpret_cast(raw + name_size)); - parameter_size = *(reinterpret_cast( - raw + name_size + sizeof(MemAddr))); - } -}; - -class FastSourceLineResolver::Module: public SourceLineResolverBase::Module { - public: - explicit Module(const string &name) : name_(name), is_corrupt_(false) { } - virtual ~Module() { } - - // Looks up the given relative address, and fills the StackFrame struct - // with the result. - virtual void LookupAddress(StackFrame *frame) const; - - // Loads a map from the given buffer in char* type. - virtual bool LoadMapFromMemory(char *memory_buffer, - size_t memory_buffer_size); - - // Tells whether the loaded symbol data is corrupt. Return value is - // undefined, if the symbol data hasn't been loaded yet. - virtual bool IsCorrupt() const { return is_corrupt_; } - - // If Windows stack walking information is available covering ADDRESS, - // return a WindowsFrameInfo structure describing it. If the information - // is not available, returns NULL. A NULL return value does not indicate - // an error. The caller takes ownership of any returned WindowsFrameInfo - // object. - virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) const; - - // If CFI stack walking information is available covering ADDRESS, - // return a CFIFrameInfo structure describing it. If the information - // is not available, return NULL. The caller takes ownership of any - // returned CFIFrameInfo object. - virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) const; - - // Number of serialized map components of Module. - static const int kNumberMaps_ = 5 + WindowsFrameInfo::STACK_INFO_LAST; - - private: - friend class FastSourceLineResolver; - friend class ModuleComparer; - typedef StaticMap FileMap; - - string name_; - StaticMap files_; - StaticRangeMap functions_; - StaticAddressMap public_symbols_; - bool is_corrupt_; - - // Each element in the array is a ContainedRangeMap for a type - // listed in WindowsFrameInfoTypes. These are split by type because - // there may be overlaps between maps of different types, but some - // information is only available as certain types. - StaticContainedRangeMap - windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST]; - - // DWARF CFI stack walking data. The Module stores the initial rule sets - // and rule deltas as strings, just as they appear in the symbol file: - // although the file may contain hundreds of thousands of STACK CFI - // records, walking a stack will only ever use a few of them, so it's - // best to delay parsing a record until it's actually needed. - // - // STACK CFI INIT records: for each range, an initial set of register - // recovery rules. The RangeMap's itself gives the starting and ending - // addresses. - StaticRangeMap cfi_initial_rules_; - - // STACK CFI records: at a given address, the changes to the register - // recovery rules that take effect at that address. The map key is the - // starting address; the ending address is the key of the next entry in - // this map, or the end of the range as given by the cfi_initial_rules_ - // entry (which FindCFIFrameInfo looks up first). - StaticMap cfi_delta_rules_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_unittest.cc deleted file mode 100644 index c7215228e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_unittest.cc +++ /dev/null @@ -1,491 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// fast_source_line_resolver_unittest.cc: Unit tests for FastSourceLineResolver. -// Two different approaches for testing fast source line resolver: -// First, use the same unit test data for basic source line resolver. -// Second, read data from symbol files, load them as basic modules, and then -// serialize them and load the serialized data as fast modules. Then compare -// modules to assure the fast module contains exactly the same data as -// basic module. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include -#include - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/memory_region.h" -#include "processor/logging.h" -#include "processor/module_serializer.h" -#include "processor/module_comparer.h" - -namespace { - -using google_breakpad::SourceLineResolverBase; -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::FastSourceLineResolver; -using google_breakpad::ModuleSerializer; -using google_breakpad::ModuleComparer; -using google_breakpad::CFIFrameInfo; -using google_breakpad::CodeModule; -using google_breakpad::MemoryRegion; -using google_breakpad::StackFrame; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::linked_ptr; -using google_breakpad::scoped_ptr; - -class TestCodeModule : public CodeModule { - public: - explicit TestCodeModule(string code_file) : code_file_(code_file) {} - virtual ~TestCodeModule() {} - - virtual uint64_t base_address() const { return 0; } - virtual uint64_t size() const { return 0xb000; } - virtual string code_file() const { return code_file_; } - virtual string code_identifier() const { return ""; } - virtual string debug_file() const { return ""; } - virtual string debug_identifier() const { return ""; } - virtual string version() const { return ""; } - virtual CodeModule* Copy() const { - return new TestCodeModule(code_file_); - } - virtual uint64_t shrink_down_delta() const { return 0; } - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta) {} - - private: - string code_file_; -}; - -// A mock memory region object, for use by the STACK CFI tests. -class MockMemoryRegion: public MemoryRegion { - uint64_t GetBase() const { return 0x10000; } - uint32_t GetSize() const { return 0x01000; } - bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { - *value = address & 0xff; - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { - *value = address & 0xffff; - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { - switch (address) { - case 0x10008: *value = 0x98ecadc3; break; // saved %ebx - case 0x1000c: *value = 0x878f7524; break; // saved %esi - case 0x10010: *value = 0x6312f9a5; break; // saved %edi - case 0x10014: *value = 0x10038; break; // caller's %ebp - case 0x10018: *value = 0xf6438648; break; // return address - default: *value = 0xdeadbeef; break; // junk - } - return true; - } - bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { - *value = address; - return true; - } - void Print() const { - assert(false); - } -}; - -// Verify that, for every association in ACTUAL, EXPECTED has the same -// association. (That is, ACTUAL's associations should be a subset of -// EXPECTED's.) Also verify that ACTUAL has associations for ".ra" and -// ".cfa". -static bool VerifyRegisters( - const char *file, int line, - const CFIFrameInfo::RegisterValueMap &expected, - const CFIFrameInfo::RegisterValueMap &actual) { - CFIFrameInfo::RegisterValueMap::const_iterator a; - a = actual.find(".cfa"); - if (a == actual.end()) - return false; - a = actual.find(".ra"); - if (a == actual.end()) - return false; - for (a = actual.begin(); a != actual.end(); a++) { - CFIFrameInfo::RegisterValueMap::const_iterator e = - expected.find(a->first); - if (e == expected.end()) { - fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n", - file, line, a->first.c_str(), a->second); - return false; - } - if (e->second != a->second) { - fprintf(stderr, - "%s:%d: register '%s' recovered value was 0x%x, expected 0x%x\n", - file, line, a->first.c_str(), a->second, e->second); - return false; - } - // Don't complain if this doesn't recover all registers. Although - // the DWARF spec says that unmentioned registers are undefined, - // GCC uses omission to mean that they are unchanged. - } - return true; -} - -static bool VerifyEmpty(const StackFrame &frame) { - if (frame.function_name.empty() && - frame.source_file_name.empty() && - frame.source_line == 0) - return true; - return false; -} - -static void ClearSourceLineInfo(StackFrame *frame) { - frame->function_name.clear(); - frame->module = NULL; - frame->source_file_name.clear(); - frame->source_line = 0; -} - -class TestFastSourceLineResolver : public ::testing::Test { - public: - void SetUp() { - testdata_dir = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata"; - } - - string symbol_file(int file_index) { - std::stringstream ss; - ss << testdata_dir << "/module" << file_index << ".out"; - return ss.str(); - } - - ModuleSerializer serializer; - BasicSourceLineResolver basic_resolver; - FastSourceLineResolver fast_resolver; - ModuleComparer module_comparer; - - string testdata_dir; -}; - -// Test adapted from basic_source_line_resolver_unittest. -TEST_F(TestFastSourceLineResolver, TestLoadAndResolve) { - TestCodeModule module1("module1"); - ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1))); - ASSERT_TRUE(basic_resolver.HasModule(&module1)); - // Convert module1 to fast_module: - ASSERT_TRUE(serializer.ConvertOneModule( - module1.code_file(), &basic_resolver, &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module1)); - - TestCodeModule module2("module2"); - ASSERT_TRUE(basic_resolver.LoadModule(&module2, symbol_file(2))); - ASSERT_TRUE(basic_resolver.HasModule(&module2)); - // Convert module2 to fast_module: - ASSERT_TRUE(serializer.ConvertOneModule( - module2.code_file(), &basic_resolver, &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module2)); - - StackFrame frame; - scoped_ptr windows_frame_info; - scoped_ptr cfi_frame_info; - frame.instruction = 0x1000; - frame.module = NULL; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_FALSE(frame.module); - ASSERT_TRUE(frame.function_name.empty()); - ASSERT_EQ(frame.function_base, 0U); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - ASSERT_EQ(frame.source_line_base, 0U); - - frame.module = &module1; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_1"); - ASSERT_TRUE(frame.module); - ASSERT_EQ(frame.module->code_file(), "module1"); - ASSERT_EQ(frame.function_base, 0x1000U); - ASSERT_EQ(frame.source_file_name, "file1_1.cc"); - ASSERT_EQ(frame.source_line, 44); - ASSERT_EQ(frame.source_line_base, 0x1000U); - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_EQ(windows_frame_info->program_string, - "$eip 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ ="); - - ClearSourceLineInfo(&frame); - frame.instruction = 0x800; - frame.module = &module1; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_TRUE(VerifyEmpty(frame)); - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_FALSE(windows_frame_info.get()); - - frame.instruction = 0x1280; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_3"); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_UNKNOWN); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_TRUE(windows_frame_info->program_string.empty()); - - frame.instruction = 0x1380; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function1_4"); - ASSERT_TRUE(frame.source_file_name.empty()); - ASSERT_EQ(frame.source_line, 0); - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_FRAME_DATA); - ASSERT_FALSE(windows_frame_info->allocates_base_pointer); - ASSERT_FALSE(windows_frame_info->program_string.empty()); - - frame.instruction = 0x2000; - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_FALSE(windows_frame_info.get()); - - // module1 has STACK CFI records covering 3d40..3def; - // module2 has STACK CFI records covering 3df0..3e9f; - // check that FindCFIFrameInfo doesn't claim to find any outside those ranges. - frame.instruction = 0x3d3f; - frame.module = &module1; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_FALSE(cfi_frame_info.get()); - - frame.instruction = 0x3e9f; - frame.module = &module1; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_FALSE(cfi_frame_info.get()); - - CFIFrameInfo::RegisterValueMap current_registers; - CFIFrameInfo::RegisterValueMap caller_registers; - CFIFrameInfo::RegisterValueMap expected_caller_registers; - MockMemoryRegion memory; - - // Regardless of which instruction evaluation takes place at, it - // should produce the same values for the caller's registers. - expected_caller_registers[".cfa"] = 0x1001c; - expected_caller_registers[".ra"] = 0xf6438648; - expected_caller_registers["$ebp"] = 0x10038; - expected_caller_registers["$ebx"] = 0x98ecadc3; - expected_caller_registers["$esi"] = 0x878f7524; - expected_caller_registers["$edi"] = 0x6312f9a5; - - frame.instruction = 0x3d40; - frame.module = &module1; - current_registers.clear(); - current_registers["$esp"] = 0x10018; - current_registers["$ebp"] = 0x10038; - current_registers["$ebx"] = 0x98ecadc3; - current_registers["$esi"] = 0x878f7524; - current_registers["$edi"] = 0x6312f9a5; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers)); - - frame.instruction = 0x3d41; - current_registers["$esp"] = 0x10014; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers)); - - frame.instruction = 0x3d43; - current_registers["$ebp"] = 0x10014; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d54; - current_registers["$ebx"] = 0x6864f054U; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d5a; - current_registers["$esi"] = 0x6285f79aU; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x3d84; - current_registers["$edi"] = 0x64061449U; - cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); - ASSERT_TRUE(cfi_frame_info.get()); - ASSERT_TRUE(cfi_frame_info.get() - ->FindCallerRegs(current_registers, memory, - &caller_registers)); - VerifyRegisters(__FILE__, __LINE__, - expected_caller_registers, caller_registers); - - frame.instruction = 0x2900; - frame.module = &module1; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, string("PublicSymbol")); - - frame.instruction = 0x4000; - frame.module = &module1; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, string("LargeFunction")); - - frame.instruction = 0x2181; - frame.module = &module2; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Function2_2"); - ASSERT_EQ(frame.function_base, 0x2170U); - ASSERT_TRUE(frame.module); - ASSERT_EQ(frame.module->code_file(), "module2"); - ASSERT_EQ(frame.source_file_name, "file2_2.cc"); - ASSERT_EQ(frame.source_line, 21); - ASSERT_EQ(frame.source_line_base, 0x2180U); - windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame)); - ASSERT_TRUE(windows_frame_info.get()); - ASSERT_EQ(windows_frame_info->type_, WindowsFrameInfo::STACK_INFO_FRAME_DATA); - ASSERT_EQ(windows_frame_info->prolog_size, 1U); - - frame.instruction = 0x216f; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Public2_1"); - - ClearSourceLineInfo(&frame); - frame.instruction = 0x219f; - frame.module = &module2; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_TRUE(frame.function_name.empty()); - - frame.instruction = 0x21a0; - frame.module = &module2; - fast_resolver.FillSourceLineInfo(&frame); - ASSERT_EQ(frame.function_name, "Public2_2"); -} - -TEST_F(TestFastSourceLineResolver, TestInvalidLoads) { - TestCodeModule module3("module3"); - ASSERT_TRUE(basic_resolver.LoadModule(&module3, - testdata_dir + "/module3_bad.out")); - ASSERT_TRUE(basic_resolver.HasModule(&module3)); - ASSERT_TRUE(basic_resolver.IsModuleCorrupt(&module3)); - // Convert module3 to fast_module: - ASSERT_TRUE(serializer.ConvertOneModule(module3.code_file(), - &basic_resolver, - &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module3)); - ASSERT_TRUE(fast_resolver.IsModuleCorrupt(&module3)); - - TestCodeModule module4("module4"); - ASSERT_TRUE(basic_resolver.LoadModule(&module4, - testdata_dir + "/module4_bad.out")); - ASSERT_TRUE(basic_resolver.HasModule(&module4)); - ASSERT_TRUE(basic_resolver.IsModuleCorrupt(&module4)); - // Convert module4 to fast_module: - ASSERT_TRUE(serializer.ConvertOneModule(module4.code_file(), - &basic_resolver, - &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module4)); - ASSERT_TRUE(fast_resolver.IsModuleCorrupt(&module4)); - - TestCodeModule module5("module5"); - ASSERT_FALSE(fast_resolver.LoadModule(&module5, - testdata_dir + "/invalid-filename")); - ASSERT_FALSE(fast_resolver.HasModule(&module5)); - - TestCodeModule invalidmodule("invalid-module"); - ASSERT_FALSE(fast_resolver.HasModule(&invalidmodule)); -} - -TEST_F(TestFastSourceLineResolver, TestUnload) { - TestCodeModule module1("module1"); - ASSERT_FALSE(basic_resolver.HasModule(&module1)); - - ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1))); - ASSERT_TRUE(basic_resolver.HasModule(&module1)); - // Convert module1 to fast_module. - ASSERT_TRUE(serializer.ConvertOneModule(module1.code_file(), - &basic_resolver, - &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module1)); - basic_resolver.UnloadModule(&module1); - fast_resolver.UnloadModule(&module1); - ASSERT_FALSE(fast_resolver.HasModule(&module1)); - - ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1))); - ASSERT_TRUE(basic_resolver.HasModule(&module1)); - // Convert module1 to fast_module. - ASSERT_TRUE(serializer.ConvertOneModule(module1.code_file(), - &basic_resolver, - &fast_resolver)); - ASSERT_TRUE(fast_resolver.HasModule(&module1)); -} - -TEST_F(TestFastSourceLineResolver, CompareModule) { - char *symbol_data; - size_t symbol_data_size; - string symbol_data_string; - string filename; - - for (int module_index = 0; module_index < 3; ++module_index) { - std::stringstream ss; - ss << testdata_dir << "/module" << module_index << ".out"; - filename = ss.str(); - ASSERT_TRUE(SourceLineResolverBase::ReadSymbolFile( - symbol_file(module_index), &symbol_data, &symbol_data_size)); - symbol_data_string.assign(symbol_data, symbol_data_size); - delete [] symbol_data; - ASSERT_TRUE(module_comparer.Compare(symbol_data_string)); - } -} - -} // namespace - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/linked_ptr.h b/toolkit/crashreporter/google-breakpad/src/processor/linked_ptr.h deleted file mode 100644 index 72fbba84a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/linked_ptr.h +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// A "smart" pointer type with reference tracking. Every pointer to a -// particular object is kept on a circular linked list. When the last pointer -// to an object is destroyed or reassigned, the object is deleted. -// -// Used properly, this deletes the object when the last reference goes away. -// There are several caveats: -// - Like all reference counting schemes, cycles lead to leaks. -// - Each smart pointer is actually two pointers (8 bytes instead of 4). -// - Every time a pointer is assigned, the entire list of pointers to that -// object is traversed. This class is therefore NOT SUITABLE when there -// will often be more than two or three pointers to a particular object. -// - References are only tracked as long as linked_ptr<> objects are copied. -// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS -// will happen (double deletion). -// -// A good use of this class is storing object references in STL containers. -// You can safely put linked_ptr<> in a vector<>. -// Other uses may not be as good. -// -// Note: If you use an incomplete type with linked_ptr<>, the class -// *containing* linked_ptr<> must have a constructor and destructor (even -// if they do nothing!). - -#ifndef PROCESSOR_LINKED_PTR_H__ -#define PROCESSOR_LINKED_PTR_H__ - -namespace google_breakpad { - -// This is used internally by all instances of linked_ptr<>. It needs to be -// a non-template class because different types of linked_ptr<> can refer to -// the same object (linked_ptr(obj) vs linked_ptr(obj)). -// So, it needs to be possible for different types of linked_ptr to participate -// in the same circular linked list, so we need a single class type here. -// -// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. -class linked_ptr_internal { - public: - // Create a new circle that includes only this instance. - void join_new() { - next_ = this; - } - - // Join an existing circle. - void join(linked_ptr_internal const* ptr) { - linked_ptr_internal const* p = ptr; - while (p->next_ != ptr) p = p->next_; - p->next_ = this; - next_ = ptr; - } - - // Leave whatever circle we're part of. Returns true iff we were the - // last member of the circle. Once this is done, you can join() another. - bool depart() { - if (next_ == this) return true; - linked_ptr_internal const* p = next_; - while (p->next_ != this) p = p->next_; - p->next_ = next_; - return false; - } - - private: - mutable linked_ptr_internal const* next_; -}; - -template -class linked_ptr { - public: - typedef T element_type; - - // Take over ownership of a raw pointer. This should happen as soon as - // possible after the object is created. - explicit linked_ptr(T* ptr = NULL) { capture(ptr); } - ~linked_ptr() { depart(); } - - // Copy an existing linked_ptr<>, adding ourselves to the list of references. - template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } - linked_ptr(linked_ptr const& ptr) { copy(&ptr); } - - // Assignment releases the old value and acquires the new. - template linked_ptr& operator=(linked_ptr const& ptr) { - depart(); - copy(&ptr); - return *this; - } - - linked_ptr& operator=(linked_ptr const& ptr) { - if (&ptr != this) { - depart(); - copy(&ptr); - } - return *this; - } - - // Smart pointer members. - void reset(T* ptr = NULL) { depart(); capture(ptr); } - T* get() const { return value_; } - T* operator->() const { return value_; } - T& operator*() const { return *value_; } - // Release ownership of the pointed object and returns it. - // Sole ownership by this linked_ptr object is required. - T* release() { - link_.depart(); - T* v = value_; - value_ = NULL; - return v; - } - - bool operator==(T* p) const { return value_ == p; } - bool operator!=(T* p) const { return value_ != p; } - template - bool operator==(linked_ptr const& ptr) const { - return value_ == ptr.get(); - } - template - bool operator!=(linked_ptr const& ptr) const { - return value_ != ptr.get(); - } - - private: - template - friend class linked_ptr; - - T* value_; - linked_ptr_internal link_; - - void depart() { - if (link_.depart()) delete value_; - } - - void capture(T* ptr) { - value_ = ptr; - link_.join_new(); - } - - template void copy(linked_ptr const* ptr) { - value_ = ptr->get(); - if (value_) - link_.join(&ptr->link_); - else - link_.join_new(); - } -}; - -template inline -bool operator==(T* ptr, const linked_ptr& x) { - return ptr == x.get(); -} - -template inline -bool operator!=(T* ptr, const linked_ptr& x) { - return ptr != x.get(); -} - -// A function to convert T* into linked_ptr -// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation -// for linked_ptr >(new FooBarBaz(arg)) -template -linked_ptr make_linked_ptr(T* ptr) { - return linked_ptr(ptr); -} - -} // namespace google_breakpad - -#endif // PROCESSOR_LINKED_PTR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/logging.cc b/toolkit/crashreporter/google-breakpad/src/processor/logging.cc deleted file mode 100644 index c1eebbc22..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/logging.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// logging.cc: Breakpad logging -// -// See logging.h for documentation. -// -// Author: Mark Mentovai - -#include -#include -#include -#include - -#include - -#include "common/stdio_wrapper.h" -#include "common/using_std_string.h" -#include "processor/logging.h" -#include "processor/pathname_stripper.h" - -namespace google_breakpad { - -LogStream::LogStream(std::ostream &stream, Severity severity, - const char *file, int line) - : stream_(stream) { - time_t clock; - time(&clock); - struct tm tm_struct; -#ifdef _WIN32 - localtime_s(&tm_struct, &clock); -#else - localtime_r(&clock, &tm_struct); -#endif - char time_string[20]; - strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", &tm_struct); - - const char *severity_string = "UNKNOWN_SEVERITY"; - switch (severity) { - case SEVERITY_INFO: - severity_string = "INFO"; - break; - case SEVERITY_ERROR: - severity_string = "ERROR"; - break; - } - - stream_ << time_string << ": " << PathnameStripper::File(file) << ":" << - line << ": " << severity_string << ": "; -} - -LogStream::~LogStream() { - stream_ << std::endl; -} - -string HexString(uint32_t number) { - char buffer[11]; - snprintf(buffer, sizeof(buffer), "0x%x", number); - return string(buffer); -} - -string HexString(uint64_t number) { - char buffer[19]; - snprintf(buffer, sizeof(buffer), "0x%" PRIx64, number); - return string(buffer); -} - -string HexString(int number) { - char buffer[19]; - snprintf(buffer, sizeof(buffer), "0x%x", number); - return string(buffer); -} - -int ErrnoString(string *error_string) { - assert(error_string); - - // strerror isn't necessarily thread-safe. strerror_r would be preferrable, - // but GNU libc uses a nonstandard strerror_r by default, which returns a - // char* (rather than an int success indicator) and doesn't necessarily - // use the supplied buffer. - error_string->assign(strerror(errno)); - return errno; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/logging.h b/toolkit/crashreporter/google-breakpad/src/processor/logging.h deleted file mode 100644 index 406fb67cf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/logging.h +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// logging.h: Breakpad logging -// -// Breakpad itself uses Breakpad logging with statements of the form: -// BPLOG(severity) << "message"; -// severity may be INFO, ERROR, or other values defined in this file. -// -// BPLOG is an overridable macro so that users can customize Breakpad's -// logging. Left at the default, logging messages are sent to stderr along -// with a timestamp and the source code location that produced a message. -// The streams may be changed by redefining BPLOG_*_STREAM, the logging -// behavior may be changed by redefining BPLOG_*, and the entire logging -// system may be overridden by redefining BPLOG(severity). These -// redefinitions may be passed to the preprocessor as a command-line flag -// (-D). -// -// If an additional header is required to override Breakpad logging, it can -// be specified by the BP_LOGGING_INCLUDE macro. If defined, this header -// will #include the header specified by that macro. -// -// If any initialization is needed before logging, it can be performed by -// a function called through the BPLOG_INIT macro. Each main function of -// an executable program in the Breakpad processor library calls -// BPLOG_INIT(&argc, &argv); before any logging can be performed; define -// BPLOG_INIT appropriately if initialization is required. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_LOGGING_H__ -#define PROCESSOR_LOGGING_H__ - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" - -#ifdef BP_LOGGING_INCLUDE -#include BP_LOGGING_INCLUDE -#endif // BP_LOGGING_INCLUDE - -#ifndef THIRD_PARTY_BREAKPAD_GOOGLE_GLUE_LOGGING_H_ -namespace base_logging { - -// The open-source copy of logging.h has diverged from Google's internal copy -// (temporarily, at least). To support the transition to structured logging -// a definition for base_logging::LogMessage is needed, which is a ostream- -// like object for streaming arguments to construct a log message. -typedef std::ostream LogMessage; - -} // namespace base_logging -#endif // THIRD_PARTY_BREAKPAD_GOOGLE_GLUE_LOGGING_H_ - -namespace google_breakpad { - -// These are defined in Microsoft headers. -#ifdef SEVERITY_ERROR -#undef SEVERITY_ERROR -#endif - -#ifdef ERROR -#undef ERROR -#endif - -class LogStream { - public: - enum Severity { - SEVERITY_INFO, - SEVERITY_ERROR - }; - - // Begin logging a message to the stream identified by |stream|, at the - // indicated severity. The file and line parameters should be set so as to - // identify the line of source code that is producing a message. - LogStream(std::ostream &stream, Severity severity, - const char *file, int line); - - // Finish logging by printing a newline and flushing the output stream. - ~LogStream(); - - template std::ostream& operator<<(const T &t) { - return stream_ << t; - } - - private: - std::ostream &stream_; - - // Disallow copy constructor and assignment operator - explicit LogStream(const LogStream &that); - void operator=(const LogStream &that); -}; - -// This class is used to explicitly ignore values in the conditional logging -// macros. This avoids compiler warnings like "value computed is not used" -// and "statement has no effect". -class LogMessageVoidify { - public: - LogMessageVoidify() {} - - // This has to be an operator with a precedence lower than << but higher - // than ?: - void operator&(base_logging::LogMessage &) {} -}; - -// Returns number formatted as a hexadecimal string, such as "0x7b". -string HexString(uint32_t number); -string HexString(uint64_t number); -string HexString(int number); - -// Returns the error code as set in the global errno variable, and sets -// error_string, a required argument, to a string describing that error -// code. -int ErrnoString(string *error_string); - -} // namespace google_breakpad - -#ifndef BPLOG_INIT -#define BPLOG_INIT(pargc, pargv) -#endif // BPLOG_INIT - -#define BPLOG_LAZY_STREAM(stream, condition) \ - !(condition) ? (void) 0 : \ - google_breakpad::LogMessageVoidify() & (BPLOG_ ## stream) - -#ifndef BPLOG_MINIMUM_SEVERITY -#define BPLOG_MINIMUM_SEVERITY SEVERITY_INFO -#endif - -#define BPLOG_LOG_IS_ON(severity) \ - ((google_breakpad::LogStream::SEVERITY_ ## severity) >= \ - (google_breakpad::LogStream::BPLOG_MINIMUM_SEVERITY)) - -#ifndef BPLOG -#define BPLOG(severity) BPLOG_LAZY_STREAM(severity, BPLOG_LOG_IS_ON(severity)) -#endif // BPLOG - -#ifndef BPLOG_INFO -#ifndef BPLOG_INFO_STREAM -#define BPLOG_INFO_STREAM std::clog -#endif // BPLOG_INFO_STREAM -#define BPLOG_INFO google_breakpad::LogStream(BPLOG_INFO_STREAM, \ - google_breakpad::LogStream::SEVERITY_INFO, \ - __FILE__, __LINE__) -#endif // BPLOG_INFO - -#ifndef BPLOG_ERROR -#ifndef BPLOG_ERROR_STREAM -#define BPLOG_ERROR_STREAM std::cerr -#endif // BPLOG_ERROR_STREAM -#define BPLOG_ERROR google_breakpad::LogStream(BPLOG_ERROR_STREAM, \ - google_breakpad::LogStream::SEVERITY_ERROR, \ - __FILE__, __LINE__) -#endif // BPLOG_ERROR - -#define BPLOG_IF(severity, condition) \ - BPLOG_LAZY_STREAM(severity, ((condition) && BPLOG_LOG_IS_ON(severity))) - -#endif // PROCESSOR_LOGGING_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h deleted file mode 100644 index 61c7bbd7c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// map_serializers_inl.h: implementation for serializing std::map and its -// wrapper classes. -// -// See map_serializers.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_MAP_SERIALIZERS_INL_H__ -#define PROCESSOR_MAP_SERIALIZERS_INL_H__ - -#include -#include - -#include "processor/map_serializers.h" -#include "processor/simple_serializer.h" - -#include "processor/address_map-inl.h" -#include "processor/range_map-inl.h" -#include "processor/contained_range_map-inl.h" - -#include "processor/logging.h" - -namespace google_breakpad { - -template -size_t StdMapSerializer::SizeOf( - const std::map &m) const { - size_t size = 0; - size_t header_size = (1 + m.size()) * sizeof(uint32_t); - size += header_size; - - typename std::map::const_iterator iter; - for (iter = m.begin(); iter != m.end(); ++iter) { - size += key_serializer_.SizeOf(iter->first); - size += value_serializer_.SizeOf(iter->second); - } - return size; -} - -template -char *StdMapSerializer::Write(const std::map &m, - char *dest) const { - if (!dest) { - BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; - return NULL; - } - char *start_address = dest; - - // Write header: - // Number of nodes. - dest = SimpleSerializer::Write(m.size(), dest); - // Nodes offsets. - uint32_t *offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m.size(); - - char *key_address = dest; - dest += sizeof(Key) * m.size(); - - // Traverse map. - typename std::map::const_iterator iter; - int index = 0; - for (iter = m.begin(); iter != m.end(); ++iter, ++index) { - offsets[index] = static_cast(dest - start_address); - key_address = key_serializer_.Write(iter->first, key_address); - dest = value_serializer_.Write(iter->second, dest); - } - return dest; -} - -template -char *StdMapSerializer::Serialize( - const std::map &m, unsigned int *size) const { - // Compute size of memory to be allocated. - unsigned int size_to_alloc = SizeOf(m); - // Allocate memory. - char *serialized_data = new char[size_to_alloc]; - if (!serialized_data) { - BPLOG(INFO) << "StdMapSerializer memory allocation failed."; - if (size) *size = 0; - return NULL; - } - // Write serialized data into memory. - Write(m, serialized_data); - - if (size) *size = size_to_alloc; - return serialized_data; -} - -template -size_t RangeMapSerializer::SizeOf( - const RangeMap &m) const { - size_t size = 0; - size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t); - size += header_size; - - typename std::map::const_iterator iter; - for (iter = m.map_.begin(); iter != m.map_.end(); ++iter) { - // Size of key (high address). - size += address_serializer_.SizeOf(iter->first); - // Size of base (low address). - size += address_serializer_.SizeOf(iter->second.base()); - // Size of entry. - size += entry_serializer_.SizeOf(iter->second.entry()); - } - return size; -} - -template -char *RangeMapSerializer::Write( - const RangeMap &m, char *dest) const { - if (!dest) { - BPLOG(ERROR) << "RangeMapSerializer failed: write to NULL address."; - return NULL; - } - char *start_address = dest; - - // Write header: - // Number of nodes. - dest = SimpleSerializer::Write(m.map_.size(), dest); - // Nodes offsets. - uint32_t *offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m.map_.size(); - - char *key_address = dest; - dest += sizeof(Address) * m.map_.size(); - - // Traverse map. - typename std::map::const_iterator iter; - int index = 0; - for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) { - offsets[index] = static_cast(dest - start_address); - key_address = address_serializer_.Write(iter->first, key_address); - dest = address_serializer_.Write(iter->second.base(), dest); - dest = entry_serializer_.Write(iter->second.entry(), dest); - } - return dest; -} - -template -char *RangeMapSerializer::Serialize( - const RangeMap &m, unsigned int *size) const { - // Compute size of memory to be allocated. - unsigned int size_to_alloc = SizeOf(m); - // Allocate memory. - char *serialized_data = new char[size_to_alloc]; - if (!serialized_data) { - BPLOG(INFO) << "RangeMapSerializer memory allocation failed."; - if (size) *size = 0; - return NULL; - } - - // Write serialized data into memory. - Write(m, serialized_data); - - if (size) *size = size_to_alloc; - return serialized_data; -} - - -template -size_t ContainedRangeMapSerializer::SizeOf( - const ContainedRangeMap *m) const { - size_t size = 0; - size_t header_size = addr_serializer_.SizeOf(m->base_) - + entry_serializer_.SizeOf(m->entry_) - + sizeof(uint32_t); - size += header_size; - // In case m.map_ == NULL, we treat it as an empty map: - size += sizeof(uint32_t); - if (m->map_) { - size += m->map_->size() * sizeof(uint32_t); - typename Map::const_iterator iter; - for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) { - size += addr_serializer_.SizeOf(iter->first); - // Recursive calculation of size: - size += SizeOf(iter->second); - } - } - return size; -} - -template -char *ContainedRangeMapSerializer::Write( - const ContainedRangeMap *m, char *dest) const { - if (!dest) { - BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; - return NULL; - } - dest = addr_serializer_.Write(m->base_, dest); - dest = SimpleSerializer::Write(entry_serializer_.SizeOf(m->entry_), - dest); - dest = entry_serializer_.Write(m->entry_, dest); - - // Write map<: - char *map_address = dest; - if (m->map_ == NULL) { - dest = SimpleSerializer::Write(0, dest); - } else { - dest = SimpleSerializer::Write(m->map_->size(), dest); - uint32_t *offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m->map_->size(); - - char *key_address = dest; - dest += sizeof(AddrType) * m->map_->size(); - - // Traverse map. - typename Map::const_iterator iter; - int index = 0; - for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) { - offsets[index] = static_cast(dest - map_address); - key_address = addr_serializer_.Write(iter->first, key_address); - // Recursively write. - dest = Write(iter->second, dest); - } - } - return dest; -} - -template -char *ContainedRangeMapSerializer::Serialize( - const ContainedRangeMap *m, unsigned int *size) const { - unsigned int size_to_alloc = SizeOf(m); - // Allocating memory. - char *serialized_data = new char[size_to_alloc]; - if (!serialized_data) { - BPLOG(INFO) << "ContainedRangeMapSerializer memory allocation failed."; - if (size) *size = 0; - return NULL; - } - Write(m, serialized_data); - if (size) *size = size_to_alloc; - return serialized_data; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_MAP_SERIALIZERS_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers.h b/toolkit/crashreporter/google-breakpad/src/processor/map_serializers.h deleted file mode 100644 index a0b9d3fd6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// map_serializers.h: defines templates for serializing std::map and its -// wrappers: AddressMap, RangeMap, and ContainedRangeMap. -// -// Author: Siyang Xie (lambxsy@google.com) - - -#ifndef PROCESSOR_MAP_SERIALIZERS_H__ -#define PROCESSOR_MAP_SERIALIZERS_H__ - -#include -#include - -#include "processor/simple_serializer.h" - -#include "processor/address_map-inl.h" -#include "processor/range_map-inl.h" -#include "processor/contained_range_map-inl.h" - -namespace google_breakpad { - -// StdMapSerializer allocates memory and serializes an std::map instance into a -// chunk of memory data. -template -class StdMapSerializer { - public: - // Calculate the memory size of serialized data. - size_t SizeOf(const std::map &m) const; - - // Writes the serialized data to memory with start address = dest, - // and returns the "end" of data, i.e., return the address follow the final - // byte of data. - // NOTE: caller has to allocate enough memory before invoke Write() method. - char* Write(const std::map &m, char* dest) const; - - // Serializes a std::map object into a chunk of memory data with format - // described in "StaticMap.h" comment. - // Returns a pointer to the serialized data. If size != NULL, *size is set - // to the size of serialized data, i.e., SizeOf(m). - // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const std::map &m, unsigned int *size) const; - - private: - SimpleSerializer key_serializer_; - SimpleSerializer value_serializer_; -}; - -// AddressMapSerializer allocates memory and serializes an AddressMap into a -// chunk of memory data. -template -class AddressMapSerializer { - public: - // Calculate the memory size of serialized data. - size_t SizeOf(const AddressMap &m) const { - return std_map_serializer_.SizeOf(m.map_); - } - - // Write the serialized data to specified memory location. Return the "end" - // of data, i.e., return the address after the final byte of data. - // NOTE: caller has to allocate enough memory before invoke Write() method. - char* Write(const AddressMap &m, char *dest) const { - return std_map_serializer_.Write(m.map_, dest); - } - - // Serializes an AddressMap object into a chunk of memory data. - // Returns a pointer to the serialized data. If size != NULL, *size is set - // to the size of serialized data, i.e., SizeOf(m). - // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const AddressMap &m, unsigned int *size) const { - return std_map_serializer_.Serialize(m.map_, size); - } - - private: - // AddressMapSerializer is a simple wrapper of StdMapSerializer, just as - // AddressMap is a simple wrapper of std::map. - StdMapSerializer std_map_serializer_; -}; - -// RangeMapSerializer allocates memory and serializes a RangeMap instance into a -// chunk of memory data. -template -class RangeMapSerializer { - public: - // Calculate the memory size of serialized data. - size_t SizeOf(const RangeMap &m) const; - - // Write the serialized data to specified memory location. Return the "end" - // of data, i.e., return the address after the final byte of data. - // NOTE: caller has to allocate enough memory before invoke Write() method. - char* Write(const RangeMap &m, char* dest) const; - - // Serializes a RangeMap object into a chunk of memory data. - // Returns a pointer to the serialized data. If size != NULL, *size is set - // to the size of serialized data, i.e., SizeOf(m). - // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const RangeMap &m, unsigned int *size) const; - - private: - // Convenient type name for Range. - typedef typename RangeMap::Range Range; - - // Serializer for RangeMap's key and Range::base_. - SimpleSerializer
address_serializer_; - // Serializer for RangeMap::Range::entry_. - SimpleSerializer entry_serializer_; -}; - -// ContainedRangeMapSerializer allocates memory and serializes a -// ContainedRangeMap instance into a chunk of memory data. -template -class ContainedRangeMapSerializer { - public: - // Calculate the memory size of serialized data. - size_t SizeOf(const ContainedRangeMap *m) const; - - // Write the serialized data to specified memory location. Return the "end" - // of data, i.e., return the address after the final byte of data. - // NOTE: caller has to allocate enough memory before invoke Write() method. - char* Write(const ContainedRangeMap *m, - char* dest) const; - - // Serializes a ContainedRangeMap object into a chunk of memory data. - // Returns a pointer to the serialized data. If size != NULL, *size is set - // to the size of serialized data, i.e., SizeOf(m). - // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const ContainedRangeMap *m, - unsigned int *size) const; - - private: - // Convenient type name for the underlying map type. - typedef std::map*> Map; - - // Serializer for addresses and entries stored in ContainedRangeMap. - SimpleSerializer addr_serializer_; - SimpleSerializer entry_serializer_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_MAP_SERIALIZERS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/map_serializers_unittest.cc deleted file mode 100644 index 0d872ec2e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/map_serializers_unittest.cc +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// map_serializers_unittest.cc: Unit tests for std::map serializer and -// std::map wrapper serializers. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "map_serializers-inl.h" - -#include "processor/address_map-inl.h" -#include "processor/range_map-inl.h" -#include "processor/contained_range_map-inl.h" - -typedef int32_t AddrType; -typedef int32_t EntryType; - -class TestStdMapSerializer : public ::testing::Test { - protected: - void SetUp() { - serialized_size_ = 0; - serialized_data_ = NULL; - } - - void TearDown() { - delete [] serialized_data_; - } - - std::map std_map_; - google_breakpad::StdMapSerializer serializer_; - uint32_t serialized_size_; - char *serialized_data_; -}; - -TEST_F(TestStdMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); - - // std_map_ is empty. - serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestStdMapSerializer, MapWithTwoElementsTestCase) { - const int32_t correct_data[] = { - // # of nodes - 2, - // Offsets - 20, 24, - // Keys - 1, 3, - // Values - 2, 6 - }; - uint32_t correct_size = sizeof(correct_data); - - std_map_.insert(std::make_pair(1, 2)); - std_map_.insert(std::make_pair(3, 6)); - - serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestStdMapSerializer, MapWithFiveElementsTestCase) { - const int32_t correct_data[] = { - // # of nodes - 5, - // Offsets - 44, 48, 52, 56, 60, - // Keys - 1, 2, 3, 4, 5, - // Values - 11, 12, 13, 14, 15 - }; - uint32_t correct_size = sizeof(correct_data); - - for (int i = 1; i < 6; ++i) - std_map_.insert(std::make_pair(i, 10 + i)); - - serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -class TestAddressMapSerializer : public ::testing::Test { - protected: - void SetUp() { - serialized_size_ = 0; - serialized_data_ = 0; - } - - void TearDown() { - delete [] serialized_data_; - } - - google_breakpad::AddressMap address_map_; - google_breakpad::AddressMapSerializer serializer_; - uint32_t serialized_size_; - char *serialized_data_; -}; - -TEST_F(TestAddressMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); - - // std_map_ is empty. - serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestAddressMapSerializer, MapWithTwoElementsTestCase) { - const int32_t correct_data[] = { - // # of nodes - 2, - // Offsets - 20, 24, - // Keys - 1, 3, - // Values - 2, 6 - }; - uint32_t correct_size = sizeof(correct_data); - - address_map_.Store(1, 2); - address_map_.Store(3, 6); - - serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestAddressMapSerializer, MapWithFourElementsTestCase) { - const int32_t correct_data[] = { - // # of nodes - 4, - // Offsets - 36, 40, 44, 48, - // Keys - -6, -4, 8, 123, - // Values - 2, 3, 5, 8 - }; - uint32_t correct_size = sizeof(correct_data); - - address_map_.Store(-6, 2); - address_map_.Store(-4, 3); - address_map_.Store(8, 5); - address_map_.Store(123, 8); - - serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - - -class TestRangeMapSerializer : public ::testing::Test { - protected: - void SetUp() { - serialized_size_ = 0; - serialized_data_ = 0; - } - - void TearDown() { - delete [] serialized_data_; - } - - google_breakpad::RangeMap range_map_; - google_breakpad::RangeMapSerializer serializer_; - uint32_t serialized_size_; - char *serialized_data_; -}; - -TEST_F(TestRangeMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); - - // range_map_ is empty. - serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestRangeMapSerializer, MapWithOneRangeTestCase) { - const int32_t correct_data[] = { - // # of nodes - 1, - // Offsets - 12, - // Keys: high address - 10, - // Values: (low address, entry) pairs - 1, 6 - }; - uint32_t correct_size = sizeof(correct_data); - - range_map_.StoreRange(1, 10, 6); - - serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestRangeMapSerializer, MapWithThreeRangesTestCase) { - const int32_t correct_data[] = { - // # of nodes - 3, - // Offsets - 28, 36, 44, - // Keys: high address - 5, 9, 20, - // Values: (low address, entry) pairs - 2, 1, 6, 2, 10, 3 - }; - uint32_t correct_size = sizeof(correct_data); - - ASSERT_TRUE(range_map_.StoreRange(2, 4, 1)); - ASSERT_TRUE(range_map_.StoreRange(6, 4, 2)); - ASSERT_TRUE(range_map_.StoreRange(10, 11, 3)); - - serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - - -class TestContainedRangeMapSerializer : public ::testing::Test { - protected: - void SetUp() { - serialized_size_ = 0; - serialized_data_ = 0; - } - - void TearDown() { - delete [] serialized_data_; - } - - google_breakpad::ContainedRangeMap crm_map_; - google_breakpad::ContainedRangeMapSerializer serializer_; - uint32_t serialized_size_; - char *serialized_data_; -}; - -TEST_F(TestContainedRangeMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { - 0, // base address of root - 4, // size of entry - 0, // entry stored at root - 0 // empty map stored at root - }; - uint32_t correct_size = sizeof(correct_data); - - // crm_map_ is empty. - serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestContainedRangeMapSerializer, MapWithOneRangeTestCase) { - const int32_t correct_data[] = { - 0, // base address of root - 4, // size of entry - 0, // entry stored at root - // Map stored at root node: - 1, // # of nodes - 12, // offset - 9, // key - // value: a child ContainedRangeMap - 3, // base address of child CRM - 4, // size of entry - -1, // entry stored in child CRM - 0 // empty sub-map stored in child CRM - }; - uint32_t correct_size = sizeof(correct_data); - - crm_map_.StoreRange(3, 7, -1); - - serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - -TEST_F(TestContainedRangeMapSerializer, MapWithTwoLevelsTestCase) { - // Tree structure of ranges: - // root level 0 - // | - // map - // / \ level 1: child1, child2 - // 2~8 10~20 - // | | - // map map - // / \ | - // 3~4 6~7 16-20 level 2: grandchild1, grandchild2, grandchild3 - - const int32_t correct_data[] = { - // root: base, entry_size, entry - 0, 4, 0, - // root's map: # of nodes, offset1, offset2, key1, key2 - 2, 20, 84, 8, 20, - // child1: base, entry_size, entry: - 2, 4, -1, - // child1's map: # of nodes, offset1, offset2, key1, key2 - 2, 20, 36, 4, 7, - // grandchild1: base, entry_size, entry, empty_map - 3, 4, -1, 0, - // grandchild2: base, entry_size, entry, empty_map - 6, 4, -1, 0, - // child2: base, entry_size, entry: - 10, 4, -1, - // child2's map: # of nodes, offset1, key1 - 1, 12, 20, - // grandchild3: base, entry_size, entry, empty_map - 16, 4, -1, 0 - }; - uint32_t correct_size = sizeof(correct_data); - - // Store child1. - ASSERT_TRUE(crm_map_.StoreRange(2, 7, -1)); - // Store child2. - ASSERT_TRUE(crm_map_.StoreRange(10, 11, -1)); - // Store grandchild1. - ASSERT_TRUE(crm_map_.StoreRange(3, 2, -1)); - // Store grandchild2. - ASSERT_TRUE(crm_map_.StoreRange(6, 2, -1)); - // Store grandchild3. - ASSERT_TRUE(crm_map_.StoreRange(16, 5, -1)); - - serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_); - - EXPECT_EQ(correct_size, serialized_size_); - EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0); -} - - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc b/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc deleted file mode 100644 index 4af62f56f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// microdump.cc: A microdump reader. -// -// See microdump.h for documentation. - -#include "google_breakpad/processor/microdump.h" - -#include -#include - -#include -#include -#include -#include - -#include "google_breakpad/common/minidump_cpu_arm.h" -#include "google_breakpad/processor/code_module.h" -#include "processor/basic_code_module.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" -#include "processor/range_map-inl.h" - -namespace { -static const char kGoogleBreakpadKey[] = "google-breakpad"; -static const char kMicrodumpBegin[] = "-----BEGIN BREAKPAD MICRODUMP-----"; -static const char kMicrodumpEnd[] = "-----END BREAKPAD MICRODUMP-----"; -static const char kOsKey[] = ": O "; -static const char kCpuKey[] = ": C "; -static const char kGpuKey[] = ": G "; -static const char kMmapKey[] = ": M "; -static const char kStackKey[] = ": S "; -static const char kStackFirstLineKey[] = ": S 0 "; -static const char kArmArchitecture[] = "arm"; -static const char kArm64Architecture[] = "arm64"; -static const char kX86Architecture[] = "x86"; -static const char kMipsArchitecture[] = "mips"; -static const char kMips64Architecture[] = "mips64"; -static const char kGpuUnknown[] = "UNKNOWN"; - -template -T HexStrToL(const string& str) { - uint64_t res = 0; - std::istringstream ss(str); - ss >> std::hex >> res; - return static_cast(res); -} - -std::vector ParseHexBuf(const string& str) { - std::vector buf; - for (size_t i = 0; i < str.length(); i += 2) { - buf.push_back(HexStrToL(str.substr(i, 2))); - } - return buf; -} - -bool GetLine(std::istringstream* istream, string* str) { - if (std::getline(*istream, *str)) { - // Trim any trailing newline from the end of the line. Allows us - // to seamlessly handle both Windows/DOS and Unix formatted input. The - // adb tool generally writes logcat dumps in Windows/DOS format. - if (!str->empty() && str->at(str->size() - 1) == '\r') { - str->erase(str->size() - 1); - } - return true; - } - return false; -} - -} // namespace - -namespace google_breakpad { - -// -// MicrodumpModules -// - -void MicrodumpModules::Add(const CodeModule* module) { - linked_ptr module_ptr(module); - if (!map_.StoreRange(module->base_address(), module->size(), module_ptr)) { - BPLOG(ERROR) << "Module " << module->code_file() << - " could not be stored"; - } -} - -void MicrodumpModules::SetEnableModuleShrink(bool is_enabled) { - map_.SetEnableShrinkDown(is_enabled); -} - -// -// MicrodumpContext -// - -void MicrodumpContext::SetContextARM(MDRawContextARM* arm) { - DumpContext::SetContextFlags(MD_CONTEXT_ARM); - DumpContext::SetContextARM(arm); - valid_ = true; -} - -void MicrodumpContext::SetContextARM64(MDRawContextARM64* arm64) { - DumpContext::SetContextFlags(MD_CONTEXT_ARM64); - DumpContext::SetContextARM64(arm64); - valid_ = true; -} - -void MicrodumpContext::SetContextX86(MDRawContextX86* x86) { - DumpContext::SetContextFlags(MD_CONTEXT_X86); - DumpContext::SetContextX86(x86); - valid_ = true; -} - -void MicrodumpContext::SetContextMIPS(MDRawContextMIPS* mips32) { - DumpContext::SetContextFlags(MD_CONTEXT_MIPS); - DumpContext::SetContextMIPS(mips32); - valid_ = true; -} - -void MicrodumpContext::SetContextMIPS64(MDRawContextMIPS* mips64) { - DumpContext::SetContextFlags(MD_CONTEXT_MIPS64); - DumpContext::SetContextMIPS(mips64); - valid_ = true; -} - - -// -// MicrodumpMemoryRegion -// - -MicrodumpMemoryRegion::MicrodumpMemoryRegion() : base_address_(0) { } - -void MicrodumpMemoryRegion::Init(uint64_t base_address, - const std::vector& contents) { - base_address_ = base_address; - contents_ = contents; -} - -uint64_t MicrodumpMemoryRegion::GetBase() const { return base_address_; } - -uint32_t MicrodumpMemoryRegion::GetSize() const { return contents_.size(); } - -bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint8_t* value) const { - return GetMemoryLittleEndian(address, value); -} - -bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint16_t* value) const { - return GetMemoryLittleEndian(address, value); -} - -bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint32_t* value) const { - return GetMemoryLittleEndian(address, value); -} - -bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint64_t* value) const { - return GetMemoryLittleEndian(address, value); -} - -template -bool MicrodumpMemoryRegion::GetMemoryLittleEndian(uint64_t address, - ValueType* value) const { - if (address < base_address_ || - address - base_address_ + sizeof(ValueType) > contents_.size()) - return false; - ValueType v = 0; - uint64_t start = address - base_address_; - // The loop condition is odd, but it's correct for size_t. - for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--) - v = (v << 8) | static_cast(contents_[start + i]); - *value = v; - return true; -} - -void MicrodumpMemoryRegion::Print() const { - // Not reached, just needed to honor the base class contract. - assert(false); -} - -// -// Microdump -// -Microdump::Microdump(const string& contents) - : context_(new MicrodumpContext()), - stack_region_(new MicrodumpMemoryRegion()), - modules_(new MicrodumpModules()), - system_info_(new SystemInfo()) { - assert(!contents.empty()); - - bool in_microdump = false; - string line; - uint64_t stack_start = 0; - std::vector stack_content; - string arch; - - std::istringstream stream(contents); - while (GetLine(&stream, &line)) { - if (line.find(kGoogleBreakpadKey) == string::npos) { - continue; - } - if (line.find(kMicrodumpBegin) != string::npos) { - in_microdump = true; - continue; - } - if (!in_microdump) { - continue; - } - if (line.find(kMicrodumpEnd) != string::npos) { - break; - } - - size_t pos; - if ((pos = line.find(kOsKey)) != string::npos) { - string os_str(line, pos + strlen(kOsKey)); - std::istringstream os_tokens(os_str); - string os_id; - string num_cpus; - string os_version; - // This reflect the actual HW arch and might not match the arch emulated - // for the execution (e.g., running a 32-bit binary on a 64-bit cpu). - string hw_arch; - - os_tokens >> os_id; - os_tokens >> arch; - os_tokens >> num_cpus; - os_tokens >> hw_arch; - GetLine(&os_tokens, &os_version); - os_version.erase(0, 1); // remove leading space. - - system_info_->cpu = arch; - system_info_->cpu_count = HexStrToL(num_cpus); - system_info_->os_version = os_version; - - if (os_id == "L") { - system_info_->os = "Linux"; - system_info_->os_short = "linux"; - } else if (os_id == "A") { - system_info_->os = "Android"; - system_info_->os_short = "android"; - modules_->SetEnableModuleShrink(true); - } - - // OS line also contains release and version for future use. - } else if ((pos = line.find(kStackKey)) != string::npos) { - if (line.find(kStackFirstLineKey) != string::npos) { - // The first line of the stack (S 0 stack header) provides the value of - // the stack pointer, the start address of the stack being dumped and - // the length of the stack. We could use it in future to double check - // that we received all the stack as expected. - continue; - } - string stack_str(line, pos + strlen(kStackKey)); - std::istringstream stack_tokens(stack_str); - string start_addr_str; - string raw_content; - stack_tokens >> start_addr_str; - stack_tokens >> raw_content; - uint64_t start_addr = HexStrToL(start_addr_str); - - if (stack_start != 0) { - // Verify that the stack chunks in the microdump are contiguous. - assert(start_addr == stack_start + stack_content.size()); - } else { - stack_start = start_addr; - } - std::vector chunk = ParseHexBuf(raw_content); - stack_content.insert(stack_content.end(), chunk.begin(), chunk.end()); - - } else if ((pos = line.find(kCpuKey)) != string::npos) { - string cpu_state_str(line, pos + strlen(kCpuKey)); - std::vector cpu_state_raw = ParseHexBuf(cpu_state_str); - if (strcmp(arch.c_str(), kArmArchitecture) == 0) { - if (cpu_state_raw.size() != sizeof(MDRawContextARM)) { - std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() - << " bytes instead of " << sizeof(MDRawContextARM) - << std::endl; - continue; - } - MDRawContextARM* arm = new MDRawContextARM(); - memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size()); - context_->SetContextARM(arm); - } else if (strcmp(arch.c_str(), kArm64Architecture) == 0) { - if (cpu_state_raw.size() != sizeof(MDRawContextARM64)) { - std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() - << " bytes instead of " << sizeof(MDRawContextARM64) - << std::endl; - continue; - } - MDRawContextARM64* arm = new MDRawContextARM64(); - memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size()); - context_->SetContextARM64(arm); - } else if (strcmp(arch.c_str(), kX86Architecture) == 0) { - if (cpu_state_raw.size() != sizeof(MDRawContextX86)) { - std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() - << " bytes instead of " << sizeof(MDRawContextX86) - << std::endl; - continue; - } - MDRawContextX86* x86 = new MDRawContextX86(); - memcpy(x86, &cpu_state_raw[0], cpu_state_raw.size()); - context_->SetContextX86(x86); - } else if (strcmp(arch.c_str(), kMipsArchitecture) == 0) { - if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) { - std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() - << " bytes instead of " << sizeof(MDRawContextMIPS) - << std::endl; - continue; - } - MDRawContextMIPS* mips32 = new MDRawContextMIPS(); - memcpy(mips32, &cpu_state_raw[0], cpu_state_raw.size()); - context_->SetContextMIPS(mips32); - } else if (strcmp(arch.c_str(), kMips64Architecture) == 0) { - if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) { - std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() - << " bytes instead of " << sizeof(MDRawContextMIPS) - << std::endl; - continue; - } - MDRawContextMIPS* mips64 = new MDRawContextMIPS(); - memcpy(mips64, &cpu_state_raw[0], cpu_state_raw.size()); - context_->SetContextMIPS64(mips64); - } else { - std::cerr << "Unsupported architecture: " << arch << std::endl; - } - } else if ((pos = line.find(kGpuKey)) != string::npos) { - string gpu_str(line, pos + strlen(kGpuKey)); - if (strcmp(gpu_str.c_str(), kGpuUnknown) != 0) { - std::istringstream gpu_tokens(gpu_str); - std::getline(gpu_tokens, system_info_->gl_version, '|'); - std::getline(gpu_tokens, system_info_->gl_vendor, '|'); - std::getline(gpu_tokens, system_info_->gl_renderer, '|'); - } - } else if ((pos = line.find(kMmapKey)) != string::npos) { - string mmap_line(line, pos + strlen(kMmapKey)); - std::istringstream mmap_tokens(mmap_line); - string addr, offset, size, identifier, filename; - mmap_tokens >> addr; - mmap_tokens >> offset; - mmap_tokens >> size; - mmap_tokens >> identifier; - mmap_tokens >> filename; - - modules_->Add(new BasicCodeModule( - HexStrToL(addr), // base_address - HexStrToL(size), // size - filename, // code_file - identifier, // code_identifier - filename, // debug_file - identifier, // debug_identifier - "")); // version - } - } - stack_region_->Init(stack_start, stack_content); -} - -} // namespace google_breakpad - diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor.cc b/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor.cc deleted file mode 100644 index 366e3f30a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// microdump_processor.cc: A microdump processor. -// -// See microdump_processor.h for documentation. - -#include "google_breakpad/processor/microdump_processor.h" - -#include - -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/microdump.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stackwalker.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "processor/logging.h" - -namespace google_breakpad { - -MicrodumpProcessor::MicrodumpProcessor(StackFrameSymbolizer* frame_symbolizer) - : frame_symbolizer_(frame_symbolizer) { - assert(frame_symbolizer); -} - -MicrodumpProcessor::~MicrodumpProcessor() {} - -ProcessResult MicrodumpProcessor::Process(const string µdump_contents, - ProcessState* process_state) { - assert(process_state); - - process_state->Clear(); - - if (microdump_contents.empty()) { - BPLOG(ERROR) << "Microdump is empty."; - return PROCESS_ERROR_MINIDUMP_NOT_FOUND; - } - - Microdump microdump(microdump_contents); - process_state->modules_ = microdump.GetModules()->Copy(); - scoped_ptr stackwalker( - Stackwalker::StackwalkerForCPU( - &process_state->system_info_, - microdump.GetContext(), - microdump.GetMemory(), - process_state->modules_, - frame_symbolizer_)); - - scoped_ptr stack(new CallStack()); - if (stackwalker.get()) { - if (!stackwalker->Walk(stack.get(), - &process_state->modules_without_symbols_, - &process_state->modules_with_corrupt_symbols_)) { - BPLOG(INFO) << "Processing was interrupted."; - return PROCESS_SYMBOL_SUPPLIER_INTERRUPTED; - } - } else { - BPLOG(ERROR) << "No stackwalker found for microdump."; - return PROCESS_ERROR_NO_THREAD_LIST; - } - - process_state->threads_.push_back(stack.release()); - process_state->thread_memory_regions_.push_back(microdump.GetMemory()); - process_state->crashed_ = true; - process_state->requesting_thread_ = 0; - process_state->system_info_ = *microdump.GetSystemInfo(); - - return PROCESS_OK; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor_unittest.cc deleted file mode 100644 index af897f7da..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_processor_unittest.cc +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) 2014, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unit test for MicrodumpProcessor. - -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/microdump_processor.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "processor/simple_symbol_supplier.h" -#include "processor/stackwalker_unittest_utils.h" - -namespace { - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::MicrodumpProcessor; -using google_breakpad::ProcessState; -using google_breakpad::SimpleSymbolSupplier; -using google_breakpad::StackFrameSymbolizer; - -class MicrodumpProcessorTest : public ::testing::Test { - public: - MicrodumpProcessorTest() - : files_path_(string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/") { - } - - void ReadFile(const string& file_name, string* file_contents) { - assert(file_contents); - std::ifstream file_stream(file_name.c_str(), std::ios::in); - ASSERT_TRUE(file_stream.good()); - std::vector bytes; - file_stream.seekg(0, std::ios_base::end); - ASSERT_TRUE(file_stream.good()); - bytes.resize(file_stream.tellg()); - file_stream.seekg(0, std::ios_base::beg); - ASSERT_TRUE(file_stream.good()); - file_stream.read(&bytes[0], bytes.size()); - ASSERT_TRUE(file_stream.good()); - *file_contents = string(&bytes[0], bytes.size()); - } - - google_breakpad::ProcessResult ProcessMicrodump( - const string& symbols_file, - const string& microdump_contents, - ProcessState* state) { - SimpleSymbolSupplier supplier(symbols_file); - BasicSourceLineResolver resolver; - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - MicrodumpProcessor processor(&frame_symbolizer); - - return processor.Process(microdump_contents, state); - } - - void AnalyzeDump(const string& microdump_file_name, bool omit_symbols, - int expected_cpu_count, ProcessState* state) { - string symbols_file = omit_symbols ? "" : files_path_ + "symbols/microdump"; - string microdump_file_path = files_path_ + microdump_file_name; - string microdump_contents; - ReadFile(microdump_file_path, µdump_contents); - - google_breakpad::ProcessResult result = - ProcessMicrodump(symbols_file, microdump_contents, state); - - ASSERT_EQ(google_breakpad::PROCESS_OK, result); - ASSERT_TRUE(state->crashed()); - ASSERT_EQ(0, state->requesting_thread()); - ASSERT_EQ(1U, state->threads()->size()); - - ASSERT_EQ(expected_cpu_count, state->system_info()->cpu_count); - ASSERT_EQ("android", state->system_info()->os_short); - ASSERT_EQ("Android", state->system_info()->os); - } - - string files_path_; -}; - -TEST_F(MicrodumpProcessorTest, TestProcess_Empty) { - ProcessState state; - google_breakpad::ProcessResult result = - ProcessMicrodump("", "", &state); - ASSERT_EQ(google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND, result); -} - -TEST_F(MicrodumpProcessorTest, TestProcess_Invalid) { - ProcessState state; - google_breakpad::ProcessResult result = - ProcessMicrodump("", "This is not a valid microdump", &state); - ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result); -} - -TEST_F(MicrodumpProcessorTest, TestProcess_MissingSymbols) { - ProcessState state; - AnalyzeDump("microdump-arm64.dmp", true /* omit_symbols */, - 2 /* expected_cpu_count */, &state); - - ASSERT_EQ(8U, state.modules()->module_count()); - ASSERT_EQ("arm64", state.system_info()->cpu); - ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version); - ASSERT_EQ(1U, state.threads()->size()); - ASSERT_EQ(12U, state.threads()->at(0)->frames()->size()); - - ASSERT_EQ("", - state.threads()->at(0)->frames()->at(0)->function_name); - ASSERT_EQ("", - state.threads()->at(0)->frames()->at(3)->function_name); -} - -TEST_F(MicrodumpProcessorTest, TestProcess_UnsupportedArch) { - string microdump_contents = - "W/google-breakpad(26491): -----BEGIN BREAKPAD MICRODUMP-----\n" - "W/google-breakpad(26491): O A \"unsupported-arch\"\n" - "W/google-breakpad(26491): S 0 A48BD840 A48BD000 00002000\n"; - - ProcessState state; - - google_breakpad::ProcessResult result = - ProcessMicrodump("", microdump_contents, &state); - - ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result); -} - -TEST_F(MicrodumpProcessorTest, TestProcessArm) { - ProcessState state; - AnalyzeDump("microdump-arm.dmp", false /* omit_symbols */, - 2 /* expected_cpu_count*/, &state); - - ASSERT_EQ(6U, state.modules()->module_count()); - ASSERT_EQ("arm", state.system_info()->cpu); - ASSERT_EQ("OpenGL ES 3.0 V@104.0 AU@ (GIT@Id3510ff6dc)", - state.system_info()->gl_version); - ASSERT_EQ("Qualcomm", state.system_info()->gl_vendor); - ASSERT_EQ("Adreno (TM) 330", state.system_info()->gl_renderer); - ASSERT_EQ("OS VERSION INFO", state.system_info()->os_version); - ASSERT_EQ(8U, state.threads()->at(0)->frames()->size()); - ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody", - state.threads()->at(0)->frames()->at(0)->function_name); - ASSERT_EQ("testing::Test::Run", - state.threads()->at(0)->frames()->at(1)->function_name); - ASSERT_EQ("main", - state.threads()->at(0)->frames()->at(6)->function_name); - ASSERT_EQ("breakpad_unittests", - state.threads()->at(0)->frames()->at(6)->module->code_file()); -} - -TEST_F(MicrodumpProcessorTest, TestProcessArm64) { - ProcessState state; - AnalyzeDump("microdump-arm64.dmp", false /* omit_symbols */, - 2 /* expected_cpu_count*/, &state); - - ASSERT_EQ(8U, state.modules()->module_count()); - ASSERT_EQ("arm64", state.system_info()->cpu); - ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version); - ASSERT_EQ(9U, state.threads()->at(0)->frames()->size()); - ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody", - state.threads()->at(0)->frames()->at(0)->function_name); - ASSERT_EQ("testing::Test::Run", - state.threads()->at(0)->frames()->at(2)->function_name); - ASSERT_EQ("main", - state.threads()->at(0)->frames()->at(7)->function_name); - ASSERT_EQ("breakpad_unittests", - state.threads()->at(0)->frames()->at(7)->module->code_file()); -} - -TEST_F(MicrodumpProcessorTest, TestProcessX86) { - ProcessState state; - AnalyzeDump("microdump-x86.dmp", false /* omit_symbols */, - 4 /* expected_cpu_count */, &state); - - ASSERT_EQ(124U, state.modules()->module_count()); - ASSERT_EQ("x86", state.system_info()->cpu); - ASSERT_EQ("asus/WW_Z00A/Z00A:5.0/LRX21V/2.19.40.22_20150627_5104_user:user/" - "release-keys", state.system_info()->os_version); - ASSERT_EQ(56U, state.threads()->at(0)->frames()->size()); - ASSERT_EQ("libc.so", - state.threads()->at(0)->frames()->at(0)->module->debug_file()); - // TODO(mmandlis): Get symbols for the test X86 microdump and test function - // names. -} - -TEST_F(MicrodumpProcessorTest, TestProcessMultiple) { - ProcessState state; - AnalyzeDump("microdump-multiple.dmp", false /* omit_symbols */, - 6 /* expected_cpu_count */, &state); - ASSERT_EQ(156U, state.modules()->module_count()); - ASSERT_EQ("arm", state.system_info()->cpu); - ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys", - state.system_info()->os_version); - ASSERT_EQ(5U, state.threads()->at(0)->frames()->size()); -} - -TEST_F(MicrodumpProcessorTest, TestProcessMips) { - ProcessState state; - AnalyzeDump("microdump-mips32.dmp", false /* omit_symbols */, - 2 /* expected_cpu_count */, &state); - - ASSERT_EQ(7U, state.modules()->module_count()); - ASSERT_EQ("mips", state.system_info()->cpu); - ASSERT_EQ("3.0.8-g893bf16 #7 SMP PREEMPT Fri Jul 10 15:20:59 PDT 2015", - state.system_info()->os_version); - ASSERT_EQ(4U, state.threads()->at(0)->frames()->size()); - - ASSERT_EQ("blaTest", - state.threads()->at(0)->frames()->at(0)->function_name); - ASSERT_EQ("Crash", - state.threads()->at(0)->frames()->at(1)->function_name); - ASSERT_EQ("main", - state.threads()->at(0)->frames()->at(2)->function_name); - ASSERT_EQ("crash_example", - state.threads()->at(0)->frames()->at(0)->module->debug_file()); -} - -TEST_F(MicrodumpProcessorTest, TestProcessMips64) { - ProcessState state; - AnalyzeDump("microdump-mips64.dmp", false /* omit_symbols */, - 1 /* expected_cpu_count */, &state); - - ASSERT_EQ(8U, state.modules()->module_count()); - ASSERT_EQ("mips64", state.system_info()->cpu); - ASSERT_EQ("3.10.0-gf185e20 #112 PREEMPT Mon Oct 5 11:12:49 PDT 2015", - state.system_info()->os_version); - ASSERT_EQ(4U, state.threads()->at(0)->frames()->size()); - - ASSERT_EQ("blaTest", - state.threads()->at(0)->frames()->at(0)->function_name); - ASSERT_EQ("Crash", - state.threads()->at(0)->frames()->at(1)->function_name); - ASSERT_EQ("main", - state.threads()->at(0)->frames()->at(2)->function_name); - ASSERT_EQ("crash_example", - state.threads()->at(0)->frames()->at(0)->module->debug_file()); -} - -} // namespace - -int main(int argc, char* argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk.cc b/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk.cc deleted file mode 100644 index 7ea80495a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk.cc +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2014 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// microdump_stackwalk.cc: Process a microdump with MicrodumpProcessor, printing -// the results, including stack traces. - -#include -#include - -#include -#include -#include - -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/microdump_processor.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "processor/logging.h" -#include "processor/simple_symbol_supplier.h" -#include "processor/stackwalk_common.h" - - -namespace { - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::MicrodumpProcessor; -using google_breakpad::ProcessResult; -using google_breakpad::ProcessState; -using google_breakpad::scoped_ptr; -using google_breakpad::SimpleSymbolSupplier; -using google_breakpad::StackFrameSymbolizer; - -// Processes |microdump_file| using MicrodumpProcessor. |symbol_path|, if -// non-empty, is the base directory of a symbol storage area, laid out in -// the format required by SimpleSymbolSupplier. If such a storage area -// is specified, it is made available for use by the MicrodumpProcessor. -// -// Returns the value of MicrodumpProcessor::Process. If processing succeeds, -// prints identifying OS and CPU information from the microdump, crash -// information and call stacks for the crashing thread. -// All information is printed to stdout. -int PrintMicrodumpProcess(const char* microdump_file, - const std::vector& symbol_paths, - bool machine_readable) { - std::ifstream file_stream(microdump_file); - std::vector bytes; - file_stream.seekg(0, std::ios_base::end); - bytes.resize(file_stream.tellg()); - file_stream.seekg(0, std::ios_base::beg); - file_stream.read(&bytes[0], bytes.size()); - string microdump_content(&bytes[0], bytes.size()); - - scoped_ptr symbol_supplier; - if (!symbol_paths.empty()) { - symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths)); - } - - BasicSourceLineResolver resolver; - StackFrameSymbolizer frame_symbolizer(symbol_supplier.get(), &resolver); - ProcessState process_state; - MicrodumpProcessor microdump_processor(&frame_symbolizer); - ProcessResult res = microdump_processor.Process(microdump_content, - &process_state); - - if (res == google_breakpad::PROCESS_OK) { - if (machine_readable) { - PrintProcessStateMachineReadable(process_state); - } else { - PrintProcessState(process_state, false, &resolver); - } - return 0; - } - - BPLOG(ERROR) << "MicrodumpProcessor::Process failed (code = " << res << ")"; - return 1; -} - -void usage(const char *program_name) { - fprintf(stderr, "usage: %s [-m] [symbol-path ...]\n" - " -m : Output in machine-readable format\n", - program_name); -} - -} // namespace - -int main(int argc, char** argv) { - BPLOG_INIT(&argc, &argv); - - if (argc < 2) { - usage(argv[0]); - return 1; - } - - const char* microdump_file; - bool machine_readable; - int symbol_path_arg; - - if (strcmp(argv[1], "-m") == 0) { - if (argc < 3) { - usage(argv[0]); - return 1; - } - - machine_readable = true; - microdump_file = argv[2]; - symbol_path_arg = 3; - } else { - machine_readable = false; - microdump_file = argv[1]; - symbol_path_arg = 2; - } - - // extra arguments are symbol paths - std::vector symbol_paths; - if (argc > symbol_path_arg) { - for (int argi = symbol_path_arg; argi < argc; ++argi) - symbol_paths.push_back(argv[argi]); - } - - return PrintMicrodumpProcess(microdump_file, - symbol_paths, - machine_readable); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_machine_readable_test b/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_machine_readable_test deleted file mode 100755 index fadec2645..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_machine_readable_test +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2014, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -source "${0%/*}/microdump_stackwalk_test_vars" # for MICRODUMP_SUPPORTED_ARCHS. -testdata_dir=$srcdir/src/processor/testdata - -set -e # Bail out with an error if any of the commands below fails. -for ARCH in $MICRODUMP_SUPPORTED_ARCHS; do - echo "Testing microdump_stackwalk -m for arch $ARCH" - ./src/processor/microdump_stackwalk -m $testdata_dir/microdump-${ARCH}.dmp \ - $testdata_dir/symbols/microdump | \ - tr -d '\015' | \ - diff -u $testdata_dir/microdump.stackwalk.machine_readable-${ARCH}.out - -done -exit 0 diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test b/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test deleted file mode 100755 index 5a1f3d59f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2014, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -source "${0%/*}/microdump_stackwalk_test_vars" # for MICRODUMP_SUPPORTED_ARCHS. -testdata_dir=$srcdir/src/processor/testdata - -set -e # Bail out with an error if any of the commands below fails. -for ARCH in $MICRODUMP_SUPPORTED_ARCHS; do - echo "Testing microdump_stackwalk for arch $ARCH" - ./src/processor/microdump_stackwalk $testdata_dir/microdump-${ARCH}.dmp \ - $testdata_dir/symbols/microdump | \ - tr -d '\015' | \ - diff -u $testdata_dir/microdump.stackwalk-${ARCH}.out - -done -exit 0 diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test_vars b/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test_vars deleted file mode 100644 index a8b0e0df5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test_vars +++ /dev/null @@ -1 +0,0 @@ -MICRODUMP_SUPPORTED_ARCHS="arm arm64" diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump.cc deleted file mode 100644 index 1e1d386df..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump.cc +++ /dev/null @@ -1,4989 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump.cc: A minidump reader. -// -// See minidump.h for documentation. -// -// Author: Mark Mentovai - -#include "google_breakpad/processor/minidump.h" - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#else // _WIN32 -#include -#endif // _WIN32 - -#include -#include -#include -#include -#include -#include - -#include "processor/range_map-inl.h" - -#include "common/scoped_ptr.h" -#include "common/stdio_wrapper.h" -#include "google_breakpad/processor/dump_context.h" -#include "processor/basic_code_module.h" -#include "processor/basic_code_modules.h" -#include "processor/logging.h" - -namespace google_breakpad { - - -using std::istream; -using std::ifstream; -using std::numeric_limits; -using std::vector; - -// Returns true iff |context_size| matches exactly one of the sizes of the -// various MDRawContext* types. -// TODO(blundell): This function can be removed once -// http://code.google.com/p/google-breakpad/issues/detail?id=550 is fixed. -static bool IsContextSizeUnique(uint32_t context_size) { - int num_matching_contexts = 0; - if (context_size == sizeof(MDRawContextX86)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextPPC)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextPPC64)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextAMD64)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextSPARC)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextARM)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextARM64)) - num_matching_contexts++; - if (context_size == sizeof(MDRawContextMIPS)) - num_matching_contexts++; - return num_matching_contexts == 1; -} - -// -// Swapping routines -// -// Inlining these doesn't increase code size significantly, and it saves -// a whole lot of unnecessary jumping back and forth. -// - - -// Swapping an 8-bit quantity is a no-op. This function is only provided -// to account for certain templatized operations that require swapping for -// wider types but handle uint8_t too -// (MinidumpMemoryRegion::GetMemoryAtAddressInternal). -static inline void Swap(uint8_t* value) { -} - - -// Optimization: don't need to AND the furthest right shift, because we're -// shifting an unsigned quantity. The standard requires zero-filling in this -// case. If the quantities were signed, a bitmask whould be needed for this -// right shift to avoid an arithmetic shift (which retains the sign bit). -// The furthest left shift never needs to be ANDed bitmask. - - -static inline void Swap(uint16_t* value) { - *value = (*value >> 8) | - (*value << 8); -} - - -static inline void Swap(uint32_t* value) { - *value = (*value >> 24) | - ((*value >> 8) & 0x0000ff00) | - ((*value << 8) & 0x00ff0000) | - (*value << 24); -} - - -static inline void Swap(uint64_t* value) { - uint32_t* value32 = reinterpret_cast(value); - Swap(&value32[0]); - Swap(&value32[1]); - uint32_t temp = value32[0]; - value32[0] = value32[1]; - value32[1] = temp; -} - - -// Given a pointer to a 128-bit int in the minidump data, set the "low" -// and "high" fields appropriately. -static void Normalize128(uint128_struct* value, bool is_big_endian) { - // The struct format is [high, low], so if the format is big-endian, - // the most significant bytes will already be in the high field. - if (!is_big_endian) { - uint64_t temp = value->low; - value->low = value->high; - value->high = temp; - } -} - -// This just swaps each int64 half of the 128-bit value. -// The value should also be normalized by calling Normalize128(). -static void Swap(uint128_struct* value) { - Swap(&value->low); - Swap(&value->high); -} - -// Swapping signed integers -static inline void Swap(int32_t* value) { - Swap(reinterpret_cast(value)); -} - -static inline void Swap(MDLocationDescriptor* location_descriptor) { - Swap(&location_descriptor->data_size); - Swap(&location_descriptor->rva); -} - - -static inline void Swap(MDMemoryDescriptor* memory_descriptor) { - Swap(&memory_descriptor->start_of_memory_range); - Swap(&memory_descriptor->memory); -} - - -static inline void Swap(MDGUID* guid) { - Swap(&guid->data1); - Swap(&guid->data2); - Swap(&guid->data3); - // Don't swap guid->data4[] because it contains 8-bit quantities. -} - -static inline void Swap(MDSystemTime* system_time) { - Swap(&system_time->year); - Swap(&system_time->month); - Swap(&system_time->day_of_week); - Swap(&system_time->day); - Swap(&system_time->hour); - Swap(&system_time->minute); - Swap(&system_time->second); - Swap(&system_time->milliseconds); -} - -static inline void Swap(MDXStateFeature* xstate_feature) { - Swap(&xstate_feature->offset); - Swap(&xstate_feature->size); -} - -static inline void Swap(MDXStateConfigFeatureMscInfo* xstate_feature_info) { - Swap(&xstate_feature_info->size_of_info); - Swap(&xstate_feature_info->context_size); - Swap(&xstate_feature_info->enabled_features); - - for (size_t i = 0; i < MD_MAXIMUM_XSTATE_FEATURES; i++) { - Swap(&xstate_feature_info->features[i]); - } -} - -static inline void Swap(uint16_t* data, size_t size_in_bytes) { - size_t data_length = size_in_bytes / sizeof(data[0]); - for (size_t i = 0; i < data_length; i++) { - Swap(&data[i]); - } -} - -// -// Character conversion routines -// - - -// Standard wide-character conversion routines depend on the system's own -// idea of what width a wide character should be: some use 16 bits, and -// some use 32 bits. For the purposes of a minidump, wide strings are -// always represented with 16-bit UTF-16 chracters. iconv isn't available -// everywhere, and its interface varies where it is available. iconv also -// deals purely with char* pointers, so in addition to considering the swap -// parameter, a converter that uses iconv would also need to take the host -// CPU's endianness into consideration. It doesn't seems worth the trouble -// of making it a dependency when we don't care about anything but UTF-16. -static string* UTF16ToUTF8(const vector& in, - bool swap) { - scoped_ptr out(new string()); - - // Set the string's initial capacity to the number of UTF-16 characters, - // because the UTF-8 representation will always be at least this long. - // If the UTF-8 representation is longer, the string will grow dynamically. - out->reserve(in.size()); - - for (vector::const_iterator iterator = in.begin(); - iterator != in.end(); - ++iterator) { - // Get a 16-bit value from the input - uint16_t in_word = *iterator; - if (swap) - Swap(&in_word); - - // Convert the input value (in_word) into a Unicode code point (unichar). - uint32_t unichar; - if (in_word >= 0xdc00 && in_word <= 0xdcff) { - BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << - HexString(in_word) << " without high"; - return NULL; - } else if (in_word >= 0xd800 && in_word <= 0xdbff) { - // High surrogate. - unichar = (in_word - 0xd7c0) << 10; - if (++iterator == in.end()) { - BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << - HexString(in_word) << " at end of string"; - return NULL; - } - uint32_t high_word = in_word; - in_word = *iterator; - if (in_word < 0xdc00 || in_word > 0xdcff) { - BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << - HexString(high_word) << " without low " << - HexString(in_word); - return NULL; - } - unichar |= in_word & 0x03ff; - } else { - // The ordinary case, a single non-surrogate Unicode character encoded - // as a single 16-bit value. - unichar = in_word; - } - - // Convert the Unicode code point (unichar) into its UTF-8 representation, - // appending it to the out string. - if (unichar < 0x80) { - (*out) += static_cast(unichar); - } else if (unichar < 0x800) { - (*out) += 0xc0 | static_cast(unichar >> 6); - (*out) += 0x80 | static_cast(unichar & 0x3f); - } else if (unichar < 0x10000) { - (*out) += 0xe0 | static_cast(unichar >> 12); - (*out) += 0x80 | static_cast((unichar >> 6) & 0x3f); - (*out) += 0x80 | static_cast(unichar & 0x3f); - } else if (unichar < 0x200000) { - (*out) += 0xf0 | static_cast(unichar >> 18); - (*out) += 0x80 | static_cast((unichar >> 12) & 0x3f); - (*out) += 0x80 | static_cast((unichar >> 6) & 0x3f); - (*out) += 0x80 | static_cast(unichar & 0x3f); - } else { - BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << - HexString(unichar) << " in UTF-8"; - return NULL; - } - } - - return out.release(); -} - -// Return the smaller of the number of code units in the UTF-16 string, -// not including the terminating null word, or maxlen. -static size_t UTF16codeunits(const uint16_t *string, size_t maxlen) { - size_t count = 0; - while (count < maxlen && string[count] != 0) - count++; - return count; -} - -static inline void Swap(MDTimeZoneInformation* time_zone) { - Swap(&time_zone->bias); - // Skip time_zone->standard_name. No need to swap UTF-16 fields. - // The swap will be done as part of the conversion to UTF-8. - Swap(&time_zone->standard_date); - Swap(&time_zone->standard_bias); - // Skip time_zone->daylight_name. No need to swap UTF-16 fields. - // The swap will be done as part of the conversion to UTF-8. - Swap(&time_zone->daylight_date); - Swap(&time_zone->daylight_bias); -} - -static void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data, - size_t max_length_in_bytes, - string* utf8_result, - bool swap) { - // Since there is no explicit byte length for each string, use - // UTF16codeunits to calculate word length, then derive byte - // length from that. - size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]); - size_t word_length = UTF16codeunits(utf16_data, max_word_length); - if (word_length > 0) { - size_t byte_length = word_length * sizeof(utf16_data[0]); - vector utf16_vector(word_length); - memcpy(&utf16_vector[0], &utf16_data[0], byte_length); - scoped_ptr temp(UTF16ToUTF8(utf16_vector, swap)); - if (temp.get()) { - utf8_result->assign(*temp); - } - } else { - utf8_result->clear(); - } -} - - -// For fields that may or may not be valid, PrintValueOrInvalid will print the -// string "(invalid)" if the field is not valid, and will print the value if -// the field is valid. The value is printed as hexadecimal or decimal. - -enum NumberFormat { - kNumberFormatDecimal, - kNumberFormatHexadecimal, -}; - -static void PrintValueOrInvalid(bool valid, - NumberFormat number_format, - uint32_t value) { - if (!valid) { - printf("(invalid)\n"); - } else if (number_format == kNumberFormatDecimal) { - printf("%d\n", value); - } else { - printf("0x%x\n", value); - } -} - -// Converts a time_t to a string showing the time in UTC. -string TimeTToUTCString(time_t tt) { - struct tm timestruct; -#ifdef _WIN32 - gmtime_s(×truct, &tt); -#else - gmtime_r(&tt, ×truct); -#endif - - char timestr[20]; - int rv = strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); - if (rv == 0) { - return string(); - } - - return string(timestr); -} - - -// -// MinidumpObject -// - - -MinidumpObject::MinidumpObject(Minidump* minidump) - : DumpObject(), - minidump_(minidump) { -} - - -// -// MinidumpStream -// - - -MinidumpStream::MinidumpStream(Minidump* minidump) - : MinidumpObject(minidump) { -} - - -// -// MinidumpContext -// - - -MinidumpContext::MinidumpContext(Minidump* minidump) - : DumpContext(), - minidump_(minidump) { -} - -MinidumpContext::~MinidumpContext() { -} - -bool MinidumpContext::Read(uint32_t expected_size) { - valid_ = false; - - // Certain raw context types are currently assumed to have unique sizes. - if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { - BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " - << "other raw context"; - return false; - } - if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) { - BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any " - << "other raw context"; - return false; - } - if (!IsContextSizeUnique(sizeof(MDRawContextARM64))) { - BPLOG(ERROR) << "sizeof(MDRawContextARM64) cannot match the size of any " - << "other raw context"; - return false; - } - - FreeContext(); - - // First, figure out what type of CPU this context structure is for. - // For some reason, the AMD64 Context doesn't have context_flags - // at the beginning of the structure, so special case it here. - if (expected_size == sizeof(MDRawContextAMD64)) { - BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; - - scoped_ptr context_amd64(new MDRawContextAMD64()); - if (!minidump_->ReadBytes(context_amd64.get(), - sizeof(MDRawContextAMD64))) { - BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; - return false; - } - - if (minidump_->swap()) - Swap(&context_amd64->context_flags); - - uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; - if (cpu_type == 0) { - if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { - context_amd64->context_flags |= cpu_type; - } else { - BPLOG(ERROR) << "Failed to preserve the current stream position"; - return false; - } - } - - if (cpu_type != MD_CONTEXT_AMD64) { - // TODO: Fall through to switch below. - // http://code.google.com/p/google-breakpad/issues/detail?id=550 - BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; - return false; - } - - // Normalize the 128-bit types in the dump. - // Since this is AMD64, by definition, the values are little-endian. - for (unsigned int vr_index = 0; - vr_index < MD_CONTEXT_AMD64_VR_COUNT; - ++vr_index) - Normalize128(&context_amd64->vector_register[vr_index], false); - - if (minidump_->swap()) { - Swap(&context_amd64->p1_home); - Swap(&context_amd64->p2_home); - Swap(&context_amd64->p3_home); - Swap(&context_amd64->p4_home); - Swap(&context_amd64->p5_home); - Swap(&context_amd64->p6_home); - // context_flags is already swapped - Swap(&context_amd64->mx_csr); - Swap(&context_amd64->cs); - Swap(&context_amd64->ds); - Swap(&context_amd64->es); - Swap(&context_amd64->fs); - Swap(&context_amd64->ss); - Swap(&context_amd64->eflags); - Swap(&context_amd64->dr0); - Swap(&context_amd64->dr1); - Swap(&context_amd64->dr2); - Swap(&context_amd64->dr3); - Swap(&context_amd64->dr6); - Swap(&context_amd64->dr7); - Swap(&context_amd64->rax); - Swap(&context_amd64->rcx); - Swap(&context_amd64->rdx); - Swap(&context_amd64->rbx); - Swap(&context_amd64->rsp); - Swap(&context_amd64->rbp); - Swap(&context_amd64->rsi); - Swap(&context_amd64->rdi); - Swap(&context_amd64->r8); - Swap(&context_amd64->r9); - Swap(&context_amd64->r10); - Swap(&context_amd64->r11); - Swap(&context_amd64->r12); - Swap(&context_amd64->r13); - Swap(&context_amd64->r14); - Swap(&context_amd64->r15); - Swap(&context_amd64->rip); - // FIXME: I'm not sure what actually determines - // which member of the union {flt_save, sse_registers} - // is valid. We're not currently using either, - // but it would be good to have them swapped properly. - - for (unsigned int vr_index = 0; - vr_index < MD_CONTEXT_AMD64_VR_COUNT; - ++vr_index) - Swap(&context_amd64->vector_register[vr_index]); - Swap(&context_amd64->vector_control); - Swap(&context_amd64->debug_control); - Swap(&context_amd64->last_branch_to_rip); - Swap(&context_amd64->last_branch_from_rip); - Swap(&context_amd64->last_exception_to_rip); - Swap(&context_amd64->last_exception_from_rip); - } - - SetContextFlags(context_amd64->context_flags); - - SetContextAMD64(context_amd64.release()); - } else if (expected_size == sizeof(MDRawContextPPC64)) { - // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext - // in the else case have 32 bits |context_flags|, so special case it here. - uint64_t context_flags; - if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { - BPLOG(ERROR) << "MinidumpContext could not read context flags"; - return false; - } - if (minidump_->swap()) - Swap(&context_flags); - - uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; - scoped_ptr context_ppc64(new MDRawContextPPC64()); - - if (cpu_type == 0) { - if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { - context_ppc64->context_flags |= cpu_type; - } else { - BPLOG(ERROR) << "Failed to preserve the current stream position"; - return false; - } - } - - if (cpu_type != MD_CONTEXT_PPC64) { - // TODO: Fall through to switch below. - // http://code.google.com/p/google-breakpad/issues/detail?id=550 - BPLOG(ERROR) << "MinidumpContext not actually ppc64 context"; - return false; - } - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_ppc64->context_flags = context_flags; - - size_t flags_size = sizeof(context_ppc64->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_ppc64.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextPPC64) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read ppc64 context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info"; - return false; - } - if (minidump_->swap()) { - // context_ppc64->context_flags was already swapped. - Swap(&context_ppc64->srr0); - Swap(&context_ppc64->srr1); - for (unsigned int gpr_index = 0; - gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; - ++gpr_index) { - Swap(&context_ppc64->gpr[gpr_index]); - } - Swap(&context_ppc64->cr); - Swap(&context_ppc64->xer); - Swap(&context_ppc64->lr); - Swap(&context_ppc64->ctr); - Swap(&context_ppc64->vrsave); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; - ++fpr_index) { - Swap(&context_ppc64->float_save.fpregs[fpr_index]); - } - // Don't swap context_ppc64->float_save.fpscr_pad because it is only - // used for padding. - Swap(&context_ppc64->float_save.fpscr); - for (unsigned int vr_index = 0; - vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; - ++vr_index) { - Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); - Swap(&context_ppc64->vector_save.save_vr[vr_index]); - } - Swap(&context_ppc64->vector_save.save_vscr); - // Don't swap the padding fields in vector_save. - Swap(&context_ppc64->vector_save.save_vrvalid); - } - - SetContextFlags(static_cast(context_ppc64->context_flags)); - - // Check for data loss when converting context flags from uint64_t into - // uint32_t - if (static_cast(GetContextFlags()) != - context_ppc64->context_flags) { - BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; - return false; - } - - SetContextPPC64(context_ppc64.release()); - } else if (expected_size == sizeof(MDRawContextARM64)) { - // |context_flags| of MDRawContextARM64 is 64 bits, but other MDRawContext - // in the else case have 32 bits |context_flags|, so special case it here. - uint64_t context_flags; - - BPLOG(INFO) << "MinidumpContext: looks like ARM64 context"; - - if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { - BPLOG(ERROR) << "MinidumpContext could not read context flags"; - return false; - } - if (minidump_->swap()) - Swap(&context_flags); - - scoped_ptr context_arm64(new MDRawContextARM64()); - - uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; - if (cpu_type == 0) { - if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { - context_arm64->context_flags |= cpu_type; - } else { - BPLOG(ERROR) << "Failed to preserve the current stream position"; - return false; - } - } - - if (cpu_type != MD_CONTEXT_ARM64) { - // TODO: Fall through to switch below. - // http://code.google.com/p/google-breakpad/issues/detail?id=550 - BPLOG(ERROR) << "MinidumpContext not actually arm64 context"; - return false; - } - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_arm64->context_flags = context_flags; - - size_t flags_size = sizeof(context_arm64->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_arm64.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextARM64) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read arm64 context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext arm64 does not match system info"; - return false; - } - - if (minidump_->swap()) { - // context_arm64->context_flags was already swapped. - for (unsigned int ireg_index = 0; - ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; - ++ireg_index) { - Swap(&context_arm64->iregs[ireg_index]); - } - Swap(&context_arm64->cpsr); - Swap(&context_arm64->float_save.fpsr); - Swap(&context_arm64->float_save.fpcr); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; - ++fpr_index) { - // While ARM64 is bi-endian, iOS (currently the only platform - // for which ARM64 support has been brought up) uses ARM64 exclusively - // in little-endian mode. - Normalize128(&context_arm64->float_save.regs[fpr_index], false); - Swap(&context_arm64->float_save.regs[fpr_index]); - } - } - SetContextFlags(static_cast(context_arm64->context_flags)); - - // Check for data loss when converting context flags from uint64_t into - // uint32_t - if (static_cast(GetContextFlags()) != - context_arm64->context_flags) { - BPLOG(ERROR) << "Data loss detected when converting ARM64 context_flags"; - return false; - } - - SetContextARM64(context_arm64.release()); - } else { - uint32_t context_flags; - if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { - BPLOG(ERROR) << "MinidumpContext could not read context flags"; - return false; - } - if (minidump_->swap()) - Swap(&context_flags); - - uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; - if (cpu_type == 0) { - // Unfortunately the flag for MD_CONTEXT_ARM that was taken - // from a Windows CE SDK header conflicts in practice with - // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, - // but handle dumps with the legacy value gracefully here. - if (context_flags & MD_CONTEXT_ARM_OLD) { - context_flags |= MD_CONTEXT_ARM; - context_flags &= ~MD_CONTEXT_ARM_OLD; - cpu_type = MD_CONTEXT_ARM; - } - } - - if (cpu_type == 0) { - if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { - context_flags |= cpu_type; - } else { - BPLOG(ERROR) << "Failed to preserve the current stream position"; - return false; - } - } - - // Allocate the context structure for the correct CPU and fill it. The - // casts are slightly unorthodox, but it seems better to do that than to - // maintain a separate pointer for each type of CPU context structure - // when only one of them will be used. - switch (cpu_type) { - case MD_CONTEXT_X86: { - if (expected_size != sizeof(MDRawContextX86)) { - BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << - expected_size << " != " << sizeof(MDRawContextX86); - return false; - } - - scoped_ptr context_x86(new MDRawContextX86()); - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_x86->context_flags = context_flags; - - size_t flags_size = sizeof(context_x86->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_x86.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextX86) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read x86 context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext x86 does not match system info"; - return false; - } - - if (minidump_->swap()) { - // context_x86->context_flags was already swapped. - Swap(&context_x86->dr0); - Swap(&context_x86->dr1); - Swap(&context_x86->dr2); - Swap(&context_x86->dr3); - Swap(&context_x86->dr6); - Swap(&context_x86->dr7); - Swap(&context_x86->float_save.control_word); - Swap(&context_x86->float_save.status_word); - Swap(&context_x86->float_save.tag_word); - Swap(&context_x86->float_save.error_offset); - Swap(&context_x86->float_save.error_selector); - Swap(&context_x86->float_save.data_offset); - Swap(&context_x86->float_save.data_selector); - // context_x86->float_save.register_area[] contains 8-bit quantities - // and does not need to be swapped. - Swap(&context_x86->float_save.cr0_npx_state); - Swap(&context_x86->gs); - Swap(&context_x86->fs); - Swap(&context_x86->es); - Swap(&context_x86->ds); - Swap(&context_x86->edi); - Swap(&context_x86->esi); - Swap(&context_x86->ebx); - Swap(&context_x86->edx); - Swap(&context_x86->ecx); - Swap(&context_x86->eax); - Swap(&context_x86->ebp); - Swap(&context_x86->eip); - Swap(&context_x86->cs); - Swap(&context_x86->eflags); - Swap(&context_x86->esp); - Swap(&context_x86->ss); - // context_x86->extended_registers[] contains 8-bit quantities and - // does not need to be swapped. - } - - SetContextX86(context_x86.release()); - - break; - } - - case MD_CONTEXT_PPC: { - if (expected_size != sizeof(MDRawContextPPC)) { - BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << - expected_size << " != " << sizeof(MDRawContextPPC); - return false; - } - - scoped_ptr context_ppc(new MDRawContextPPC()); - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_ppc->context_flags = context_flags; - - size_t flags_size = sizeof(context_ppc->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_ppc.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextPPC) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read ppc context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext ppc does not match system info"; - return false; - } - - // Normalize the 128-bit types in the dump. - // Since this is PowerPC, by definition, the values are big-endian. - for (unsigned int vr_index = 0; - vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; - ++vr_index) { - Normalize128(&context_ppc->vector_save.save_vr[vr_index], true); - } - - if (minidump_->swap()) { - // context_ppc->context_flags was already swapped. - Swap(&context_ppc->srr0); - Swap(&context_ppc->srr1); - for (unsigned int gpr_index = 0; - gpr_index < MD_CONTEXT_PPC_GPR_COUNT; - ++gpr_index) { - Swap(&context_ppc->gpr[gpr_index]); - } - Swap(&context_ppc->cr); - Swap(&context_ppc->xer); - Swap(&context_ppc->lr); - Swap(&context_ppc->ctr); - Swap(&context_ppc->mq); - Swap(&context_ppc->vrsave); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; - ++fpr_index) { - Swap(&context_ppc->float_save.fpregs[fpr_index]); - } - // Don't swap context_ppc->float_save.fpscr_pad because it is only - // used for padding. - Swap(&context_ppc->float_save.fpscr); - for (unsigned int vr_index = 0; - vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; - ++vr_index) { - Swap(&context_ppc->vector_save.save_vr[vr_index]); - } - Swap(&context_ppc->vector_save.save_vscr); - // Don't swap the padding fields in vector_save. - Swap(&context_ppc->vector_save.save_vrvalid); - } - - SetContextPPC(context_ppc.release()); - - break; - } - - case MD_CONTEXT_SPARC: { - if (expected_size != sizeof(MDRawContextSPARC)) { - BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << - expected_size << " != " << sizeof(MDRawContextSPARC); - return false; - } - - scoped_ptr context_sparc(new MDRawContextSPARC()); - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_sparc->context_flags = context_flags; - - size_t flags_size = sizeof(context_sparc->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_sparc.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextSPARC) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read sparc context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext sparc does not match system info"; - return false; - } - - if (minidump_->swap()) { - // context_sparc->context_flags was already swapped. - for (unsigned int gpr_index = 0; - gpr_index < MD_CONTEXT_SPARC_GPR_COUNT; - ++gpr_index) { - Swap(&context_sparc->g_r[gpr_index]); - } - Swap(&context_sparc->ccr); - Swap(&context_sparc->pc); - Swap(&context_sparc->npc); - Swap(&context_sparc->y); - Swap(&context_sparc->asi); - Swap(&context_sparc->fprs); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; - ++fpr_index) { - Swap(&context_sparc->float_save.regs[fpr_index]); - } - Swap(&context_sparc->float_save.filler); - Swap(&context_sparc->float_save.fsr); - } - SetContextSPARC(context_sparc.release()); - - break; - } - - case MD_CONTEXT_ARM: { - if (expected_size != sizeof(MDRawContextARM)) { - BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << - expected_size << " != " << sizeof(MDRawContextARM); - return false; - } - - scoped_ptr context_arm(new MDRawContextARM()); - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_arm->context_flags = context_flags; - - size_t flags_size = sizeof(context_arm->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_arm.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextARM) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read arm context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext arm does not match system info"; - return false; - } - - if (minidump_->swap()) { - // context_arm->context_flags was already swapped. - for (unsigned int ireg_index = 0; - ireg_index < MD_CONTEXT_ARM_GPR_COUNT; - ++ireg_index) { - Swap(&context_arm->iregs[ireg_index]); - } - Swap(&context_arm->cpsr); - Swap(&context_arm->float_save.fpscr); - for (unsigned int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; - ++fpr_index) { - Swap(&context_arm->float_save.regs[fpr_index]); - } - for (unsigned int fpe_index = 0; - fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; - ++fpe_index) { - Swap(&context_arm->float_save.extra[fpe_index]); - } - } - SetContextARM(context_arm.release()); - - break; - } - - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: { - if (expected_size != sizeof(MDRawContextMIPS)) { - BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " - << expected_size - << " != " - << sizeof(MDRawContextMIPS); - return false; - } - - scoped_ptr context_mips(new MDRawContextMIPS()); - - // Set the context_flags member, which has already been read, and - // read the rest of the structure beginning with the first member - // after context_flags. - context_mips->context_flags = context_flags; - - size_t flags_size = sizeof(context_mips->context_flags); - uint8_t* context_after_flags = - reinterpret_cast(context_mips.get()) + flags_size; - if (!minidump_->ReadBytes(context_after_flags, - sizeof(MDRawContextMIPS) - flags_size)) { - BPLOG(ERROR) << "MinidumpContext could not read MIPS context"; - return false; - } - - // Do this after reading the entire MDRawContext structure because - // GetSystemInfo may seek minidump to a new position. - if (!CheckAgainstSystemInfo(cpu_type)) { - BPLOG(ERROR) << "MinidumpContext MIPS does not match system info"; - return false; - } - - if (minidump_->swap()) { - // context_mips->context_flags was already swapped. - for (int ireg_index = 0; - ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; - ++ireg_index) { - Swap(&context_mips->iregs[ireg_index]); - } - Swap(&context_mips->mdhi); - Swap(&context_mips->mdlo); - for (int dsp_index = 0; - dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; - ++dsp_index) { - Swap(&context_mips->hi[dsp_index]); - Swap(&context_mips->lo[dsp_index]); - } - Swap(&context_mips->dsp_control); - Swap(&context_mips->epc); - Swap(&context_mips->badvaddr); - Swap(&context_mips->status); - Swap(&context_mips->cause); - for (int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; - ++fpr_index) { - Swap(&context_mips->float_save.regs[fpr_index]); - } - Swap(&context_mips->float_save.fpcsr); - Swap(&context_mips->float_save.fir); - } - SetContextMIPS(context_mips.release()); - - break; - } - - default: { - // Unknown context type - Don't log as an error yet. Let the - // caller work that out. - BPLOG(INFO) << "MinidumpContext unknown context type " << - HexString(cpu_type); - return false; - break; - } - } - SetContextFlags(context_flags); - } - - valid_ = true; - return true; -} - -bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { - // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, - // as this function just implements a sanity check. - MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); - if (!system_info) { - BPLOG(INFO) << "MinidumpContext could not be compared against " - "MinidumpSystemInfo"; - return true; - } - - // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info. - const MDRawSystemInfo* raw_system_info = system_info->system_info(); - if (!raw_system_info) { - BPLOG(INFO) << "MinidumpContext could not be compared against " - "MDRawSystemInfo"; - return false; - } - - MDCPUArchitecture system_info_cpu_type = static_cast( - raw_system_info->processor_architecture); - - // Compare the CPU type of the context record to the CPU type in the - // minidump's system info stream. - bool return_value = false; - switch (context_cpu_type) { - case MD_CONTEXT_X86: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 || - system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 || - system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) { - return_value = true; - } - break; - - case MD_CONTEXT_PPC: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC) - return_value = true; - break; - - case MD_CONTEXT_PPC64: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64) - return_value = true; - break; - - case MD_CONTEXT_AMD64: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) - return_value = true; - break; - - case MD_CONTEXT_SPARC: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC) - return_value = true; - break; - - case MD_CONTEXT_ARM: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM) - return_value = true; - break; - - case MD_CONTEXT_ARM64: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64) - return_value = true; - break; - - case MD_CONTEXT_MIPS: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS) - return_value = true; - break; - - case MD_CONTEXT_MIPS64: - if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS64) - return_value = true; - break; - } - - BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << - HexString(context_cpu_type) << - " wrong for MinidumpSystemInfo CPU " << - HexString(system_info_cpu_type); - - return return_value; -} - - -// -// MinidumpMemoryRegion -// - - -uint32_t MinidumpMemoryRegion::max_bytes_ = 2 * 1024 * 1024; // 2MB - - -MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) - : MinidumpObject(minidump), - descriptor_(NULL), - memory_(NULL) { -} - - -MinidumpMemoryRegion::~MinidumpMemoryRegion() { - delete memory_; -} - - -void MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { - descriptor_ = descriptor; - valid_ = descriptor && - descriptor_->memory.data_size <= - numeric_limits::max() - - descriptor_->start_of_memory_range; -} - - -const uint8_t* MinidumpMemoryRegion::GetMemory() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; - return NULL; - } - - if (!memory_) { - if (descriptor_->memory.data_size == 0) { - BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; - return NULL; - } - - if (!minidump_->SeekSet(descriptor_->memory.rva)) { - BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; - return NULL; - } - - if (descriptor_->memory.data_size > max_bytes_) { - BPLOG(ERROR) << "MinidumpMemoryRegion size " << - descriptor_->memory.data_size << " exceeds maximum " << - max_bytes_; - return NULL; - } - - scoped_ptr< vector > memory( - new vector(descriptor_->memory.data_size)); - - if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { - BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; - return NULL; - } - - memory_ = memory.release(); - } - - return &(*memory_)[0]; -} - - -uint64_t MinidumpMemoryRegion::GetBase() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase"; - return static_cast(-1); - } - - return descriptor_->start_of_memory_range; -} - - -uint32_t MinidumpMemoryRegion::GetSize() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize"; - return 0; - } - - return descriptor_->memory.data_size; -} - - -void MinidumpMemoryRegion::FreeMemory() { - delete memory_; - memory_ = NULL; -} - - -template -bool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address, - T* value) const { - BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal " - "requires |value|"; - assert(value); - *value = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for " - "GetMemoryAtAddressInternal"; - return false; - } - - // Common failure case - if (address < descriptor_->start_of_memory_range || - sizeof(T) > numeric_limits::max() - address || - address + sizeof(T) > descriptor_->start_of_memory_range + - descriptor_->memory.data_size) { - BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " << - HexString(address) << "+" << sizeof(T) << "/" << - HexString(descriptor_->start_of_memory_range) << "+" << - HexString(descriptor_->memory.data_size); - return false; - } - - const uint8_t* memory = GetMemory(); - if (!memory) { - // GetMemory already logged a perfectly good message. - return false; - } - - // If the CPU requires memory accesses to be aligned, this can crash. - // x86 and ppc are able to cope, though. - *value = *reinterpret_cast( - &memory[address - descriptor_->start_of_memory_range]); - - if (minidump_->swap()) - Swap(value); - - return true; -} - - -bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint8_t* value) const { - return GetMemoryAtAddressInternal(address, value); -} - - -bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint16_t* value) const { - return GetMemoryAtAddressInternal(address, value); -} - - -bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint32_t* value) const { - return GetMemoryAtAddressInternal(address, value); -} - - -bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, - uint64_t* value) const { - return GetMemoryAtAddressInternal(address, value); -} - - -void MinidumpMemoryRegion::Print() const { - if (!valid_) { - BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; - return; - } - - const uint8_t* memory = GetMemory(); - if (memory) { - printf("0x"); - for (unsigned int byte_index = 0; - byte_index < descriptor_->memory.data_size; - byte_index++) { - printf("%02x", memory[byte_index]); - } - printf("\n"); - } else { - printf("No memory\n"); - } -} - - -// -// MinidumpThread -// - - -MinidumpThread::MinidumpThread(Minidump* minidump) - : MinidumpObject(minidump), - thread_(), - memory_(NULL), - context_(NULL) { -} - - -MinidumpThread::~MinidumpThread() { - delete memory_; - delete context_; -} - - -bool MinidumpThread::Read() { - // Invalidate cached data. - delete memory_; - memory_ = NULL; - delete context_; - context_ = NULL; - - valid_ = false; - - if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) { - BPLOG(ERROR) << "MinidumpThread cannot read thread"; - return false; - } - - if (minidump_->swap()) { - Swap(&thread_.thread_id); - Swap(&thread_.suspend_count); - Swap(&thread_.priority_class); - Swap(&thread_.priority); - Swap(&thread_.teb); - Swap(&thread_.stack); - Swap(&thread_.thread_context); - } - - // Check for base + size overflow or undersize. - if (thread_.stack.memory.rva == 0 || - thread_.stack.memory.data_size == 0 || - thread_.stack.memory.data_size > numeric_limits::max() - - thread_.stack.start_of_memory_range) { - // This is ok, but log an error anyway. - BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << - HexString(thread_.stack.start_of_memory_range) << "+" << - HexString(thread_.stack.memory.data_size) << - ", RVA 0x" << HexString(thread_.stack.memory.rva); - } else { - memory_ = new MinidumpMemoryRegion(minidump_); - memory_->SetDescriptor(&thread_.stack); - } - - valid_ = true; - return true; -} - -uint64_t MinidumpThread::GetStartOfStackMemoryRange() const { - if (!valid_) { - BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread"; - return 0; - } - - return thread_.stack.start_of_memory_range; -} - -MinidumpMemoryRegion* MinidumpThread::GetMemory() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; - return NULL; - } - - return memory_; -} - - -MinidumpContext* MinidumpThread::GetContext() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; - return NULL; - } - - if (!context_) { - if (!minidump_->SeekSet(thread_.thread_context.rva)) { - BPLOG(ERROR) << "MinidumpThread cannot seek to context"; - return NULL; - } - - scoped_ptr context(new MinidumpContext(minidump_)); - - if (!context->Read(thread_.thread_context.data_size)) { - BPLOG(ERROR) << "MinidumpThread cannot read context"; - return NULL; - } - - context_ = context.release(); - } - - return context_; -} - - -bool MinidumpThread::GetThreadID(uint32_t *thread_id) const { - BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires " - "|thread_id|"; - assert(thread_id); - *thread_id = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID"; - return false; - } - - *thread_id = thread_.thread_id; - return true; -} - - -void MinidumpThread::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpThread cannot print invalid data"; - return; - } - - printf("MDRawThread\n"); - printf(" thread_id = 0x%x\n", thread_.thread_id); - printf(" suspend_count = %d\n", thread_.suspend_count); - printf(" priority_class = 0x%x\n", thread_.priority_class); - printf(" priority = 0x%x\n", thread_.priority); - printf(" teb = 0x%" PRIx64 "\n", thread_.teb); - printf(" stack.start_of_memory_range = 0x%" PRIx64 "\n", - thread_.stack.start_of_memory_range); - printf(" stack.memory.data_size = 0x%x\n", - thread_.stack.memory.data_size); - printf(" stack.memory.rva = 0x%x\n", thread_.stack.memory.rva); - printf(" thread_context.data_size = 0x%x\n", - thread_.thread_context.data_size); - printf(" thread_context.rva = 0x%x\n", - thread_.thread_context.rva); - - MinidumpContext* context = GetContext(); - if (context) { - printf("\n"); - context->Print(); - } else { - printf(" (no context)\n"); - printf("\n"); - } - - MinidumpMemoryRegion* memory = GetMemory(); - if (memory) { - printf("Stack\n"); - memory->Print(); - } else { - printf("No stack\n"); - } - printf("\n"); -} - - -// -// MinidumpThreadList -// - - -uint32_t MinidumpThreadList::max_threads_ = 4096; - - -MinidumpThreadList::MinidumpThreadList(Minidump* minidump) - : MinidumpStream(minidump), - id_to_thread_map_(), - threads_(NULL), - thread_count_(0) { -} - - -MinidumpThreadList::~MinidumpThreadList() { - delete threads_; -} - - -bool MinidumpThreadList::Read(uint32_t expected_size) { - // Invalidate cached data. - id_to_thread_map_.clear(); - delete threads_; - threads_ = NULL; - thread_count_ = 0; - - valid_ = false; - - uint32_t thread_count; - if (expected_size < sizeof(thread_count)) { - BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " << - expected_size << " < " << sizeof(thread_count); - return false; - } - if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) { - BPLOG(ERROR) << "MinidumpThreadList cannot read thread count"; - return false; - } - - if (minidump_->swap()) - Swap(&thread_count); - - if (thread_count > numeric_limits::max() / sizeof(MDRawThread)) { - BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count << - " would cause multiplication overflow"; - return false; - } - - if (expected_size != sizeof(thread_count) + - thread_count * sizeof(MDRawThread)) { - // may be padded with 4 bytes on 64bit ABIs for alignment - if (expected_size == sizeof(thread_count) + 4 + - thread_count * sizeof(MDRawThread)) { - uint32_t useless; - if (!minidump_->ReadBytes(&useless, 4)) { - BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded " - "bytes"; - return false; - } - } else { - BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size << - " != " << sizeof(thread_count) + - thread_count * sizeof(MDRawThread); - return false; - } - } - - - if (thread_count > max_threads_) { - BPLOG(ERROR) << "MinidumpThreadList count " << thread_count << - " exceeds maximum " << max_threads_; - return false; - } - - if (thread_count != 0) { - scoped_ptr threads( - new MinidumpThreads(thread_count, MinidumpThread(minidump_))); - - for (unsigned int thread_index = 0; - thread_index < thread_count; - ++thread_index) { - MinidumpThread* thread = &(*threads)[thread_index]; - - // Assume that the file offset is correct after the last read. - if (!thread->Read()) { - BPLOG(ERROR) << "MinidumpThreadList cannot read thread " << - thread_index << "/" << thread_count; - return false; - } - - uint32_t thread_id; - if (!thread->GetThreadID(&thread_id)) { - BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " << - thread_index << "/" << thread_count; - return false; - } - - if (GetThreadByID(thread_id)) { - // Another thread with this ID is already in the list. Data error. - BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " << - HexString(thread_id) << " at thread " << - thread_index << "/" << thread_count; - return false; - } - id_to_thread_map_[thread_id] = thread; - } - - threads_ = threads.release(); - } - - thread_count_ = thread_count; - - valid_ = true; - return true; -} - - -MinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) - const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; - return NULL; - } - - if (index >= thread_count_) { - BPLOG(ERROR) << "MinidumpThreadList index out of range: " << - index << "/" << thread_count_; - return NULL; - } - - return &(*threads_)[index]; -} - - -MinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) { - // Don't check valid_. Read calls this method before everything is - // validated. It is safe to not check valid_ here. - return id_to_thread_map_[thread_id]; -} - - -void MinidumpThreadList::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data"; - return; - } - - printf("MinidumpThreadList\n"); - printf(" thread_count = %d\n", thread_count_); - printf("\n"); - - for (unsigned int thread_index = 0; - thread_index < thread_count_; - ++thread_index) { - printf("thread[%d]\n", thread_index); - - (*threads_)[thread_index].Print(); - } -} - - -// -// MinidumpModule -// - - -uint32_t MinidumpModule::max_cv_bytes_ = 32768; -uint32_t MinidumpModule::max_misc_bytes_ = 32768; - - -MinidumpModule::MinidumpModule(Minidump* minidump) - : MinidumpObject(minidump), - module_valid_(false), - has_debug_info_(false), - module_(), - name_(NULL), - cv_record_(NULL), - cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), - misc_record_(NULL) { -} - - -MinidumpModule::~MinidumpModule() { - delete name_; - delete cv_record_; - delete misc_record_; -} - - -bool MinidumpModule::Read() { - // Invalidate cached data. - delete name_; - name_ = NULL; - delete cv_record_; - cv_record_ = NULL; - cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; - delete misc_record_; - misc_record_ = NULL; - - module_valid_ = false; - has_debug_info_ = false; - valid_ = false; - - if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) { - BPLOG(ERROR) << "MinidumpModule cannot read module"; - return false; - } - - if (minidump_->swap()) { - Swap(&module_.base_of_image); - Swap(&module_.size_of_image); - Swap(&module_.checksum); - Swap(&module_.time_date_stamp); - Swap(&module_.module_name_rva); - Swap(&module_.version_info.signature); - Swap(&module_.version_info.struct_version); - Swap(&module_.version_info.file_version_hi); - Swap(&module_.version_info.file_version_lo); - Swap(&module_.version_info.product_version_hi); - Swap(&module_.version_info.product_version_lo); - Swap(&module_.version_info.file_flags_mask); - Swap(&module_.version_info.file_flags); - Swap(&module_.version_info.file_os); - Swap(&module_.version_info.file_type); - Swap(&module_.version_info.file_subtype); - Swap(&module_.version_info.file_date_hi); - Swap(&module_.version_info.file_date_lo); - Swap(&module_.cv_record); - Swap(&module_.misc_record); - // Don't swap reserved fields because their contents are unknown (as - // are their proper widths). - } - - // Check for base + size overflow or undersize. - if (module_.size_of_image == 0 || - module_.size_of_image > - numeric_limits::max() - module_.base_of_image) { - BPLOG(ERROR) << "MinidumpModule has a module problem, " << - HexString(module_.base_of_image) << "+" << - HexString(module_.size_of_image); - return false; - } - - module_valid_ = true; - return true; -} - - -bool MinidumpModule::ReadAuxiliaryData() { - if (!module_valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData"; - return false; - } - - // Each module must have a name. - name_ = minidump_->ReadString(module_.module_name_rva); - if (!name_) { - BPLOG(ERROR) << "MinidumpModule could not read name"; - return false; - } - - // At this point, we have enough info for the module to be valid. - valid_ = true; - - // CodeView and miscellaneous debug records are only required if the - // module indicates that they exist. - if (module_.cv_record.data_size && !GetCVRecord(NULL)) { - BPLOG(ERROR) << "MinidumpModule has no CodeView record, " - "but one was expected"; - return false; - } - - if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { - BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " - "but one was expected"; - return false; - } - - has_debug_info_ = true; - return true; -} - - -string MinidumpModule::code_file() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for code_file"; - return ""; - } - - return *name_; -} - - -string MinidumpModule::code_identifier() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier"; - return ""; - } - - if (!has_debug_info_) - return ""; - - MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo(); - if (!minidump_system_info) { - BPLOG(ERROR) << "MinidumpModule code_identifier requires " - "MinidumpSystemInfo"; - return ""; - } - - const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); - if (!raw_system_info) { - BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo"; - return ""; - } - - string identifier; - - switch (raw_system_info->platform_id) { - case MD_OS_WIN32_NT: - case MD_OS_WIN32_WINDOWS: { - // Use the same format that the MS symbol server uses in filesystem - // hierarchies. - char identifier_string[17]; - snprintf(identifier_string, sizeof(identifier_string), "%08X%x", - module_.time_date_stamp, module_.size_of_image); - identifier = identifier_string; - break; - } - - case MD_OS_ANDROID: - case MD_OS_LINUX: { - // If ELF CodeView data is present, return the debug id. - if (cv_record_ && cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { - const MDCVInfoELF* cv_record_elf = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); - - for (unsigned int build_id_index = 0; - build_id_index < (cv_record_->size() - MDCVInfoELF_minsize); - ++build_id_index) { - char hexbyte[3]; - snprintf(hexbyte, sizeof(hexbyte), "%02x", - cv_record_elf->build_id[build_id_index]); - identifier += hexbyte; - } - break; - } - // Otherwise fall through to the case below. - } - - case MD_OS_MAC_OS_X: - case MD_OS_IOS: - case MD_OS_SOLARIS: - case MD_OS_NACL: - case MD_OS_PS3: { - // TODO(mmentovai): support uuid extension if present, otherwise fall - // back to version (from LC_ID_DYLIB?), otherwise fall back to something - // else. - identifier = "id"; - break; - } - - default: { - // Without knowing what OS generated the dump, we can't generate a good - // identifier. Return an empty string, signalling failure. - BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, " - "found " << HexString(raw_system_info->platform_id); - break; - } - } - - return identifier; -} - - -string MinidumpModule::debug_file() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for debug_file"; - return ""; - } - - if (!has_debug_info_) - return ""; - - string file; - // Prefer the CodeView record if present. - if (cv_record_) { - if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { - // It's actually an MDCVInfoPDB70 structure. - const MDCVInfoPDB70* cv_record_70 = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); - - // GetCVRecord guarantees pdb_file_name is null-terminated. - file = reinterpret_cast(cv_record_70->pdb_file_name); - } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { - // It's actually an MDCVInfoPDB20 structure. - const MDCVInfoPDB20* cv_record_20 = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); - - // GetCVRecord guarantees pdb_file_name is null-terminated. - file = reinterpret_cast(cv_record_20->pdb_file_name); - } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { - // It's actually an MDCVInfoELF structure. - assert(reinterpret_cast(&(*cv_record_)[0])-> - cv_signature == MD_CVINFOELF_SIGNATURE); - - // For MDCVInfoELF, the debug file is the code file. - file = *name_; - } - - // If there's a CodeView record but it doesn't match a known signature, - // try the miscellaneous record. - } - - if (file.empty()) { - // No usable CodeView record. Try the miscellaneous debug record. - if (misc_record_) { - const MDImageDebugMisc* misc_record = - reinterpret_cast(&(*misc_record_)[0]); - if (!misc_record->unicode) { - // If it's not Unicode, just stuff it into the string. It's unclear - // if misc_record->data is 0-terminated, so use an explicit size. - file = string( - reinterpret_cast(misc_record->data), - module_.misc_record.data_size - MDImageDebugMisc_minsize); - } else { - // There's a misc_record but it encodes the debug filename in UTF-16. - // (Actually, because miscellaneous records are so old, it's probably - // UCS-2.) Convert it to UTF-8 for congruity with the other strings - // that this method (and all other methods in the Minidump family) - // return. - - unsigned int bytes = - module_.misc_record.data_size - MDImageDebugMisc_minsize; - if (bytes % 2 == 0) { - unsigned int utf16_words = bytes / 2; - - // UTF16ToUTF8 expects a vector, so create a temporary one - // and copy the UTF-16 data into it. - vector string_utf16(utf16_words); - if (utf16_words) - memcpy(&string_utf16[0], &misc_record->data, bytes); - - // GetMiscRecord already byte-swapped the data[] field if it contains - // UTF-16, so pass false as the swap argument. - scoped_ptr new_file(UTF16ToUTF8(string_utf16, false)); - file = *new_file; - } - } - } - } - - // Relatively common case - BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " - "debug_file for " << *name_; - - return file; -} - -static string guid_and_age_to_debug_id(const MDGUID& guid, - uint32_t age) { - char identifier_string[41]; - snprintf(identifier_string, sizeof(identifier_string), - "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", - guid.data1, - guid.data2, - guid.data3, - guid.data4[0], - guid.data4[1], - guid.data4[2], - guid.data4[3], - guid.data4[4], - guid.data4[5], - guid.data4[6], - guid.data4[7], - age); - return identifier_string; -} - -string MinidumpModule::debug_identifier() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; - return ""; - } - - if (!has_debug_info_) - return ""; - - string identifier; - - // Use the CodeView record if present. - if (cv_record_) { - if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { - // It's actually an MDCVInfoPDB70 structure. - const MDCVInfoPDB70* cv_record_70 = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); - - // Use the same format that the MS symbol server uses in filesystem - // hierarchies. - identifier = guid_and_age_to_debug_id(cv_record_70->signature, - cv_record_70->age); - } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { - // It's actually an MDCVInfoPDB20 structure. - const MDCVInfoPDB20* cv_record_20 = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); - - // Use the same format that the MS symbol server uses in filesystem - // hierarchies. - char identifier_string[17]; - snprintf(identifier_string, sizeof(identifier_string), - "%08X%x", cv_record_20->signature, cv_record_20->age); - identifier = identifier_string; - } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { - // It's actually an MDCVInfoELF structure. - const MDCVInfoELF* cv_record_elf = - reinterpret_cast(&(*cv_record_)[0]); - assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); - - // For backwards-compatibility, stuff as many bytes as will fit into - // a MDGUID and use the MS symbol server format as MDCVInfoPDB70 does - // with age = 0. Historically Breakpad would do this during dump - // writing to fit the build id data into a MDCVInfoPDB70 struct. - // The full build id is available by calling code_identifier. - MDGUID guid = {0}; - memcpy(&guid, &cv_record_elf->build_id, - std::min(cv_record_->size() - MDCVInfoELF_minsize, - sizeof(MDGUID))); - identifier = guid_and_age_to_debug_id(guid, 0); - } - } - - // TODO(mmentovai): if there's no usable CodeView record, there might be a - // miscellaneous debug record. It only carries a filename, though, and no - // identifier. I'm not sure what the right thing to do for the identifier - // is in that case, but I don't expect to find many modules without a - // CodeView record (or some other Breakpad extension structure in place of - // a CodeView record). Treat it as an error (empty identifier) for now. - - // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier(). - - // Relatively common case - BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine " - "debug_identifier for " << *name_; - - return identifier; -} - - -string MinidumpModule::version() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for version"; - return ""; - } - - string version; - - if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE && - module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) { - char version_string[24]; - snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u", - module_.version_info.file_version_hi >> 16, - module_.version_info.file_version_hi & 0xffff, - module_.version_info.file_version_lo >> 16, - module_.version_info.file_version_lo & 0xffff); - version = version_string; - } - - // TODO(mmentovai): possibly support other struct types in place of - // the one used with MD_VSFIXEDFILEINFO_SIGNATURE. We can possibly use - // a different structure that better represents versioning facilities on - // Mac OS X and Linux, instead of forcing them to adhere to the dotted - // quad of 16-bit ints that Windows uses. - - BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine " - "version for " << *name_; - - return version; -} - - -CodeModule* MinidumpModule::Copy() const { - return new BasicCodeModule(this); -} - - -uint64_t MinidumpModule::shrink_down_delta() const { - return 0; -} - -void MinidumpModule::SetShrinkDownDelta(uint64_t shrink_down_delta) { - // Not implemented - assert(false); -} - - -const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { - if (!module_valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; - return NULL; - } - - if (!cv_record_) { - // This just guards against 0-sized CodeView records; more specific checks - // are used when the signature is checked against various structure types. - if (module_.cv_record.data_size == 0) { - return NULL; - } - - if (!minidump_->SeekSet(module_.cv_record.rva)) { - BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; - return NULL; - } - - if (module_.cv_record.data_size > max_cv_bytes_) { - BPLOG(ERROR) << "MinidumpModule CodeView record size " << - module_.cv_record.data_size << " exceeds maximum " << - max_cv_bytes_; - return NULL; - } - - // Allocating something that will be accessed as MDCVInfoPDB70 or - // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment - // problems. x86 and ppc are able to cope, though. This allocation - // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are - // variable-sized due to their pdb_file_name fields; these structures - // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating - // them as such would result in incomplete structures or overruns. - scoped_ptr< vector > cv_record( - new vector(module_.cv_record.data_size)); - - if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { - BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; - return NULL; - } - - uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; - if (module_.cv_record.data_size > sizeof(signature)) { - MDCVInfoPDB70* cv_record_signature = - reinterpret_cast(&(*cv_record)[0]); - signature = cv_record_signature->cv_signature; - if (minidump_->swap()) - Swap(&signature); - } - - if (signature == MD_CVINFOPDB70_SIGNATURE) { - // Now that the structure type is known, recheck the size. - if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { - BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << - MDCVInfoPDB70_minsize << " > " << - module_.cv_record.data_size; - return NULL; - } - - if (minidump_->swap()) { - MDCVInfoPDB70* cv_record_70 = - reinterpret_cast(&(*cv_record)[0]); - Swap(&cv_record_70->cv_signature); - Swap(&cv_record_70->signature); - Swap(&cv_record_70->age); - // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit - // quantities. (It's a path, is it UTF-8?) - } - - // The last field of either structure is null-terminated 8-bit character - // data. Ensure that it's null-terminated. - if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { - BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " - "0-terminated"; - return NULL; - } - } else if (signature == MD_CVINFOPDB20_SIGNATURE) { - // Now that the structure type is known, recheck the size. - if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { - BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << - MDCVInfoPDB20_minsize << " > " << - module_.cv_record.data_size; - return NULL; - } - if (minidump_->swap()) { - MDCVInfoPDB20* cv_record_20 = - reinterpret_cast(&(*cv_record)[0]); - Swap(&cv_record_20->cv_header.signature); - Swap(&cv_record_20->cv_header.offset); - Swap(&cv_record_20->signature); - Swap(&cv_record_20->age); - // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit - // quantities. (It's a path, is it UTF-8?) - } - - // The last field of either structure is null-terminated 8-bit character - // data. Ensure that it's null-terminated. - if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { - BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " - "0-terminated"; - return NULL; - } - } else if (signature == MD_CVINFOELF_SIGNATURE) { - // Now that the structure type is known, recheck the size. - if (MDCVInfoELF_minsize > module_.cv_record.data_size) { - BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " << - MDCVInfoELF_minsize << " > " << - module_.cv_record.data_size; - return NULL; - } - // There's nothing to swap in CVInfoELF, it's just raw bytes. - } - - // If the signature doesn't match something above, it's not something - // that Breakpad can presently handle directly. Because some modules in - // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, - // don't bail out here - allow the data to be returned to the user, - // although byte-swapping can't be done. - - // Store the vector type because that's how storage was allocated, but - // return it casted to uint8_t*. - cv_record_ = cv_record.release(); - cv_record_signature_ = signature; - } - - if (size) - *size = module_.cv_record.data_size; - - return &(*cv_record_)[0]; -} - - -const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { - if (!module_valid_) { - BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; - return NULL; - } - - if (!misc_record_) { - if (module_.misc_record.data_size == 0) { - return NULL; - } - - if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { - BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " - "size mismatch, " << MDImageDebugMisc_minsize << " > " << - module_.misc_record.data_size; - return NULL; - } - - if (!minidump_->SeekSet(module_.misc_record.rva)) { - BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " - "debugging record"; - return NULL; - } - - if (module_.misc_record.data_size > max_misc_bytes_) { - BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << - module_.misc_record.data_size << " exceeds maximum " << - max_misc_bytes_; - return NULL; - } - - // Allocating something that will be accessed as MDImageDebugMisc but - // is allocated as uint8_t[] can cause alignment problems. x86 and - // ppc are able to cope, though. This allocation style is needed - // because the MDImageDebugMisc is variable-sized due to its data field; - // this structure is not MDImageDebugMisc_minsize and treating it as such - // would result in an incomplete structure or an overrun. - scoped_ptr< vector > misc_record_mem( - new vector(module_.misc_record.data_size)); - MDImageDebugMisc* misc_record = - reinterpret_cast(&(*misc_record_mem)[0]); - - if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { - BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " - "record"; - return NULL; - } - - if (minidump_->swap()) { - Swap(&misc_record->data_type); - Swap(&misc_record->length); - // Don't swap misc_record.unicode because it's an 8-bit quantity. - // Don't swap the reserved fields for the same reason, and because - // they don't contain any valid data. - if (misc_record->unicode) { - // There is a potential alignment problem, but shouldn't be a problem - // in practice due to the layout of MDImageDebugMisc. - uint16_t* data16 = reinterpret_cast(&(misc_record->data)); - unsigned int dataBytes = module_.misc_record.data_size - - MDImageDebugMisc_minsize; - Swap(data16, dataBytes); - } - } - - if (module_.misc_record.data_size != misc_record->length) { - BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " - "size mismatch, " << module_.misc_record.data_size << - " != " << misc_record->length; - return NULL; - } - - // Store the vector type because that's how storage was allocated, but - // return it casted to MDImageDebugMisc*. - misc_record_ = misc_record_mem.release(); - } - - if (size) - *size = module_.misc_record.data_size; - - return reinterpret_cast(&(*misc_record_)[0]); -} - - -void MinidumpModule::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpModule cannot print invalid data"; - return; - } - - printf("MDRawModule\n"); - printf(" base_of_image = 0x%" PRIx64 "\n", - module_.base_of_image); - printf(" size_of_image = 0x%x\n", - module_.size_of_image); - printf(" checksum = 0x%x\n", - module_.checksum); - printf(" time_date_stamp = 0x%x %s\n", - module_.time_date_stamp, - TimeTToUTCString(module_.time_date_stamp).c_str()); - printf(" module_name_rva = 0x%x\n", - module_.module_name_rva); - printf(" version_info.signature = 0x%x\n", - module_.version_info.signature); - printf(" version_info.struct_version = 0x%x\n", - module_.version_info.struct_version); - printf(" version_info.file_version = 0x%x:0x%x\n", - module_.version_info.file_version_hi, - module_.version_info.file_version_lo); - printf(" version_info.product_version = 0x%x:0x%x\n", - module_.version_info.product_version_hi, - module_.version_info.product_version_lo); - printf(" version_info.file_flags_mask = 0x%x\n", - module_.version_info.file_flags_mask); - printf(" version_info.file_flags = 0x%x\n", - module_.version_info.file_flags); - printf(" version_info.file_os = 0x%x\n", - module_.version_info.file_os); - printf(" version_info.file_type = 0x%x\n", - module_.version_info.file_type); - printf(" version_info.file_subtype = 0x%x\n", - module_.version_info.file_subtype); - printf(" version_info.file_date = 0x%x:0x%x\n", - module_.version_info.file_date_hi, - module_.version_info.file_date_lo); - printf(" cv_record.data_size = %d\n", - module_.cv_record.data_size); - printf(" cv_record.rva = 0x%x\n", - module_.cv_record.rva); - printf(" misc_record.data_size = %d\n", - module_.misc_record.data_size); - printf(" misc_record.rva = 0x%x\n", - module_.misc_record.rva); - - printf(" (code_file) = \"%s\"\n", code_file().c_str()); - printf(" (code_identifier) = \"%s\"\n", - code_identifier().c_str()); - - uint32_t cv_record_size; - const uint8_t *cv_record = GetCVRecord(&cv_record_size); - if (cv_record) { - if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { - const MDCVInfoPDB70* cv_record_70 = - reinterpret_cast(cv_record); - assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); - - printf(" (cv_record).cv_signature = 0x%x\n", - cv_record_70->cv_signature); - printf(" (cv_record).signature = %08x-%04x-%04x-%02x%02x-", - cv_record_70->signature.data1, - cv_record_70->signature.data2, - cv_record_70->signature.data3, - cv_record_70->signature.data4[0], - cv_record_70->signature.data4[1]); - for (unsigned int guidIndex = 2; - guidIndex < 8; - ++guidIndex) { - printf("%02x", cv_record_70->signature.data4[guidIndex]); - } - printf("\n"); - printf(" (cv_record).age = %d\n", - cv_record_70->age); - printf(" (cv_record).pdb_file_name = \"%s\"\n", - cv_record_70->pdb_file_name); - } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { - const MDCVInfoPDB20* cv_record_20 = - reinterpret_cast(cv_record); - assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); - - printf(" (cv_record).cv_header.signature = 0x%x\n", - cv_record_20->cv_header.signature); - printf(" (cv_record).cv_header.offset = 0x%x\n", - cv_record_20->cv_header.offset); - printf(" (cv_record).signature = 0x%x %s\n", - cv_record_20->signature, - TimeTToUTCString(cv_record_20->signature).c_str()); - printf(" (cv_record).age = %d\n", - cv_record_20->age); - printf(" (cv_record).pdb_file_name = \"%s\"\n", - cv_record_20->pdb_file_name); - } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { - const MDCVInfoELF* cv_record_elf = - reinterpret_cast(cv_record); - assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); - - printf(" (cv_record).cv_signature = 0x%x\n", - cv_record_elf->cv_signature); - printf(" (cv_record).build_id = "); - for (unsigned int build_id_index = 0; - build_id_index < (cv_record_size - MDCVInfoELF_minsize); - ++build_id_index) { - printf("%02x", cv_record_elf->build_id[build_id_index]); - } - printf("\n"); - } else { - printf(" (cv_record) = "); - for (unsigned int cv_byte_index = 0; - cv_byte_index < cv_record_size; - ++cv_byte_index) { - printf("%02x", cv_record[cv_byte_index]); - } - printf("\n"); - } - } else { - printf(" (cv_record) = (null)\n"); - } - - const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); - if (misc_record) { - printf(" (misc_record).data_type = 0x%x\n", - misc_record->data_type); - printf(" (misc_record).length = 0x%x\n", - misc_record->length); - printf(" (misc_record).unicode = %d\n", - misc_record->unicode); - if (misc_record->unicode) { - string misc_record_data_utf8; - ConvertUTF16BufferToUTF8String( - reinterpret_cast(misc_record->data), - misc_record->length - offsetof(MDImageDebugMisc, data), - &misc_record_data_utf8, - false); // already swapped - printf(" (misc_record).data = \"%s\"\n", - misc_record_data_utf8.c_str()); - } else { - printf(" (misc_record).data = \"%s\"\n", - misc_record->data); - } - } else { - printf(" (misc_record) = (null)\n"); - } - - printf(" (debug_file) = \"%s\"\n", debug_file().c_str()); - printf(" (debug_identifier) = \"%s\"\n", - debug_identifier().c_str()); - printf(" (version) = \"%s\"\n", version().c_str()); - printf("\n"); -} - - -// -// MinidumpModuleList -// - - -uint32_t MinidumpModuleList::max_modules_ = 1024; - - -MinidumpModuleList::MinidumpModuleList(Minidump* minidump) - : MinidumpStream(minidump), - range_map_(new RangeMap()), - modules_(NULL), - module_count_(0) { - range_map_->SetEnableShrinkDown(minidump_->IsAndroid()); -} - - -MinidumpModuleList::~MinidumpModuleList() { - delete range_map_; - delete modules_; -} - - -bool MinidumpModuleList::Read(uint32_t expected_size) { - // Invalidate cached data. - range_map_->Clear(); - delete modules_; - modules_ = NULL; - module_count_ = 0; - - valid_ = false; - - uint32_t module_count; - if (expected_size < sizeof(module_count)) { - BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " << - expected_size << " < " << sizeof(module_count); - return false; - } - if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) { - BPLOG(ERROR) << "MinidumpModuleList could not read module count"; - return false; - } - - if (minidump_->swap()) - Swap(&module_count); - - if (module_count > numeric_limits::max() / MD_MODULE_SIZE) { - BPLOG(ERROR) << "MinidumpModuleList module count " << module_count << - " would cause multiplication overflow"; - return false; - } - - if (expected_size != sizeof(module_count) + - module_count * MD_MODULE_SIZE) { - // may be padded with 4 bytes on 64bit ABIs for alignment - if (expected_size == sizeof(module_count) + 4 + - module_count * MD_MODULE_SIZE) { - uint32_t useless; - if (!minidump_->ReadBytes(&useless, 4)) { - BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded " - "bytes"; - return false; - } - } else { - BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size << - " != " << sizeof(module_count) + - module_count * MD_MODULE_SIZE; - return false; - } - } - - if (module_count > max_modules_) { - BPLOG(ERROR) << "MinidumpModuleList count " << module_count_ << - " exceeds maximum " << max_modules_; - return false; - } - - if (module_count != 0) { - scoped_ptr modules( - new MinidumpModules(module_count, MinidumpModule(minidump_))); - - for (unsigned int module_index = 0; - module_index < module_count; - ++module_index) { - MinidumpModule* module = &(*modules)[module_index]; - - // Assume that the file offset is correct after the last read. - if (!module->Read()) { - BPLOG(ERROR) << "MinidumpModuleList could not read module " << - module_index << "/" << module_count; - return false; - } - } - - // Loop through the module list once more to read additional data and - // build the range map. This is done in a second pass because - // MinidumpModule::ReadAuxiliaryData seeks around, and if it were - // included in the loop above, additional seeks would be needed where - // none are now to read contiguous data. - uint64_t last_end_address = 0; - for (unsigned int module_index = 0; - module_index < module_count; - ++module_index) { - MinidumpModule* module = &(*modules)[module_index]; - - // ReadAuxiliaryData fails if any data that the module indicates should - // exist is missing, but we treat some such cases as valid anyway. See - // issue #222: if a debugging record is of a format that's too large to - // handle, it shouldn't render the entire dump invalid. Check module - // validity before giving up. - if (!module->ReadAuxiliaryData() && !module->valid()) { - BPLOG(ERROR) << "MinidumpModuleList could not read required module " - "auxiliary data for module " << - module_index << "/" << module_count; - return false; - } - - // It is safe to use module->code_file() after successfully calling - // module->ReadAuxiliaryData or noting that the module is valid. - - uint64_t base_address = module->base_address(); - uint64_t module_size = module->size(); - if (base_address == static_cast(-1)) { - BPLOG(ERROR) << "MinidumpModuleList found bad base address " - "for module " << module_index << "/" << module_count << - ", " << module->code_file(); - return false; - } - - if (!range_map_->StoreRange(base_address, module_size, module_index)) { - // Android's shared memory implementation /dev/ashmem can contain - // duplicate entries for JITted code, so ignore these. - // TODO(wfh): Remove this code when Android is fixed. - // See https://crbug.com/439531 - const string kDevAshmem("/dev/ashmem/"); - if (module->code_file().compare( - 0, kDevAshmem.length(), kDevAshmem) != 0) { - if (base_address < last_end_address) { - // If failed due to apparent range overlap the cause may be - // the client correction applied for Android packed relocations. - // If this is the case, back out the client correction and retry. - module_size -= last_end_address - base_address; - base_address = last_end_address; - if (!range_map_->StoreRange(base_address, - module_size, module_index)) { - BPLOG(ERROR) << "MinidumpModuleList could not store module " << - module_index << "/" << module_count << ", " << - module->code_file() << ", " << - HexString(base_address) << "+" << - HexString(module_size) << ", after adjusting"; - return false; - } - } else { - BPLOG(ERROR) << "MinidumpModuleList could not store module " << - module_index << "/" << module_count << ", " << - module->code_file() << ", " << - HexString(base_address) << "+" << - HexString(module_size); - return false; - } - } else { - BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module " << - module_index << "/" << module_count << ", " << - module->code_file() << ", " << - HexString(base_address) << "+" << - HexString(module_size); - } - } - last_end_address = base_address + module_size; - } - - modules_ = modules.release(); - } - - module_count_ = module_count; - - valid_ = true; - return true; -} - - -const MinidumpModule* MinidumpModuleList::GetModuleForAddress( - uint64_t address) const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; - return NULL; - } - - unsigned int module_index; - if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { - BPLOG(INFO) << "MinidumpModuleList has no module at " << - HexString(address); - return NULL; - } - - return GetModuleAtIndex(module_index); -} - - -const MinidumpModule* MinidumpModuleList::GetMainModule() const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; - return NULL; - } - - // The main code module is the first one present in a minidump file's - // MDRawModuleList. - return GetModuleAtIndex(0); -} - - -const MinidumpModule* MinidumpModuleList::GetModuleAtSequence( - unsigned int sequence) const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; - return NULL; - } - - if (sequence >= module_count_) { - BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << - sequence << "/" << module_count_; - return NULL; - } - - unsigned int module_index; - if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, - NULL /* base */, NULL /* delta */, - NULL /* size */)) { - BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; - return NULL; - } - - return GetModuleAtIndex(module_index); -} - - -const MinidumpModule* MinidumpModuleList::GetModuleAtIndex( - unsigned int index) const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; - return NULL; - } - - if (index >= module_count_) { - BPLOG(ERROR) << "MinidumpModuleList index out of range: " << - index << "/" << module_count_; - return NULL; - } - - return &(*modules_)[index]; -} - - -const CodeModules* MinidumpModuleList::Copy() const { - return new BasicCodeModules(this); -} - -vector > -MinidumpModuleList::GetShrunkRangeModules() const { - return vector >(); -} - -bool MinidumpModuleList::IsModuleShrinkEnabled() const { - return range_map_->IsShrinkDownEnabled(); -} - -void MinidumpModuleList::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data"; - return; - } - - printf("MinidumpModuleList\n"); - printf(" module_count = %d\n", module_count_); - printf("\n"); - - for (unsigned int module_index = 0; - module_index < module_count_; - ++module_index) { - printf("module[%d]\n", module_index); - - (*modules_)[module_index].Print(); - } -} - - -// -// MinidumpMemoryList -// - - -uint32_t MinidumpMemoryList::max_regions_ = 4096; - - -MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) - : MinidumpStream(minidump), - range_map_(new RangeMap()), - descriptors_(NULL), - regions_(NULL), - region_count_(0) { -} - - -MinidumpMemoryList::~MinidumpMemoryList() { - delete range_map_; - delete descriptors_; - delete regions_; -} - - -bool MinidumpMemoryList::Read(uint32_t expected_size) { - // Invalidate cached data. - delete descriptors_; - descriptors_ = NULL; - delete regions_; - regions_ = NULL; - range_map_->Clear(); - region_count_ = 0; - - valid_ = false; - - uint32_t region_count; - if (expected_size < sizeof(region_count)) { - BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " << - expected_size << " < " << sizeof(region_count); - return false; - } - if (!minidump_->ReadBytes(®ion_count, sizeof(region_count))) { - BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count"; - return false; - } - - if (minidump_->swap()) - Swap(®ion_count); - - if (region_count > - numeric_limits::max() / sizeof(MDMemoryDescriptor)) { - BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count << - " would cause multiplication overflow"; - return false; - } - - if (expected_size != sizeof(region_count) + - region_count * sizeof(MDMemoryDescriptor)) { - // may be padded with 4 bytes on 64bit ABIs for alignment - if (expected_size == sizeof(region_count) + 4 + - region_count * sizeof(MDMemoryDescriptor)) { - uint32_t useless; - if (!minidump_->ReadBytes(&useless, 4)) { - BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded " - "bytes"; - return false; - } - } else { - BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size << - " != " << sizeof(region_count) + - region_count * sizeof(MDMemoryDescriptor); - return false; - } - } - - if (region_count > max_regions_) { - BPLOG(ERROR) << "MinidumpMemoryList count " << region_count << - " exceeds maximum " << max_regions_; - return false; - } - - if (region_count != 0) { - scoped_ptr descriptors( - new MemoryDescriptors(region_count)); - - // Read the entire array in one fell swoop, instead of reading one entry - // at a time in the loop. - if (!minidump_->ReadBytes(&(*descriptors)[0], - sizeof(MDMemoryDescriptor) * region_count)) { - BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list"; - return false; - } - - scoped_ptr regions( - new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); - - for (unsigned int region_index = 0; - region_index < region_count; - ++region_index) { - MDMemoryDescriptor* descriptor = &(*descriptors)[region_index]; - - if (minidump_->swap()) - Swap(descriptor); - - uint64_t base_address = descriptor->start_of_memory_range; - uint32_t region_size = descriptor->memory.data_size; - - // Check for base + size overflow or undersize. - if (region_size == 0 || - region_size > numeric_limits::max() - base_address) { - BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " << - " region " << region_index << "/" << region_count << - ", " << HexString(base_address) << "+" << - HexString(region_size); - return false; - } - - if (!range_map_->StoreRange(base_address, region_size, region_index)) { - BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " << - region_index << "/" << region_count << ", " << - HexString(base_address) << "+" << - HexString(region_size); - return false; - } - - (*regions)[region_index].SetDescriptor(descriptor); - } - - descriptors_ = descriptors.release(); - regions_ = regions.release(); - } - - region_count_ = region_count; - - valid_ = true; - return true; -} - - -MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( - unsigned int index) { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; - return NULL; - } - - if (index >= region_count_) { - BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << - index << "/" << region_count_; - return NULL; - } - - return &(*regions_)[index]; -} - - -MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( - uint64_t address) { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; - return NULL; - } - - unsigned int region_index; - if (!range_map_->RetrieveRange(address, ®ion_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { - BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << - HexString(address); - return NULL; - } - - return GetMemoryRegionAtIndex(region_index); -} - - -void MinidumpMemoryList::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data"; - return; - } - - printf("MinidumpMemoryList\n"); - printf(" region_count = %d\n", region_count_); - printf("\n"); - - for (unsigned int region_index = 0; - region_index < region_count_; - ++region_index) { - MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index]; - printf("region[%d]\n", region_index); - printf("MDMemoryDescriptor\n"); - printf(" start_of_memory_range = 0x%" PRIx64 "\n", - descriptor->start_of_memory_range); - printf(" memory.data_size = 0x%x\n", descriptor->memory.data_size); - printf(" memory.rva = 0x%x\n", descriptor->memory.rva); - MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index); - if (region) { - printf("Memory\n"); - region->Print(); - } else { - printf("No memory\n"); - } - printf("\n"); - } -} - - -// -// MinidumpException -// - - -MinidumpException::MinidumpException(Minidump* minidump) - : MinidumpStream(minidump), - exception_(), - context_(NULL) { -} - - -MinidumpException::~MinidumpException() { - delete context_; -} - - -bool MinidumpException::Read(uint32_t expected_size) { - // Invalidate cached data. - delete context_; - context_ = NULL; - - valid_ = false; - - if (expected_size != sizeof(exception_)) { - BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size << - " != " << sizeof(exception_); - return false; - } - - if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) { - BPLOG(ERROR) << "MinidumpException cannot read exception"; - return false; - } - - if (minidump_->swap()) { - Swap(&exception_.thread_id); - // exception_.__align is for alignment only and does not need to be - // swapped. - Swap(&exception_.exception_record.exception_code); - Swap(&exception_.exception_record.exception_flags); - Swap(&exception_.exception_record.exception_record); - Swap(&exception_.exception_record.exception_address); - Swap(&exception_.exception_record.number_parameters); - // exception_.exception_record.__align is for alignment only and does not - // need to be swapped. - for (unsigned int parameter_index = 0; - parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS; - ++parameter_index) { - Swap(&exception_.exception_record.exception_information[parameter_index]); - } - Swap(&exception_.thread_context); - } - - valid_ = true; - return true; -} - - -bool MinidumpException::GetThreadID(uint32_t *thread_id) const { - BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires " - "|thread_id|"; - assert(thread_id); - *thread_id = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID"; - return false; - } - - *thread_id = exception_.thread_id; - return true; -} - - -MinidumpContext* MinidumpException::GetContext() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; - return NULL; - } - - if (!context_) { - if (!minidump_->SeekSet(exception_.thread_context.rva)) { - BPLOG(ERROR) << "MinidumpException cannot seek to context"; - return NULL; - } - - scoped_ptr context(new MinidumpContext(minidump_)); - - // Don't log as an error if we can still fall back on the thread's context - // (which must be possible if we got this far.) - if (!context->Read(exception_.thread_context.data_size)) { - BPLOG(INFO) << "MinidumpException cannot read context"; - return NULL; - } - - context_ = context.release(); - } - - return context_; -} - - -void MinidumpException::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpException cannot print invalid data"; - return; - } - - printf("MDException\n"); - printf(" thread_id = 0x%x\n", - exception_.thread_id); - printf(" exception_record.exception_code = 0x%x\n", - exception_.exception_record.exception_code); - printf(" exception_record.exception_flags = 0x%x\n", - exception_.exception_record.exception_flags); - printf(" exception_record.exception_record = 0x%" PRIx64 "\n", - exception_.exception_record.exception_record); - printf(" exception_record.exception_address = 0x%" PRIx64 "\n", - exception_.exception_record.exception_address); - printf(" exception_record.number_parameters = %d\n", - exception_.exception_record.number_parameters); - for (unsigned int parameterIndex = 0; - parameterIndex < exception_.exception_record.number_parameters; - ++parameterIndex) { - printf(" exception_record.exception_information[%2d] = 0x%" PRIx64 "\n", - parameterIndex, - exception_.exception_record.exception_information[parameterIndex]); - } - printf(" thread_context.data_size = %d\n", - exception_.thread_context.data_size); - printf(" thread_context.rva = 0x%x\n", - exception_.thread_context.rva); - MinidumpContext* context = GetContext(); - if (context) { - printf("\n"); - context->Print(); - } else { - printf(" (no context)\n"); - printf("\n"); - } -} - -// -// MinidumpAssertion -// - - -MinidumpAssertion::MinidumpAssertion(Minidump* minidump) - : MinidumpStream(minidump), - assertion_(), - expression_(), - function_(), - file_() { -} - - -MinidumpAssertion::~MinidumpAssertion() { -} - - -bool MinidumpAssertion::Read(uint32_t expected_size) { - // Invalidate cached data. - valid_ = false; - - if (expected_size != sizeof(assertion_)) { - BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size << - " != " << sizeof(assertion_); - return false; - } - - if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) { - BPLOG(ERROR) << "MinidumpAssertion cannot read assertion"; - return false; - } - - // Each of {expression, function, file} is a UTF-16 string, - // we'll convert them to UTF-8 for ease of use. - ConvertUTF16BufferToUTF8String(assertion_.expression, - sizeof(assertion_.expression), &expression_, - minidump_->swap()); - ConvertUTF16BufferToUTF8String(assertion_.function, - sizeof(assertion_.function), &function_, - minidump_->swap()); - ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file), - &file_, minidump_->swap()); - - if (minidump_->swap()) { - Swap(&assertion_.line); - Swap(&assertion_.type); - } - - valid_ = true; - return true; -} - -void MinidumpAssertion::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data"; - return; - } - - printf("MDAssertion\n"); - printf(" expression = %s\n", - expression_.c_str()); - printf(" function = %s\n", - function_.c_str()); - printf(" file = %s\n", - file_.c_str()); - printf(" line = %u\n", - assertion_.line); - printf(" type = %u\n", - assertion_.type); - printf("\n"); -} - -// -// MinidumpSystemInfo -// - - -MinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) - : MinidumpStream(minidump), - system_info_(), - csd_version_(NULL), - cpu_vendor_(NULL) { -} - - -MinidumpSystemInfo::~MinidumpSystemInfo() { - delete csd_version_; - delete cpu_vendor_; -} - - -bool MinidumpSystemInfo::Read(uint32_t expected_size) { - // Invalidate cached data. - delete csd_version_; - csd_version_ = NULL; - delete cpu_vendor_; - cpu_vendor_ = NULL; - - valid_ = false; - - if (expected_size != sizeof(system_info_)) { - BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size << - " != " << sizeof(system_info_); - return false; - } - - if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) { - BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info"; - return false; - } - - if (minidump_->swap()) { - Swap(&system_info_.processor_architecture); - Swap(&system_info_.processor_level); - Swap(&system_info_.processor_revision); - // number_of_processors and product_type are 8-bit quantities and need no - // swapping. - Swap(&system_info_.major_version); - Swap(&system_info_.minor_version); - Swap(&system_info_.build_number); - Swap(&system_info_.platform_id); - Swap(&system_info_.csd_version_rva); - Swap(&system_info_.suite_mask); - // Don't swap the reserved2 field because its contents are unknown. - - if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || - system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { - for (unsigned int i = 0; i < 3; ++i) - Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]); - Swap(&system_info_.cpu.x86_cpu_info.version_information); - Swap(&system_info_.cpu.x86_cpu_info.feature_information); - Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); - } else { - for (unsigned int i = 0; i < 2; ++i) - Swap(&system_info_.cpu.other_cpu_info.processor_features[i]); - } - } - - valid_ = true; - return true; -} - - -string MinidumpSystemInfo::GetOS() { - string os; - - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS"; - return os; - } - - switch (system_info_.platform_id) { - case MD_OS_WIN32_NT: - case MD_OS_WIN32_WINDOWS: - os = "windows"; - break; - - case MD_OS_MAC_OS_X: - os = "mac"; - break; - - case MD_OS_IOS: - os = "ios"; - break; - - case MD_OS_LINUX: - os = "linux"; - break; - - case MD_OS_SOLARIS: - os = "solaris"; - break; - - case MD_OS_ANDROID: - os = "android"; - break; - - case MD_OS_PS3: - os = "ps3"; - break; - - case MD_OS_NACL: - os = "nacl"; - break; - - default: - BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " << - HexString(system_info_.platform_id); - break; - } - - return os; -} - - -string MinidumpSystemInfo::GetCPU() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU"; - return ""; - } - - string cpu; - - switch (system_info_.processor_architecture) { - case MD_CPU_ARCHITECTURE_X86: - case MD_CPU_ARCHITECTURE_X86_WIN64: - cpu = "x86"; - break; - - case MD_CPU_ARCHITECTURE_AMD64: - cpu = "x86-64"; - break; - - case MD_CPU_ARCHITECTURE_PPC: - cpu = "ppc"; - break; - - case MD_CPU_ARCHITECTURE_PPC64: - cpu = "ppc64"; - break; - - case MD_CPU_ARCHITECTURE_SPARC: - cpu = "sparc"; - break; - - case MD_CPU_ARCHITECTURE_ARM: - cpu = "arm"; - break; - - case MD_CPU_ARCHITECTURE_ARM64: - cpu = "arm64"; - break; - - default: - BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " << - HexString(system_info_.processor_architecture); - break; - } - - return cpu; -} - - -const string* MinidumpSystemInfo::GetCSDVersion() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; - return NULL; - } - - if (!csd_version_) - csd_version_ = minidump_->ReadString(system_info_.csd_version_rva); - - BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read " - "CSD version"; - - return csd_version_; -} - - -const string* MinidumpSystemInfo::GetCPUVendor() { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; - return NULL; - } - - // CPU vendor information can only be determined from x86 minidumps. - if (!cpu_vendor_ && - (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || - system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) { - char cpu_vendor_string[13]; - snprintf(cpu_vendor_string, sizeof(cpu_vendor_string), - "%c%c%c%c%c%c%c%c%c%c%c%c", - system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff, - system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff, - system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff, - (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff); - cpu_vendor_ = new string(cpu_vendor_string); - } - - return cpu_vendor_; -} - - -void MinidumpSystemInfo::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data"; - return; - } - - printf("MDRawSystemInfo\n"); - printf(" processor_architecture = 0x%x\n", - system_info_.processor_architecture); - printf(" processor_level = %d\n", - system_info_.processor_level); - printf(" processor_revision = 0x%x\n", - system_info_.processor_revision); - printf(" number_of_processors = %d\n", - system_info_.number_of_processors); - printf(" product_type = %d\n", - system_info_.product_type); - printf(" major_version = %d\n", - system_info_.major_version); - printf(" minor_version = %d\n", - system_info_.minor_version); - printf(" build_number = %d\n", - system_info_.build_number); - printf(" platform_id = 0x%x\n", - system_info_.platform_id); - printf(" csd_version_rva = 0x%x\n", - system_info_.csd_version_rva); - printf(" suite_mask = 0x%x\n", - system_info_.suite_mask); - if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || - system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { - printf(" cpu.x86_cpu_info (valid):\n"); - } else { - printf(" cpu.x86_cpu_info (invalid):\n"); - } - for (unsigned int i = 0; i < 3; ++i) { - printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", - i, system_info_.cpu.x86_cpu_info.vendor_id[i]); - } - printf(" cpu.x86_cpu_info.version_information = 0x%x\n", - system_info_.cpu.x86_cpu_info.version_information); - printf(" cpu.x86_cpu_info.feature_information = 0x%x\n", - system_info_.cpu.x86_cpu_info.feature_information); - printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", - system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); - if (system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86 && - system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86_WIN64) { - printf(" cpu.other_cpu_info (valid):\n"); - for (unsigned int i = 0; i < 2; ++i) { - printf(" cpu.other_cpu_info.processor_features[%d] = 0x%" PRIx64 "\n", - i, system_info_.cpu.other_cpu_info.processor_features[i]); - } - } - const string* csd_version = GetCSDVersion(); - if (csd_version) { - printf(" (csd_version) = \"%s\"\n", - csd_version->c_str()); - } else { - printf(" (csd_version) = (null)\n"); - } - const string* cpu_vendor = GetCPUVendor(); - if (cpu_vendor) { - printf(" (cpu_vendor) = \"%s\"\n", - cpu_vendor->c_str()); - } else { - printf(" (cpu_vendor) = (null)\n"); - } - printf("\n"); -} - - -// -// MinidumpMiscInfo -// - - -MinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump) - : MinidumpStream(minidump), - misc_info_() { -} - - -bool MinidumpMiscInfo::Read(uint32_t expected_size) { - valid_ = false; - - size_t padding = 0; - if (expected_size != MD_MISCINFO_SIZE && - expected_size != MD_MISCINFO2_SIZE && - expected_size != MD_MISCINFO3_SIZE && - expected_size != MD_MISCINFO4_SIZE && - expected_size != MD_MISCINFO5_SIZE) { - if (expected_size > MD_MISCINFO5_SIZE) { - // Only read the part of the misc info structure we know how to handle - BPLOG(INFO) << "MinidumpMiscInfo size larger than expected " - << expected_size << ", skipping over the unknown part"; - padding = expected_size - MD_MISCINFO5_SIZE; - expected_size = MD_MISCINFO5_SIZE; - } else { - BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size - << " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE - << ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE - << ", " << MD_MISCINFO5_SIZE << ")"; - return false; - } - } - - if (!minidump_->ReadBytes(&misc_info_, expected_size)) { - BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info"; - return false; - } - - if (padding != 0) { - off_t saved_position = minidump_->Tell(); - if (saved_position == -1) { - BPLOG(ERROR) << "MinidumpMiscInfo could not tell the current position"; - return false; - } - - if (!minidump_->SeekSet(saved_position + padding)) { - BPLOG(ERROR) << "MinidumpMiscInfo could not seek past the miscellaneous " - << "info structure"; - return false; - } - } - - if (minidump_->swap()) { - // Swap version 1 fields - Swap(&misc_info_.size_of_info); - Swap(&misc_info_.flags1); - Swap(&misc_info_.process_id); - Swap(&misc_info_.process_create_time); - Swap(&misc_info_.process_user_time); - Swap(&misc_info_.process_kernel_time); - if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { - // Swap version 2 fields - Swap(&misc_info_.processor_max_mhz); - Swap(&misc_info_.processor_current_mhz); - Swap(&misc_info_.processor_mhz_limit); - Swap(&misc_info_.processor_max_idle_state); - Swap(&misc_info_.processor_current_idle_state); - } - if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { - // Swap version 3 fields - Swap(&misc_info_.process_integrity_level); - Swap(&misc_info_.process_execute_flags); - Swap(&misc_info_.protected_process); - Swap(&misc_info_.time_zone_id); - Swap(&misc_info_.time_zone); - } - if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { - // Swap version 4 fields. - // Do not swap UTF-16 strings. The swap is done as part of the - // conversion to UTF-8 (code follows below). - } - if (misc_info_.size_of_info > MD_MISCINFO4_SIZE) { - // Swap version 5 fields - Swap(&misc_info_.xstate_data); - Swap(&misc_info_.process_cookie); - } - } - - if (expected_size + padding != misc_info_.size_of_info) { - BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << - expected_size << " != " << misc_info_.size_of_info; - return false; - } - - // Convert UTF-16 strings - if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { - // Convert UTF-16 strings in version 3 fields - ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name, - sizeof(misc_info_.time_zone.standard_name), - &standard_name_, minidump_->swap()); - ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name, - sizeof(misc_info_.time_zone.daylight_name), - &daylight_name_, minidump_->swap()); - } - if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { - // Convert UTF-16 strings in version 4 fields - ConvertUTF16BufferToUTF8String(misc_info_.build_string, - sizeof(misc_info_.build_string), - &build_string_, minidump_->swap()); - ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str, - sizeof(misc_info_.dbg_bld_str), - &dbg_bld_str_, minidump_->swap()); - } - - valid_ = true; - return true; -} - - -void MinidumpMiscInfo::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data"; - return; - } - - printf("MDRawMiscInfo\n"); - // Print version 1 fields - printf(" size_of_info = %d\n", misc_info_.size_of_info); - printf(" flags1 = 0x%x\n", misc_info_.flags1); - printf(" process_id = "); - PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID, - kNumberFormatDecimal, misc_info_.process_id); - if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES) { - printf(" process_create_time = 0x%x %s\n", - misc_info_.process_create_time, - TimeTToUTCString(misc_info_.process_create_time).c_str()); - } else { - printf(" process_create_time = (invalid)\n"); - } - printf(" process_user_time = "); - PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES, - kNumberFormatDecimal, misc_info_.process_user_time); - printf(" process_kernel_time = "); - PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES, - kNumberFormatDecimal, misc_info_.process_kernel_time); - if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { - // Print version 2 fields - printf(" processor_max_mhz = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, - kNumberFormatDecimal, misc_info_.processor_max_mhz); - printf(" processor_current_mhz = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, - kNumberFormatDecimal, misc_info_.processor_current_mhz); - printf(" processor_mhz_limit = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, - kNumberFormatDecimal, misc_info_.processor_mhz_limit); - printf(" processor_max_idle_state = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, - kNumberFormatDecimal, - misc_info_.processor_max_idle_state); - printf(" processor_current_idle_state = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, - kNumberFormatDecimal, - misc_info_.processor_current_idle_state); - } - if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { - // Print version 3 fields - printf(" process_integrity_level = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY, - kNumberFormatHexadecimal, - misc_info_.process_integrity_level); - printf(" process_execute_flags = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS, - kNumberFormatHexadecimal, - misc_info_.process_execute_flags); - printf(" protected_process = "); - PrintValueOrInvalid(misc_info_.flags1 & - MD_MISCINFO_FLAGS1_PROTECTED_PROCESS, - kNumberFormatDecimal, misc_info_.protected_process); - printf(" time_zone_id = "); - PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE, - kNumberFormatDecimal, misc_info_.time_zone_id); - if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE) { - printf(" time_zone.bias = %d\n", - misc_info_.time_zone.bias); - printf(" time_zone.standard_name = %s\n", standard_name_.c_str()); - printf(" time_zone.standard_date = " - "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n", - misc_info_.time_zone.standard_date.year, - misc_info_.time_zone.standard_date.month, - misc_info_.time_zone.standard_date.day, - misc_info_.time_zone.standard_date.day_of_week, - misc_info_.time_zone.standard_date.hour, - misc_info_.time_zone.standard_date.minute, - misc_info_.time_zone.standard_date.second, - misc_info_.time_zone.standard_date.milliseconds); - printf(" time_zone.standard_bias = %d\n", - misc_info_.time_zone.standard_bias); - printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str()); - printf(" time_zone.daylight_date = " - "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n", - misc_info_.time_zone.daylight_date.year, - misc_info_.time_zone.daylight_date.month, - misc_info_.time_zone.daylight_date.day, - misc_info_.time_zone.daylight_date.day_of_week, - misc_info_.time_zone.daylight_date.hour, - misc_info_.time_zone.daylight_date.minute, - misc_info_.time_zone.daylight_date.second, - misc_info_.time_zone.daylight_date.milliseconds); - printf(" time_zone.daylight_bias = %d\n", - misc_info_.time_zone.daylight_bias); - } else { - printf(" time_zone.bias = (invalid)\n"); - printf(" time_zone.standard_name = (invalid)\n"); - printf(" time_zone.standard_date = (invalid)\n"); - printf(" time_zone.standard_bias = (invalid)\n"); - printf(" time_zone.daylight_name = (invalid)\n"); - printf(" time_zone.daylight_date = (invalid)\n"); - printf(" time_zone.daylight_bias = (invalid)\n"); - } - } - if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { - // Print version 4 fields - if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_BUILDSTRING) { - printf(" build_string = %s\n", build_string_.c_str()); - printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str()); - } else { - printf(" build_string = (invalid)\n"); - printf(" dbg_bld_str = (invalid)\n"); - } - } - if (misc_info_.size_of_info > MD_MISCINFO4_SIZE) { - // Print version 5 fields - if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_COOKIE) { - printf(" xstate_data.size_of_info = %d\n", - misc_info_.xstate_data.size_of_info); - printf(" xstate_data.context_size = %d\n", - misc_info_.xstate_data.context_size); - printf(" xstate_data.enabled_features = 0x%" PRIx64 "\n", - misc_info_.xstate_data.enabled_features); - for (size_t i = 0; i < MD_MAXIMUM_XSTATE_FEATURES; i++) { - if (misc_info_.xstate_data.enabled_features & (1 << i)) { - printf(" xstate_data.features[%02zu] = { %d, %d }\n", i, - misc_info_.xstate_data.features[i].offset, - misc_info_.xstate_data.features[i].size); - } - } - if (misc_info_.xstate_data.enabled_features == 0) { - printf(" xstate_data.features[] = (empty)\n"); - } - printf(" process_cookie = %d\n", - misc_info_.process_cookie); - } else { - printf(" xstate_data.size_of_info = (invalid)\n"); - printf(" xstate_data.context_size = (invalid)\n"); - printf(" xstate_data.enabled_features = (invalid)\n"); - printf(" xstate_data.features[] = (invalid)\n"); - printf(" process_cookie = (invalid)\n"); - } - } - printf("\n"); -} - - -// -// MinidumpBreakpadInfo -// - - -MinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump) - : MinidumpStream(minidump), - breakpad_info_() { -} - - -bool MinidumpBreakpadInfo::Read(uint32_t expected_size) { - valid_ = false; - - if (expected_size != sizeof(breakpad_info_)) { - BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size << - " != " << sizeof(breakpad_info_); - return false; - } - - if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) { - BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info"; - return false; - } - - if (minidump_->swap()) { - Swap(&breakpad_info_.validity); - Swap(&breakpad_info_.dump_thread_id); - Swap(&breakpad_info_.requesting_thread_id); - } - - valid_ = true; - return true; -} - - -bool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const { - BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID " - "requires |thread_id|"; - assert(thread_id); - *thread_id = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID"; - return false; - } - - if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) { - BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread"; - return false; - } - - *thread_id = breakpad_info_.dump_thread_id; - return true; -} - - -bool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id) - const { - BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID " - "requires |thread_id|"; - assert(thread_id); - *thread_id = 0; - - if (!thread_id || !valid_) { - BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID"; - return false; - } - - if (!(breakpad_info_.validity & - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) { - BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread"; - return false; - } - - *thread_id = breakpad_info_.requesting_thread_id; - return true; -} - - -void MinidumpBreakpadInfo::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data"; - return; - } - - printf("MDRawBreakpadInfo\n"); - printf(" validity = 0x%x\n", breakpad_info_.validity); - printf(" dump_thread_id = "); - PrintValueOrInvalid(breakpad_info_.validity & - MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID, - kNumberFormatHexadecimal, breakpad_info_.dump_thread_id); - printf(" requesting_thread_id = "); - PrintValueOrInvalid(breakpad_info_.validity & - MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID, - kNumberFormatHexadecimal, - breakpad_info_.requesting_thread_id); - - printf("\n"); -} - - -// -// MinidumpMemoryInfo -// - - -MinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump) - : MinidumpObject(minidump), - memory_info_() { -} - - -bool MinidumpMemoryInfo::IsExecutable() const { - uint32_t protection = - memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; - return protection == MD_MEMORY_PROTECT_EXECUTE || - protection == MD_MEMORY_PROTECT_EXECUTE_READ || - protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE; -} - - -bool MinidumpMemoryInfo::IsWritable() const { - uint32_t protection = - memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; - return protection == MD_MEMORY_PROTECT_READWRITE || - protection == MD_MEMORY_PROTECT_WRITECOPY || - protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE || - protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY; -} - - -bool MinidumpMemoryInfo::Read() { - valid_ = false; - - if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) { - BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info"; - return false; - } - - if (minidump_->swap()) { - Swap(&memory_info_.base_address); - Swap(&memory_info_.allocation_base); - Swap(&memory_info_.allocation_protection); - Swap(&memory_info_.region_size); - Swap(&memory_info_.state); - Swap(&memory_info_.protection); - Swap(&memory_info_.type); - } - - // Check for base + size overflow or undersize. - if (memory_info_.region_size == 0 || - memory_info_.region_size > numeric_limits::max() - - memory_info_.base_address) { - BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " << - HexString(memory_info_.base_address) << "+" << - HexString(memory_info_.region_size); - return false; - } - - valid_ = true; - return true; -} - - -void MinidumpMemoryInfo::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data"; - return; - } - - printf("MDRawMemoryInfo\n"); - printf(" base_address = 0x%" PRIx64 "\n", - memory_info_.base_address); - printf(" allocation_base = 0x%" PRIx64 "\n", - memory_info_.allocation_base); - printf(" allocation_protection = 0x%x\n", - memory_info_.allocation_protection); - printf(" region_size = 0x%" PRIx64 "\n", memory_info_.region_size); - printf(" state = 0x%x\n", memory_info_.state); - printf(" protection = 0x%x\n", memory_info_.protection); - printf(" type = 0x%x\n", memory_info_.type); -} - - -// -// MinidumpMemoryInfoList -// - - -MinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) - : MinidumpStream(minidump), - range_map_(new RangeMap()), - infos_(NULL), - info_count_(0) { -} - - -MinidumpMemoryInfoList::~MinidumpMemoryInfoList() { - delete range_map_; - delete infos_; -} - - -bool MinidumpMemoryInfoList::Read(uint32_t expected_size) { - // Invalidate cached data. - delete infos_; - infos_ = NULL; - range_map_->Clear(); - info_count_ = 0; - - valid_ = false; - - MDRawMemoryInfoList header; - if (expected_size < sizeof(MDRawMemoryInfoList)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << - expected_size << " < " << sizeof(MDRawMemoryInfoList); - return false; - } - if (!minidump_->ReadBytes(&header, sizeof(header))) { - BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header"; - return false; - } - - if (minidump_->swap()) { - Swap(&header.size_of_header); - Swap(&header.size_of_entry); - Swap(&header.number_of_entries); - } - - // Sanity check that the header is the expected size. - // TODO(ted): could possibly handle this more gracefully, assuming - // that future versions of the structs would be backwards-compatible. - if (header.size_of_header != sizeof(MDRawMemoryInfoList)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << - header.size_of_header << " != " << - sizeof(MDRawMemoryInfoList); - return false; - } - - // Sanity check that the entries are the expected size. - if (header.size_of_entry != sizeof(MDRawMemoryInfo)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " << - header.size_of_entry << " != " << - sizeof(MDRawMemoryInfo); - return false; - } - - if (header.number_of_entries > - numeric_limits::max() / sizeof(MDRawMemoryInfo)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList info count " << - header.number_of_entries << - " would cause multiplication overflow"; - return false; - } - - if (expected_size != sizeof(MDRawMemoryInfoList) + - header.number_of_entries * sizeof(MDRawMemoryInfo)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size << - " != " << sizeof(MDRawMemoryInfoList) + - header.number_of_entries * sizeof(MDRawMemoryInfo); - return false; - } - - // Check for data loss when converting header.number_of_entries from - // uint64_t into MinidumpMemoryInfos::size_type (uint32_t) - MinidumpMemoryInfos::size_type header_number_of_entries = - static_cast(header.number_of_entries); - if (static_cast(header_number_of_entries) != - header.number_of_entries) { - BPLOG(ERROR) << "Data loss detected when converting " - "the header's number_of_entries"; - return false; - } - - if (header.number_of_entries != 0) { - scoped_ptr infos( - new MinidumpMemoryInfos(header_number_of_entries, - MinidumpMemoryInfo(minidump_))); - - for (unsigned int index = 0; - index < header.number_of_entries; - ++index) { - MinidumpMemoryInfo* info = &(*infos)[index]; - - // Assume that the file offset is correct after the last read. - if (!info->Read()) { - BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " << - index << "/" << header.number_of_entries; - return false; - } - - uint64_t base_address = info->GetBase(); - uint64_t region_size = info->GetSize(); - - if (!range_map_->StoreRange(base_address, region_size, index)) { - BPLOG(ERROR) << "MinidumpMemoryInfoList could not store" - " memory region " << - index << "/" << header.number_of_entries << ", " << - HexString(base_address) << "+" << - HexString(region_size); - return false; - } - } - - infos_ = infos.release(); - } - - info_count_ = header_number_of_entries; - - valid_ = true; - return true; -} - - -const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( - unsigned int index) const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; - return NULL; - } - - if (index >= info_count_) { - BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << - index << "/" << info_count_; - return NULL; - } - - return &(*infos_)[index]; -} - - -const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( - uint64_t address) const { - if (!valid_) { - BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" - " GetMemoryInfoForAddress"; - return NULL; - } - - unsigned int info_index; - if (!range_map_->RetrieveRange(address, &info_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { - BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << - HexString(address); - return NULL; - } - - return GetMemoryInfoAtIndex(info_index); -} - - -void MinidumpMemoryInfoList::Print() { - if (!valid_) { - BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data"; - return; - } - - printf("MinidumpMemoryInfoList\n"); - printf(" info_count = %d\n", info_count_); - printf("\n"); - - for (unsigned int info_index = 0; - info_index < info_count_; - ++info_index) { - printf("info[%d]\n", info_index); - (*infos_)[info_index].Print(); - printf("\n"); - } -} - -// -// MinidumpLinuxMaps -// - -MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump *minidump) - : MinidumpObject(minidump) { -} - -void MinidumpLinuxMaps::Print() const { - if (!valid_) { - BPLOG(ERROR) << "MinidumpLinuxMaps cannot print invalid data"; - return; - } - std::cout << region_.line << std::endl; -} - -// -// MinidumpLinuxMapsList -// - -MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump *minidump) - : MinidumpStream(minidump), - maps_(NULL), - maps_count_(0) { -} - -MinidumpLinuxMapsList::~MinidumpLinuxMapsList() { - if (maps_) { - for (unsigned int i = 0; i < maps_->size(); i++) { - delete (*maps_)[i]; - } - delete maps_; - } -} - -const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsForAddress( - uint64_t address) const { - if (!valid_ || (maps_ == NULL)) { - BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress"; - return NULL; - } - - // Search every memory mapping. - for (unsigned int index = 0; index < maps_count_; index++) { - // Check if address is within bounds of the current memory region. - if ((*maps_)[index]->GetBase() <= address && - (*maps_)[index]->GetBase() + (*maps_)[index]->GetSize() > address) { - return (*maps_)[index]; - } - } - - // No mapping encloses the memory address. - BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at " - << HexString(address); - return NULL; -} - -const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsAtIndex( - unsigned int index) const { - if (!valid_ || (maps_ == NULL)) { - BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex"; - return NULL; - } - - // Index out of bounds. - if (index >= maps_count_ || (maps_ == NULL)) { - BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: " - << index - << "/" - << maps_count_; - return NULL; - } - return (*maps_)[index]; -} - -bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { - // Invalidate cached data. - if (maps_) { - for (unsigned int i = 0; i < maps_->size(); i++) { - delete (*maps_)[i]; - } - delete maps_; - } - maps_ = NULL; - maps_count_ = 0; - - valid_ = false; - - // Load and check expected stream length. - uint32_t length = 0; - if (!minidump_->SeekToStreamType(MD_LINUX_MAPS, &length)) { - BPLOG(ERROR) << "MinidumpLinuxMapsList stream type not found"; - return false; - } - if (expected_size != length) { - BPLOG(ERROR) << "MinidumpLinuxMapsList size mismatch: " - << expected_size - << " != " - << length; - return false; - } - - // Create a vector to read stream data. The vector needs to have - // at least enough capacity to read all the data. - vector mapping_bytes(length); - if (!minidump_->ReadBytes(&mapping_bytes[0], length)) { - BPLOG(ERROR) << "MinidumpLinuxMapsList failed to read bytes"; - return false; - } - string map_string(mapping_bytes.begin(), mapping_bytes.end()); - vector all_regions; - - // Parse string into mapping data. - if (!ParseProcMaps(map_string, &all_regions)) { - return false; - } - - scoped_ptr maps(new MinidumpLinuxMappings()); - - // Push mapping data into wrapper classes. - for (size_t i = 0; i < all_regions.size(); i++) { - scoped_ptr ele(new MinidumpLinuxMaps(minidump_)); - ele->region_ = all_regions[i]; - ele->valid_ = true; - maps->push_back(ele.release()); - } - - // Set instance variables. - maps_ = maps.release(); - maps_count_ = maps_->size(); - valid_ = true; - return true; -} - -void MinidumpLinuxMapsList::Print() const { - if (!valid_ || (maps_ == NULL)) { - BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data"; - return; - } - for (size_t i = 0; i < maps_->size(); i++) { - (*maps_)[i]->Print(); - } -} - -// -// Minidump -// - - -uint32_t Minidump::max_streams_ = 128; -unsigned int Minidump::max_string_length_ = 1024; - - -Minidump::Minidump(const string& path) - : header_(), - directory_(NULL), - stream_map_(new MinidumpStreamMap()), - path_(path), - stream_(NULL), - swap_(false), - valid_(false) { -} - -Minidump::Minidump(istream& stream) - : header_(), - directory_(NULL), - stream_map_(new MinidumpStreamMap()), - path_(), - stream_(&stream), - swap_(false), - valid_(false) { -} - -Minidump::~Minidump() { - if (stream_) { - BPLOG(INFO) << "Minidump closing minidump"; - } - if (!path_.empty()) { - delete stream_; - } - delete directory_; - delete stream_map_; -} - - -bool Minidump::Open() { - if (stream_ != NULL) { - BPLOG(INFO) << "Minidump reopening minidump " << path_; - - // The file is already open. Seek to the beginning, which is the position - // the file would be at if it were opened anew. - return SeekSet(0); - } - - stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); - if (!stream_ || !stream_->good()) { - string error_string; - int error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "Minidump could not open minidump " << path_ << - ", error " << error_code << ": " << error_string; - return false; - } - - BPLOG(INFO) << "Minidump opened minidump " << path_; - return true; -} - -bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) { - // Initialize output parameters - *context_cpu_flags = 0; - - // Save the current stream position - off_t saved_position = Tell(); - if (saved_position == -1) { - // Failed to save the current stream position. - // Returns true because the current position of the stream is preserved. - return true; - } - - const MDRawSystemInfo* system_info = - GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; - - if (system_info != NULL) { - switch (system_info->processor_architecture) { - case MD_CPU_ARCHITECTURE_X86: - *context_cpu_flags = MD_CONTEXT_X86; - break; - case MD_CPU_ARCHITECTURE_MIPS: - *context_cpu_flags = MD_CONTEXT_MIPS; - break; - case MD_CPU_ARCHITECTURE_MIPS64: - *context_cpu_flags = MD_CONTEXT_MIPS64; - break; - case MD_CPU_ARCHITECTURE_ALPHA: - *context_cpu_flags = MD_CONTEXT_ALPHA; - break; - case MD_CPU_ARCHITECTURE_PPC: - *context_cpu_flags = MD_CONTEXT_PPC; - break; - case MD_CPU_ARCHITECTURE_PPC64: - *context_cpu_flags = MD_CONTEXT_PPC64; - break; - case MD_CPU_ARCHITECTURE_SHX: - *context_cpu_flags = MD_CONTEXT_SHX; - break; - case MD_CPU_ARCHITECTURE_ARM: - *context_cpu_flags = MD_CONTEXT_ARM; - break; - case MD_CPU_ARCHITECTURE_ARM64: - *context_cpu_flags = MD_CONTEXT_ARM64; - break; - case MD_CPU_ARCHITECTURE_IA64: - *context_cpu_flags = MD_CONTEXT_IA64; - break; - case MD_CPU_ARCHITECTURE_ALPHA64: - *context_cpu_flags = 0; - break; - case MD_CPU_ARCHITECTURE_MSIL: - *context_cpu_flags = 0; - break; - case MD_CPU_ARCHITECTURE_AMD64: - *context_cpu_flags = MD_CONTEXT_AMD64; - break; - case MD_CPU_ARCHITECTURE_X86_WIN64: - *context_cpu_flags = 0; - break; - case MD_CPU_ARCHITECTURE_SPARC: - *context_cpu_flags = MD_CONTEXT_SPARC; - break; - case MD_CPU_ARCHITECTURE_UNKNOWN: - *context_cpu_flags = 0; - break; - default: - *context_cpu_flags = 0; - break; - } - } - - // Restore position and return - return SeekSet(saved_position); -} - - -bool Minidump::Read() { - // Invalidate cached data. - delete directory_; - directory_ = NULL; - stream_map_->clear(); - - valid_ = false; - - if (!Open()) { - BPLOG(ERROR) << "Minidump cannot open minidump"; - return false; - } - - if (!ReadBytes(&header_, sizeof(MDRawHeader))) { - BPLOG(ERROR) << "Minidump cannot read header"; - return false; - } - - if (header_.signature != MD_HEADER_SIGNATURE) { - // The file may be byte-swapped. Under the present architecture, these - // classes don't know or need to know what CPU (or endianness) the - // minidump was produced on in order to parse it. Use the signature as - // a byte order marker. - uint32_t signature_swapped = header_.signature; - Swap(&signature_swapped); - if (signature_swapped != MD_HEADER_SIGNATURE) { - // This isn't a minidump or a byte-swapped minidump. - BPLOG(ERROR) << "Minidump header signature mismatch: (" << - HexString(header_.signature) << ", " << - HexString(signature_swapped) << ") != " << - HexString(MD_HEADER_SIGNATURE); - return false; - } - swap_ = true; - } else { - // The file is not byte-swapped. Set swap_ false (it may have been true - // if the object is being reused?) - swap_ = false; - } - - BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") << - "byte-swapping minidump"; - - if (swap_) { - Swap(&header_.signature); - Swap(&header_.version); - Swap(&header_.stream_count); - Swap(&header_.stream_directory_rva); - Swap(&header_.checksum); - Swap(&header_.time_date_stamp); - Swap(&header_.flags); - } - - // Version check. The high 16 bits of header_.version contain something - // else "implementation specific." - if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) { - BPLOG(ERROR) << "Minidump version mismatch: " << - HexString(header_.version & 0x0000ffff) << " != " << - HexString(MD_HEADER_VERSION); - return false; - } - - if (!SeekSet(header_.stream_directory_rva)) { - BPLOG(ERROR) << "Minidump cannot seek to stream directory"; - return false; - } - - if (header_.stream_count > max_streams_) { - BPLOG(ERROR) << "Minidump stream count " << header_.stream_count << - " exceeds maximum " << max_streams_; - return false; - } - - if (header_.stream_count != 0) { - scoped_ptr directory( - new MinidumpDirectoryEntries(header_.stream_count)); - - // Read the entire array in one fell swoop, instead of reading one entry - // at a time in the loop. - if (!ReadBytes(&(*directory)[0], - sizeof(MDRawDirectory) * header_.stream_count)) { - BPLOG(ERROR) << "Minidump cannot read stream directory"; - return false; - } - - for (unsigned int stream_index = 0; - stream_index < header_.stream_count; - ++stream_index) { - MDRawDirectory* directory_entry = &(*directory)[stream_index]; - - if (swap_) { - Swap(&directory_entry->stream_type); - Swap(&directory_entry->location); - } - - // Initialize the stream_map_ map, which speeds locating a stream by - // type. - unsigned int stream_type = directory_entry->stream_type; - switch (stream_type) { - case MD_THREAD_LIST_STREAM: - case MD_MODULE_LIST_STREAM: - case MD_MEMORY_LIST_STREAM: - case MD_EXCEPTION_STREAM: - case MD_SYSTEM_INFO_STREAM: - case MD_MISC_INFO_STREAM: - case MD_BREAKPAD_INFO_STREAM: { - if (stream_map_->find(stream_type) != stream_map_->end()) { - // Another stream with this type was already found. A minidump - // file should contain at most one of each of these stream types. - BPLOG(ERROR) << "Minidump found multiple streams of type " << - stream_type << ", but can only deal with one"; - return false; - } - // Fall through to default - } - - default: { - // Overwrites for stream types other than those above, but it's - // expected to be the user's burden in that case. - (*stream_map_)[stream_type].stream_index = stream_index; - } - } - } - - directory_ = directory.release(); - } - - valid_ = true; - return true; -} - - -MinidumpThreadList* Minidump::GetThreadList() { - MinidumpThreadList* thread_list; - return GetStream(&thread_list); -} - - -MinidumpModuleList* Minidump::GetModuleList() { - MinidumpModuleList* module_list; - return GetStream(&module_list); -} - - -MinidumpMemoryList* Minidump::GetMemoryList() { - MinidumpMemoryList* memory_list; - return GetStream(&memory_list); -} - - -MinidumpException* Minidump::GetException() { - MinidumpException* exception; - return GetStream(&exception); -} - -MinidumpAssertion* Minidump::GetAssertion() { - MinidumpAssertion* assertion; - return GetStream(&assertion); -} - - -MinidumpSystemInfo* Minidump::GetSystemInfo() { - MinidumpSystemInfo* system_info; - return GetStream(&system_info); -} - - -MinidumpMiscInfo* Minidump::GetMiscInfo() { - MinidumpMiscInfo* misc_info; - return GetStream(&misc_info); -} - - -MinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { - MinidumpBreakpadInfo* breakpad_info; - return GetStream(&breakpad_info); -} - -MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { - MinidumpMemoryInfoList* memory_info_list; - return GetStream(&memory_info_list); -} - -MinidumpLinuxMapsList *Minidump::GetLinuxMapsList() { - MinidumpLinuxMapsList *linux_maps_list; - return GetStream(&linux_maps_list); -} - -bool Minidump::IsAndroid() { - // Save the current stream position - off_t saved_position = Tell(); - if (saved_position == -1) { - return false; - } - const MDRawSystemInfo* system_info = - GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; - - // Restore position and return - if (!SeekSet(saved_position)) { - BPLOG(ERROR) << "Couldn't seek back to saved position"; - return false; - } - - return system_info && system_info->platform_id == MD_OS_ANDROID; -} - -static const char* get_stream_name(uint32_t stream_type) { - switch (stream_type) { - case MD_UNUSED_STREAM: - return "MD_UNUSED_STREAM"; - case MD_RESERVED_STREAM_0: - return "MD_RESERVED_STREAM_0"; - case MD_RESERVED_STREAM_1: - return "MD_RESERVED_STREAM_1"; - case MD_THREAD_LIST_STREAM: - return "MD_THREAD_LIST_STREAM"; - case MD_MODULE_LIST_STREAM: - return "MD_MODULE_LIST_STREAM"; - case MD_MEMORY_LIST_STREAM: - return "MD_MEMORY_LIST_STREAM"; - case MD_EXCEPTION_STREAM: - return "MD_EXCEPTION_STREAM"; - case MD_SYSTEM_INFO_STREAM: - return "MD_SYSTEM_INFO_STREAM"; - case MD_THREAD_EX_LIST_STREAM: - return "MD_THREAD_EX_LIST_STREAM"; - case MD_MEMORY_64_LIST_STREAM: - return "MD_MEMORY_64_LIST_STREAM"; - case MD_COMMENT_STREAM_A: - return "MD_COMMENT_STREAM_A"; - case MD_COMMENT_STREAM_W: - return "MD_COMMENT_STREAM_W"; - case MD_HANDLE_DATA_STREAM: - return "MD_HANDLE_DATA_STREAM"; - case MD_FUNCTION_TABLE_STREAM: - return "MD_FUNCTION_TABLE_STREAM"; - case MD_UNLOADED_MODULE_LIST_STREAM: - return "MD_UNLOADED_MODULE_LIST_STREAM"; - case MD_MISC_INFO_STREAM: - return "MD_MISC_INFO_STREAM"; - case MD_MEMORY_INFO_LIST_STREAM: - return "MD_MEMORY_INFO_LIST_STREAM"; - case MD_THREAD_INFO_LIST_STREAM: - return "MD_THREAD_INFO_LIST_STREAM"; - case MD_HANDLE_OPERATION_LIST_STREAM: - return "MD_HANDLE_OPERATION_LIST_STREAM"; - case MD_TOKEN_STREAM: - return "MD_TOKEN_STREAM"; - case MD_JAVASCRIPT_DATA_STREAM: - return "MD_JAVASCRIPT_DATA_STREAM"; - case MD_SYSTEM_MEMORY_INFO_STREAM: - return "MD_SYSTEM_MEMORY_INFO_STREAM"; - case MD_PROCESS_VM_COUNTERS_STREAM: - return "MD_PROCESS_VM_COUNTERS_STREAM"; - case MD_LAST_RESERVED_STREAM: - return "MD_LAST_RESERVED_STREAM"; - case MD_BREAKPAD_INFO_STREAM: - return "MD_BREAKPAD_INFO_STREAM"; - case MD_ASSERTION_INFO_STREAM: - return "MD_ASSERTION_INFO_STREAM"; - case MD_LINUX_CPU_INFO: - return "MD_LINUX_CPU_INFO"; - case MD_LINUX_PROC_STATUS: - return "MD_LINUX_PROC_STATUS"; - case MD_LINUX_LSB_RELEASE: - return "MD_LINUX_LSB_RELEASE"; - case MD_LINUX_CMD_LINE: - return "MD_LINUX_CMD_LINE"; - case MD_LINUX_ENVIRON: - return "MD_LINUX_ENVIRON"; - case MD_LINUX_AUXV: - return "MD_LINUX_AUXV"; - case MD_LINUX_MAPS: - return "MD_LINUX_MAPS"; - case MD_LINUX_DSO_DEBUG: - return "MD_LINUX_DSO_DEBUG"; - default: - return "unknown"; - } -} - -void Minidump::Print() { - if (!valid_) { - BPLOG(ERROR) << "Minidump cannot print invalid data"; - return; - } - - printf("MDRawHeader\n"); - printf(" signature = 0x%x\n", header_.signature); - printf(" version = 0x%x\n", header_.version); - printf(" stream_count = %d\n", header_.stream_count); - printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); - printf(" checksum = 0x%x\n", header_.checksum); - printf(" time_date_stamp = 0x%x %s\n", - header_.time_date_stamp, - TimeTToUTCString(header_.time_date_stamp).c_str()); - printf(" flags = 0x%" PRIx64 "\n", header_.flags); - printf("\n"); - - for (unsigned int stream_index = 0; - stream_index < header_.stream_count; - ++stream_index) { - MDRawDirectory* directory_entry = &(*directory_)[stream_index]; - - printf("mDirectory[%d]\n", stream_index); - printf("MDRawDirectory\n"); - printf(" stream_type = 0x%x (%s)\n", directory_entry->stream_type, - get_stream_name(directory_entry->stream_type)); - printf(" location.data_size = %d\n", - directory_entry->location.data_size); - printf(" location.rva = 0x%x\n", directory_entry->location.rva); - printf("\n"); - } - - printf("Streams:\n"); - for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin(); - iterator != stream_map_->end(); - ++iterator) { - uint32_t stream_type = iterator->first; - const MinidumpStreamInfo& info = iterator->second; - printf(" stream type 0x%x (%s) at index %d\n", stream_type, - get_stream_name(stream_type), - info.stream_index); - } - printf("\n"); -} - - -const MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) - const { - if (!valid_) { - BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; - return NULL; - } - - if (index >= header_.stream_count) { - BPLOG(ERROR) << "Minidump stream directory index out of range: " << - index << "/" << header_.stream_count; - return NULL; - } - - return &(*directory_)[index]; -} - - -bool Minidump::ReadBytes(void* bytes, size_t count) { - // Can't check valid_ because Read needs to call this method before - // validity can be determined. - if (!stream_) { - return false; - } - stream_->read(static_cast(bytes), count); - std::streamsize bytes_read = stream_->gcount(); - if (bytes_read == -1) { - string error_string; - int error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string; - return false; - } - - // Convert to size_t and check for data loss - size_t bytes_read_converted = static_cast(bytes_read); - if (static_cast(bytes_read_converted) != bytes_read) { - BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting " - << bytes_read << " to " << bytes_read_converted; - return false; - } - - if (bytes_read_converted != count) { - BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count; - return false; - } - - return true; -} - - -bool Minidump::SeekSet(off_t offset) { - // Can't check valid_ because Read needs to call this method before - // validity can be determined. - if (!stream_) { - return false; - } - stream_->seekg(offset, std::ios_base::beg); - if (!stream_->good()) { - string error_string; - int error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; - return false; - } - return true; -} - -off_t Minidump::Tell() { - if (!valid_ || !stream_) { - return (off_t)-1; - } - - // Check for conversion data loss - std::streamoff std_streamoff = stream_->tellg(); - off_t rv = static_cast(std_streamoff); - if (static_cast(rv) == std_streamoff) { - return rv; - } else { - BPLOG(ERROR) << "Data loss detected"; - return (off_t)-1; - } -} - - -string* Minidump::ReadString(off_t offset) { - if (!valid_) { - BPLOG(ERROR) << "Invalid Minidump for ReadString"; - return NULL; - } - if (!SeekSet(offset)) { - BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; - return NULL; - } - - uint32_t bytes; - if (!ReadBytes(&bytes, sizeof(bytes))) { - BPLOG(ERROR) << "ReadString could not read string size at offset " << - offset; - return NULL; - } - if (swap_) - Swap(&bytes); - - if (bytes % 2 != 0) { - BPLOG(ERROR) << "ReadString found odd-sized " << bytes << - "-byte string at offset " << offset; - return NULL; - } - unsigned int utf16_words = bytes / 2; - - if (utf16_words > max_string_length_) { - BPLOG(ERROR) << "ReadString string length " << utf16_words << - " exceeds maximum " << max_string_length_ << - " at offset " << offset; - return NULL; - } - - vector string_utf16(utf16_words); - - if (utf16_words) { - if (!ReadBytes(&string_utf16[0], bytes)) { - BPLOG(ERROR) << "ReadString could not read " << bytes << - "-byte string at offset " << offset; - return NULL; - } - } - - return UTF16ToUTF8(string_utf16, swap_); -} - - -bool Minidump::SeekToStreamType(uint32_t stream_type, - uint32_t* stream_length) { - BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires " - "|stream_length|"; - assert(stream_length); - *stream_length = 0; - - if (!valid_) { - BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType"; - return false; - } - - MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type); - if (iterator == stream_map_->end()) { - // This stream type didn't exist in the directory. - BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present"; - return false; - } - - const MinidumpStreamInfo& info = iterator->second; - if (info.stream_index >= header_.stream_count) { - BPLOG(ERROR) << "SeekToStreamType: type " << stream_type << - " out of range: " << - info.stream_index << "/" << header_.stream_count; - return false; - } - - MDRawDirectory* directory_entry = &(*directory_)[info.stream_index]; - if (!SeekSet(directory_entry->location.rva)) { - BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " << - stream_type; - return false; - } - - *stream_length = directory_entry->location.data_size; - - return true; -} - - -template -T* Minidump::GetStream(T** stream) { - // stream is a garbage parameter that's present only to account for C++'s - // inability to overload a method based solely on its return type. - - const uint32_t stream_type = T::kStreamType; - - BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << - " requires |stream|"; - assert(stream); - *stream = NULL; - - if (!valid_) { - BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; - return NULL; - } - - MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); - if (iterator == stream_map_->end()) { - // This stream type didn't exist in the directory. - BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; - return NULL; - } - - // Get a pointer so that the stored stream field can be altered. - MinidumpStreamInfo* info = &iterator->second; - - if (info->stream) { - // This cast is safe because info.stream is only populated by this - // method, and there is a direct correlation between T and stream_type. - *stream = static_cast(info->stream); - return *stream; - } - - uint32_t stream_length; - if (!SeekToStreamType(stream_type, &stream_length)) { - BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; - return NULL; - } - - scoped_ptr new_stream(new T(this)); - - if (!new_stream->Read(stream_length)) { - BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; - return NULL; - } - - *stream = new_stream.release(); - info->stream = *stream; - return *stream; -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump.cc deleted file mode 100644 index 343f04428..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump.cc +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_dump.cc: Print the contents of a minidump file in somewhat -// readable text. -// -// Author: Mark Mentovai - -#include -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/minidump.h" -#include "processor/logging.h" - -namespace { - -using google_breakpad::Minidump; -using google_breakpad::MinidumpThreadList; -using google_breakpad::MinidumpModuleList; -using google_breakpad::MinidumpMemoryInfoList; -using google_breakpad::MinidumpMemoryList; -using google_breakpad::MinidumpException; -using google_breakpad::MinidumpAssertion; -using google_breakpad::MinidumpSystemInfo; -using google_breakpad::MinidumpMiscInfo; -using google_breakpad::MinidumpBreakpadInfo; - -static void DumpRawStream(Minidump *minidump, - uint32_t stream_type, - const char *stream_name, - int *errors) { - uint32_t length = 0; - if (!minidump->SeekToStreamType(stream_type, &length)) { - return; - } - - printf("Stream %s:\n", stream_name); - - if (length == 0) { - printf("\n"); - return; - } - std::vector contents(length); - if (!minidump->ReadBytes(&contents[0], length)) { - ++*errors; - BPLOG(ERROR) << "minidump.ReadBytes failed"; - return; - } - size_t current_offset = 0; - while (current_offset < length) { - size_t remaining = length - current_offset; - // Printf requires an int and direct casting from size_t results - // in compatibility warnings. - uint32_t int_remaining = remaining; - printf("%.*s", int_remaining, &contents[current_offset]); - char *next_null = reinterpret_cast( - memchr(&contents[current_offset], 0, remaining)); - if (next_null == NULL) - break; - printf("\\0\n"); - size_t null_offset = next_null - &contents[0]; - current_offset = null_offset + 1; - } - printf("\n\n"); -} - -static bool PrintMinidumpDump(const char *minidump_file) { - Minidump minidump(minidump_file); - if (!minidump.Read()) { - BPLOG(ERROR) << "minidump.Read() failed"; - return false; - } - minidump.Print(); - - int errors = 0; - - MinidumpThreadList *thread_list = minidump.GetThreadList(); - if (!thread_list) { - ++errors; - BPLOG(ERROR) << "minidump.GetThreadList() failed"; - } else { - thread_list->Print(); - } - - MinidumpModuleList *module_list = minidump.GetModuleList(); - if (!module_list) { - ++errors; - BPLOG(ERROR) << "minidump.GetModuleList() failed"; - } else { - module_list->Print(); - } - - MinidumpMemoryList *memory_list = minidump.GetMemoryList(); - if (!memory_list) { - ++errors; - BPLOG(ERROR) << "minidump.GetMemoryList() failed"; - } else { - memory_list->Print(); - } - - MinidumpException *exception = minidump.GetException(); - if (!exception) { - BPLOG(INFO) << "minidump.GetException() failed"; - } else { - exception->Print(); - } - - MinidumpAssertion *assertion = minidump.GetAssertion(); - if (!assertion) { - BPLOG(INFO) << "minidump.GetAssertion() failed"; - } else { - assertion->Print(); - } - - MinidumpSystemInfo *system_info = minidump.GetSystemInfo(); - if (!system_info) { - ++errors; - BPLOG(ERROR) << "minidump.GetSystemInfo() failed"; - } else { - system_info->Print(); - } - - MinidumpMiscInfo *misc_info = minidump.GetMiscInfo(); - if (!misc_info) { - ++errors; - BPLOG(ERROR) << "minidump.GetMiscInfo() failed"; - } else { - misc_info->Print(); - } - - MinidumpBreakpadInfo *breakpad_info = minidump.GetBreakpadInfo(); - if (!breakpad_info) { - // Breakpad info is optional, so don't treat this as an error. - BPLOG(INFO) << "minidump.GetBreakpadInfo() failed"; - } else { - breakpad_info->Print(); - } - - MinidumpMemoryInfoList *memory_info_list = minidump.GetMemoryInfoList(); - if (!memory_info_list) { - ++errors; - BPLOG(ERROR) << "minidump.GetMemoryInfoList() failed"; - } else { - memory_info_list->Print(); - } - - DumpRawStream(&minidump, - MD_LINUX_CMD_LINE, - "MD_LINUX_CMD_LINE", - &errors); - DumpRawStream(&minidump, - MD_LINUX_ENVIRON, - "MD_LINUX_ENVIRON", - &errors); - DumpRawStream(&minidump, - MD_LINUX_LSB_RELEASE, - "MD_LINUX_LSB_RELEASE", - &errors); - DumpRawStream(&minidump, - MD_LINUX_PROC_STATUS, - "MD_LINUX_PROC_STATUS", - &errors); - DumpRawStream(&minidump, - MD_LINUX_CPU_INFO, - "MD_LINUX_CPU_INFO", - &errors); - DumpRawStream(&minidump, - MD_LINUX_MAPS, - "MD_LINUX_MAPS", - &errors); - - return errors == 0; -} - -} // namespace - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - if (argc != 2) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 1; - } - - return PrintMinidumpDump(argv[1]) ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump_test b/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump_test deleted file mode 100755 index fb62ace73..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_dump_test +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2006, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -testdata_dir=$srcdir/src/processor/testdata -./src/processor/minidump_dump $testdata_dir/minidump2.dmp | \ - tr -d '\015' | \ - diff -u $testdata_dir/minidump2.dump.out - -exit $? diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc deleted file mode 100644 index 33b4a1284..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc +++ /dev/null @@ -1,1577 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "google_breakpad/processor/minidump_processor.h" - -#include - -#include - -#include "common/scoped_ptr.h" -#include "common/stdio_wrapper.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/exploitability.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "processor/logging.h" -#include "processor/stackwalker_x86.h" -#include "processor/symbolic_constants_win.h" - -namespace google_breakpad { - -MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier, - SourceLineResolverInterface *resolver) - : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)), - own_frame_symbolizer_(true), - enable_exploitability_(false), - enable_objdump_(false) { -} - -MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier, - SourceLineResolverInterface *resolver, - bool enable_exploitability) - : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)), - own_frame_symbolizer_(true), - enable_exploitability_(enable_exploitability), - enable_objdump_(false) { -} - -MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer *frame_symbolizer, - bool enable_exploitability) - : frame_symbolizer_(frame_symbolizer), - own_frame_symbolizer_(false), - enable_exploitability_(enable_exploitability), - enable_objdump_(false) { - assert(frame_symbolizer_); -} - -MinidumpProcessor::~MinidumpProcessor() { - if (own_frame_symbolizer_) delete frame_symbolizer_; -} - -ProcessResult MinidumpProcessor::Process( - Minidump *dump, ProcessState *process_state) { - assert(dump); - assert(process_state); - - process_state->Clear(); - - const MDRawHeader *header = dump->header(); - if (!header) { - BPLOG(ERROR) << "Minidump " << dump->path() << " has no header"; - return PROCESS_ERROR_NO_MINIDUMP_HEADER; - } - process_state->time_date_stamp_ = header->time_date_stamp; - - bool has_process_create_time = - GetProcessCreateTime(dump, &process_state->process_create_time_); - - bool has_cpu_info = GetCPUInfo(dump, &process_state->system_info_); - bool has_os_info = GetOSInfo(dump, &process_state->system_info_); - - uint32_t dump_thread_id = 0; - bool has_dump_thread = false; - uint32_t requesting_thread_id = 0; - bool has_requesting_thread = false; - - MinidumpBreakpadInfo *breakpad_info = dump->GetBreakpadInfo(); - if (breakpad_info) { - has_dump_thread = breakpad_info->GetDumpThreadID(&dump_thread_id); - has_requesting_thread = - breakpad_info->GetRequestingThreadID(&requesting_thread_id); - } - - MinidumpException *exception = dump->GetException(); - if (exception) { - process_state->crashed_ = true; - has_requesting_thread = exception->GetThreadID(&requesting_thread_id); - - process_state->crash_reason_ = GetCrashReason( - dump, &process_state->crash_address_); - } - - // This will just return an empty string if it doesn't exist. - process_state->assertion_ = GetAssertion(dump); - - MinidumpModuleList *module_list = dump->GetModuleList(); - - // Put a copy of the module list into ProcessState object. This is not - // necessarily a MinidumpModuleList, but it adheres to the CodeModules - // interface, which is all that ProcessState needs to expose. - if (module_list) { - process_state->modules_ = module_list->Copy(); - process_state->shrunk_range_modules_ = - process_state->modules_->GetShrunkRangeModules(); - for (unsigned int i = 0; - i < process_state->shrunk_range_modules_.size(); - i++) { - linked_ptr module = - process_state->shrunk_range_modules_[i]; - BPLOG(INFO) << "The range for module " << module->code_file() - << " was shrunk down by " << HexString( - module->shrink_down_delta()) << " bytes. "; - } - } - - MinidumpMemoryList *memory_list = dump->GetMemoryList(); - if (memory_list) { - BPLOG(INFO) << "Found " << memory_list->region_count() - << " memory regions."; - } - - MinidumpThreadList *threads = dump->GetThreadList(); - if (!threads) { - BPLOG(ERROR) << "Minidump " << dump->path() << " has no thread list"; - return PROCESS_ERROR_NO_THREAD_LIST; - } - - BPLOG(INFO) << "Minidump " << dump->path() << " has " << - (has_cpu_info ? "" : "no ") << "CPU info, " << - (has_os_info ? "" : "no ") << "OS info, " << - (breakpad_info != NULL ? "" : "no ") << "Breakpad info, " << - (exception != NULL ? "" : "no ") << "exception, " << - (module_list != NULL ? "" : "no ") << "module list, " << - (threads != NULL ? "" : "no ") << "thread list, " << - (has_dump_thread ? "" : "no ") << "dump thread, " << - (has_requesting_thread ? "" : "no ") << "requesting thread, and " << - (has_process_create_time ? "" : "no ") << "process create time"; - - bool interrupted = false; - bool found_requesting_thread = false; - unsigned int thread_count = threads->thread_count(); - - // Reset frame_symbolizer_ at the beginning of stackwalk for each minidump. - frame_symbolizer_->Reset(); - - for (unsigned int thread_index = 0; - thread_index < thread_count; - ++thread_index) { - char thread_string_buffer[64]; - snprintf(thread_string_buffer, sizeof(thread_string_buffer), "%d/%d", - thread_index, thread_count); - string thread_string = dump->path() + ":" + thread_string_buffer; - - MinidumpThread *thread = threads->GetThreadAtIndex(thread_index); - if (!thread) { - BPLOG(ERROR) << "Could not get thread for " << thread_string; - return PROCESS_ERROR_GETTING_THREAD; - } - - uint32_t thread_id; - if (!thread->GetThreadID(&thread_id)) { - BPLOG(ERROR) << "Could not get thread ID for " << thread_string; - return PROCESS_ERROR_GETTING_THREAD_ID; - } - - thread_string += " id " + HexString(thread_id); - BPLOG(INFO) << "Looking at thread " << thread_string; - - // If this thread is the thread that produced the minidump, don't process - // it. Because of the problems associated with a thread producing a - // dump of itself (when both its context and its stack are in flux), - // processing that stack wouldn't provide much useful data. - if (has_dump_thread && thread_id == dump_thread_id) { - continue; - } - - MinidumpContext *context = thread->GetContext(); - - if (has_requesting_thread && thread_id == requesting_thread_id) { - if (found_requesting_thread) { - // There can't be more than one requesting thread. - BPLOG(ERROR) << "Duplicate requesting thread: " << thread_string; - return PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS; - } - - // Use processed_state->threads_.size() instead of thread_index. - // thread_index points to the thread index in the minidump, which - // might be greater than the thread index in the threads vector if - // any of the minidump's threads are skipped and not placed into the - // processed threads vector. The thread vector's current size will - // be the index of the current thread when it's pushed into the - // vector. - process_state->requesting_thread_ = process_state->threads_.size(); - - found_requesting_thread = true; - - if (process_state->crashed_) { - // Use the exception record's context for the crashed thread, instead - // of the thread's own context. For the crashed thread, the thread's - // own context is the state inside the exception handler. Using it - // would not result in the expected stack trace from the time of the - // crash. If the exception context is invalid, however, we fall back - // on the thread context. - MinidumpContext *ctx = exception->GetContext(); - context = ctx ? ctx : thread->GetContext(); - } - } - - // If the memory region for the stack cannot be read using the RVA stored - // in the memory descriptor inside MINIDUMP_THREAD, try to locate and use - // a memory region (containing the stack) from the minidump memory list. - MinidumpMemoryRegion *thread_memory = thread->GetMemory(); - if (!thread_memory && memory_list) { - uint64_t start_stack_memory_range = thread->GetStartOfStackMemoryRange(); - if (start_stack_memory_range) { - thread_memory = memory_list->GetMemoryRegionForAddress( - start_stack_memory_range); - } - } - if (!thread_memory) { - BPLOG(ERROR) << "No memory region for " << thread_string; - } - - // Use process_state->modules_ instead of module_list, because the - // |modules| argument will be used to populate the |module| fields in - // the returned StackFrame objects, which will be placed into the - // returned ProcessState object. module_list's lifetime is only as - // long as the Minidump object: it will be deleted when this function - // returns. process_state->modules_ is owned by the ProcessState object - // (just like the StackFrame objects), and is much more suitable for this - // task. - scoped_ptr stackwalker( - Stackwalker::StackwalkerForCPU(process_state->system_info(), - context, - thread_memory, - process_state->modules_, - frame_symbolizer_)); - - scoped_ptr stack(new CallStack()); - if (stackwalker.get()) { - if (!stackwalker->Walk(stack.get(), - &process_state->modules_without_symbols_, - &process_state->modules_with_corrupt_symbols_)) { - BPLOG(INFO) << "Stackwalker interrupt (missing symbols?) at " - << thread_string; - interrupted = true; - } - } else { - // Threads with missing CPU contexts will hit this, but - // don't abort processing the rest of the dump just for - // one bad thread. - BPLOG(ERROR) << "No stackwalker for " << thread_string; - } - stack->set_tid(thread_id); - process_state->threads_.push_back(stack.release()); - process_state->thread_memory_regions_.push_back(thread_memory); - } - - if (interrupted) { - BPLOG(INFO) << "Processing interrupted for " << dump->path(); - return PROCESS_SYMBOL_SUPPLIER_INTERRUPTED; - } - - // If a requesting thread was indicated, it must be present. - if (has_requesting_thread && !found_requesting_thread) { - // Don't mark as an error, but invalidate the requesting thread - BPLOG(ERROR) << "Minidump indicated requesting thread " << - HexString(requesting_thread_id) << ", not found in " << - dump->path(); - process_state->requesting_thread_ = -1; - } - - // Exploitability defaults to EXPLOITABILITY_NOT_ANALYZED - process_state->exploitability_ = EXPLOITABILITY_NOT_ANALYZED; - - // If an exploitability run was requested we perform the platform specific - // rating. - if (enable_exploitability_) { - scoped_ptr exploitability( - Exploitability::ExploitabilityForPlatform(dump, - process_state, - enable_objdump_)); - // The engine will be null if the platform is not supported - if (exploitability != NULL) { - process_state->exploitability_ = exploitability->CheckExploitability(); - } else { - process_state->exploitability_ = EXPLOITABILITY_ERR_NOENGINE; - } - } - - BPLOG(INFO) << "Processed " << dump->path(); - return PROCESS_OK; -} - -ProcessResult MinidumpProcessor::Process( - const string &minidump_file, ProcessState *process_state) { - BPLOG(INFO) << "Processing minidump in file " << minidump_file; - - Minidump dump(minidump_file); - if (!dump.Read()) { - BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read"; - return PROCESS_ERROR_MINIDUMP_NOT_FOUND; - } - - return Process(&dump, process_state); -} - -// Returns the MDRawSystemInfo from a minidump, or NULL if system info is -// not available from the minidump. If system_info is non-NULL, it is used -// to pass back the MinidumpSystemInfo object. -static const MDRawSystemInfo* GetSystemInfo(Minidump *dump, - MinidumpSystemInfo **system_info) { - MinidumpSystemInfo *minidump_system_info = dump->GetSystemInfo(); - if (!minidump_system_info) - return NULL; - - if (system_info) - *system_info = minidump_system_info; - - return minidump_system_info->system_info(); -} - -// Extract CPU info string from ARM-specific MDRawSystemInfo structure. -// raw_info: pointer to source MDRawSystemInfo. -// cpu_info: address of target string, cpu info text will be appended to it. -static void GetARMCpuInfo(const MDRawSystemInfo* raw_info, - string* cpu_info) { - assert(raw_info != NULL && cpu_info != NULL); - - // Write ARM architecture version. - char cpu_string[32]; - snprintf(cpu_string, sizeof(cpu_string), "ARMv%d", - raw_info->processor_level); - cpu_info->append(cpu_string); - - // There is no good list of implementer id values, but the following - // pages provide some help: - // http://comments.gmane.org/gmane.linux.linaro.devel/6903 - // http://forum.xda-developers.com/archive/index.php/t-480226.html - const struct { - uint32_t id; - const char* name; - } vendors[] = { - { 0x41, "ARM" }, - { 0x51, "Qualcomm" }, - { 0x56, "Marvell" }, - { 0x69, "Intel/Marvell" }, - }; - const struct { - uint32_t id; - const char* name; - } parts[] = { - { 0x4100c050, "Cortex-A5" }, - { 0x4100c080, "Cortex-A8" }, - { 0x4100c090, "Cortex-A9" }, - { 0x4100c0f0, "Cortex-A15" }, - { 0x4100c140, "Cortex-R4" }, - { 0x4100c150, "Cortex-R5" }, - { 0x4100b360, "ARM1136" }, - { 0x4100b560, "ARM1156" }, - { 0x4100b760, "ARM1176" }, - { 0x4100b020, "ARM11-MPCore" }, - { 0x41009260, "ARM926" }, - { 0x41009460, "ARM946" }, - { 0x41009660, "ARM966" }, - { 0x510006f0, "Krait" }, - { 0x510000f0, "Scorpion" }, - }; - - const struct { - uint32_t hwcap; - const char* name; - } features[] = { - { MD_CPU_ARM_ELF_HWCAP_SWP, "swp" }, - { MD_CPU_ARM_ELF_HWCAP_HALF, "half" }, - { MD_CPU_ARM_ELF_HWCAP_THUMB, "thumb" }, - { MD_CPU_ARM_ELF_HWCAP_26BIT, "26bit" }, - { MD_CPU_ARM_ELF_HWCAP_FAST_MULT, "fastmult" }, - { MD_CPU_ARM_ELF_HWCAP_FPA, "fpa" }, - { MD_CPU_ARM_ELF_HWCAP_VFP, "vfpv2" }, - { MD_CPU_ARM_ELF_HWCAP_EDSP, "edsp" }, - { MD_CPU_ARM_ELF_HWCAP_JAVA, "java" }, - { MD_CPU_ARM_ELF_HWCAP_IWMMXT, "iwmmxt" }, - { MD_CPU_ARM_ELF_HWCAP_CRUNCH, "crunch" }, - { MD_CPU_ARM_ELF_HWCAP_THUMBEE, "thumbee" }, - { MD_CPU_ARM_ELF_HWCAP_NEON, "neon" }, - { MD_CPU_ARM_ELF_HWCAP_VFPv3, "vfpv3" }, - { MD_CPU_ARM_ELF_HWCAP_VFPv3D16, "vfpv3d16" }, - { MD_CPU_ARM_ELF_HWCAP_TLS, "tls" }, - { MD_CPU_ARM_ELF_HWCAP_VFPv4, "vfpv4" }, - { MD_CPU_ARM_ELF_HWCAP_IDIVA, "idiva" }, - { MD_CPU_ARM_ELF_HWCAP_IDIVT, "idivt" }, - }; - - uint32_t cpuid = raw_info->cpu.arm_cpu_info.cpuid; - if (cpuid != 0) { - // Extract vendor name from CPUID - const char* vendor = NULL; - uint32_t vendor_id = (cpuid >> 24) & 0xff; - for (size_t i = 0; i < sizeof(vendors)/sizeof(vendors[0]); ++i) { - if (vendors[i].id == vendor_id) { - vendor = vendors[i].name; - break; - } - } - cpu_info->append(" "); - if (vendor) { - cpu_info->append(vendor); - } else { - snprintf(cpu_string, sizeof(cpu_string), "vendor(0x%x)", vendor_id); - cpu_info->append(cpu_string); - } - - // Extract part name from CPUID - uint32_t part_id = (cpuid & 0xff00fff0); - const char* part = NULL; - for (size_t i = 0; i < sizeof(parts)/sizeof(parts[0]); ++i) { - if (parts[i].id == part_id) { - part = parts[i].name; - break; - } - } - cpu_info->append(" "); - if (part != NULL) { - cpu_info->append(part); - } else { - snprintf(cpu_string, sizeof(cpu_string), "part(0x%x)", part_id); - cpu_info->append(cpu_string); - } - } - uint32_t elf_hwcaps = raw_info->cpu.arm_cpu_info.elf_hwcaps; - if (elf_hwcaps != 0) { - cpu_info->append(" features: "); - const char* comma = ""; - for (size_t i = 0; i < sizeof(features)/sizeof(features[0]); ++i) { - if (elf_hwcaps & features[i].hwcap) { - cpu_info->append(comma); - cpu_info->append(features[i].name); - comma = ","; - } - } - } -} - -// static -bool MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) { - assert(dump); - assert(info); - - info->cpu.clear(); - info->cpu_info.clear(); - - MinidumpSystemInfo *system_info; - const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info); - if (!raw_system_info) - return false; - - switch (raw_system_info->processor_architecture) { - case MD_CPU_ARCHITECTURE_X86: - case MD_CPU_ARCHITECTURE_AMD64: { - if (raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_X86) - info->cpu = "x86"; - else - info->cpu = "amd64"; - - const string *cpu_vendor = system_info->GetCPUVendor(); - if (cpu_vendor) { - info->cpu_info = *cpu_vendor; - info->cpu_info.append(" "); - } - - char x86_info[36]; - snprintf(x86_info, sizeof(x86_info), "family %u model %u stepping %u", - raw_system_info->processor_level, - raw_system_info->processor_revision >> 8, - raw_system_info->processor_revision & 0xff); - info->cpu_info.append(x86_info); - break; - } - - case MD_CPU_ARCHITECTURE_PPC: { - info->cpu = "ppc"; - break; - } - - case MD_CPU_ARCHITECTURE_PPC64: { - info->cpu = "ppc64"; - break; - } - - case MD_CPU_ARCHITECTURE_SPARC: { - info->cpu = "sparc"; - break; - } - - case MD_CPU_ARCHITECTURE_ARM: { - info->cpu = "arm"; - GetARMCpuInfo(raw_system_info, &info->cpu_info); - break; - } - - case MD_CPU_ARCHITECTURE_ARM64: { - info->cpu = "arm64"; - break; - } - - case MD_CPU_ARCHITECTURE_MIPS: { - info->cpu = "mips"; - break; - } - case MD_CPU_ARCHITECTURE_MIPS64: { - info->cpu = "mips64"; - break; - } - - default: { - // Assign the numeric architecture ID into the CPU string. - char cpu_string[7]; - snprintf(cpu_string, sizeof(cpu_string), "0x%04x", - raw_system_info->processor_architecture); - info->cpu = cpu_string; - break; - } - } - - info->cpu_count = raw_system_info->number_of_processors; - - return true; -} - -// static -bool MinidumpProcessor::GetOSInfo(Minidump *dump, SystemInfo *info) { - assert(dump); - assert(info); - - info->os.clear(); - info->os_short.clear(); - info->os_version.clear(); - - MinidumpSystemInfo *system_info; - const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, &system_info); - if (!raw_system_info) - return false; - - info->os_short = system_info->GetOS(); - - switch (raw_system_info->platform_id) { - case MD_OS_WIN32_NT: { - info->os = "Windows NT"; - break; - } - - case MD_OS_WIN32_WINDOWS: { - info->os = "Windows"; - break; - } - - case MD_OS_MAC_OS_X: { - info->os = "Mac OS X"; - break; - } - - case MD_OS_IOS: { - info->os = "iOS"; - break; - } - - case MD_OS_LINUX: { - info->os = "Linux"; - break; - } - - case MD_OS_SOLARIS: { - info->os = "Solaris"; - break; - } - - case MD_OS_ANDROID: { - info->os = "Android"; - break; - } - - case MD_OS_PS3: { - info->os = "PS3"; - break; - } - - case MD_OS_NACL: { - info->os = "NaCl"; - break; - } - - default: { - // Assign the numeric platform ID into the OS string. - char os_string[11]; - snprintf(os_string, sizeof(os_string), "0x%08x", - raw_system_info->platform_id); - info->os = os_string; - break; - } - } - - char os_version_string[33]; - snprintf(os_version_string, sizeof(os_version_string), "%u.%u.%u", - raw_system_info->major_version, - raw_system_info->minor_version, - raw_system_info->build_number); - info->os_version = os_version_string; - - const string *csd_version = system_info->GetCSDVersion(); - if (csd_version) { - info->os_version.append(" "); - info->os_version.append(*csd_version); - } - - return true; -} - -// static -bool MinidumpProcessor::GetProcessCreateTime(Minidump* dump, - uint32_t* process_create_time) { - assert(dump); - assert(process_create_time); - - *process_create_time = 0; - - MinidumpMiscInfo* minidump_misc_info = dump->GetMiscInfo(); - if (!minidump_misc_info) { - return false; - } - - const MDRawMiscInfo* md_raw_misc_info = minidump_misc_info->misc_info(); - if (!md_raw_misc_info) { - return false; - } - - if (!(md_raw_misc_info->flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES)) { - return false; - } - - *process_create_time = md_raw_misc_info->process_create_time; - return true; -} - -// static -string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) { - MinidumpException *exception = dump->GetException(); - if (!exception) - return ""; - - const MDRawExceptionStream *raw_exception = exception->exception(); - if (!raw_exception) - return ""; - - if (address) - *address = raw_exception->exception_record.exception_address; - - // The reason value is OS-specific and possibly CPU-specific. Set up - // sensible numeric defaults for the reason string in case we can't - // map the codes to a string (because there's no system info, or because - // it's an unrecognized platform, or because it's an unrecognized code.) - char reason_string[24]; - uint32_t exception_code = raw_exception->exception_record.exception_code; - uint32_t exception_flags = raw_exception->exception_record.exception_flags; - snprintf(reason_string, sizeof(reason_string), "0x%08x / 0x%08x", - exception_code, exception_flags); - string reason = reason_string; - - const MDRawSystemInfo *raw_system_info = GetSystemInfo(dump, NULL); - if (!raw_system_info) - return reason; - - switch (raw_system_info->platform_id) { - case MD_OS_MAC_OS_X: - case MD_OS_IOS: { - char flags_string[11]; - snprintf(flags_string, sizeof(flags_string), "0x%08x", exception_flags); - switch (exception_code) { - case MD_EXCEPTION_MAC_BAD_ACCESS: - reason = "EXC_BAD_ACCESS / "; - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS: - reason.append("KERN_INVALID_ADDRESS"); - break; - case MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE: - reason.append("KERN_PROTECTION_FAILURE"); - break; - case MD_EXCEPTION_CODE_MAC_NO_ACCESS: - reason.append("KERN_NO_ACCESS"); - break; - case MD_EXCEPTION_CODE_MAC_MEMORY_FAILURE: - reason.append("KERN_MEMORY_FAILURE"); - break; - case MD_EXCEPTION_CODE_MAC_MEMORY_ERROR: - reason.append("KERN_MEMORY_ERROR"); - break; - default: - // arm and ppc overlap - if (raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_ARM || - raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_ARM64) { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN: - reason.append("EXC_ARM_DA_ALIGN"); - break; - case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG: - reason.append("EXC_ARM_DA_DEBUG"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - } else if (raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_PPC) { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_PPC_VM_PROT_READ: - reason.append("EXC_PPC_VM_PROT_READ"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_BADSPACE: - reason.append("EXC_PPC_BADSPACE"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_UNALIGNED: - reason.append("EXC_PPC_UNALIGNED"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - } else if (raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_X86 || - raw_system_info->processor_architecture == - MD_CPU_ARCHITECTURE_AMD64) { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT: - reason.append("EXC_I386_GPFLT"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - } else { - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - } - break; - } - break; - case MD_EXCEPTION_MAC_BAD_INSTRUCTION: - reason = "EXC_BAD_INSTRUCTION / "; - switch (raw_system_info->processor_architecture) { - case MD_CPU_ARCHITECTURE_ARM: - case MD_CPU_ARCHITECTURE_ARM64: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_ARM_UNDEFINED: - reason.append("EXC_ARM_UNDEFINED"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - case MD_CPU_ARCHITECTURE_PPC: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_PPC_INVALID_SYSCALL: - reason.append("EXC_PPC_INVALID_SYSCALL"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_UNIMPLEMENTED_INSTRUCTION: - reason.append("EXC_PPC_UNIPL_INST"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_INSTRUCTION: - reason.append("EXC_PPC_PRIVINST"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_PRIVILEGED_REGISTER: - reason.append("EXC_PPC_PRIVREG"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_TRACE: - reason.append("EXC_PPC_TRACE"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_PERFORMANCE_MONITOR: - reason.append("EXC_PPC_PERFMON"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - case MD_CPU_ARCHITECTURE_AMD64: - case MD_CPU_ARCHITECTURE_X86: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION: - reason.append("EXC_I386_INVOP"); - break; - case MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT: - reason.append("EXC_I386_INVTSSFLT"); - break; - case MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT: - reason.append("EXC_I386_SEGNPFLT"); - break; - case MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT: - reason.append("EXC_I386_STKFLT"); - break; - case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT: - reason.append("EXC_I386_GPFLT"); - break; - case MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT: - reason.append("EXC_I386_ALIGNFLT"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - case MD_EXCEPTION_MAC_ARITHMETIC: - reason = "EXC_ARITHMETIC / "; - switch (raw_system_info->processor_architecture) { - case MD_CPU_ARCHITECTURE_PPC: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_PPC_OVERFLOW: - reason.append("EXC_PPC_OVERFLOW"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_ZERO_DIVIDE: - reason.append("EXC_PPC_ZERO_DIVIDE"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_INEXACT: - reason.append("EXC_FLT_INEXACT"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_ZERO_DIVIDE: - reason.append("EXC_PPC_FLT_ZERO_DIVIDE"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_UNDERFLOW: - reason.append("EXC_PPC_FLT_UNDERFLOW"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_OVERFLOW: - reason.append("EXC_PPC_FLT_OVERFLOW"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_FLOAT_NOT_A_NUMBER: - reason.append("EXC_PPC_FLT_NOT_A_NUMBER"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_NO_EMULATION: - reason.append("EXC_PPC_NOEMULATION"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_ALTIVEC_ASSIST: - reason.append("EXC_PPC_ALTIVECASSIST"); - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - case MD_CPU_ARCHITECTURE_AMD64: - case MD_CPU_ARCHITECTURE_X86: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_X86_DIV: - reason.append("EXC_I386_DIV"); - break; - case MD_EXCEPTION_CODE_MAC_X86_INTO: - reason.append("EXC_I386_INTO"); - break; - case MD_EXCEPTION_CODE_MAC_X86_NOEXT: - reason.append("EXC_I386_NOEXT"); - break; - case MD_EXCEPTION_CODE_MAC_X86_EXTOVR: - reason.append("EXC_I386_EXTOVR"); - break; - case MD_EXCEPTION_CODE_MAC_X86_EXTERR: - reason.append("EXC_I386_EXTERR"); - break; - case MD_EXCEPTION_CODE_MAC_X86_EMERR: - reason.append("EXC_I386_EMERR"); - break; - case MD_EXCEPTION_CODE_MAC_X86_BOUND: - reason.append("EXC_I386_BOUND"); - break; - case MD_EXCEPTION_CODE_MAC_X86_SSEEXTERR: - reason.append("EXC_I386_SSEEXTERR"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - case MD_EXCEPTION_MAC_EMULATION: - reason = "EXC_EMULATION / "; - reason.append(flags_string); - break; - case MD_EXCEPTION_MAC_SOFTWARE: - reason = "EXC_SOFTWARE / "; - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_ABORT: - reason.append("SIGABRT"); - break; - case MD_EXCEPTION_CODE_MAC_NS_EXCEPTION: - reason.append("UNCAUGHT_NS_EXCEPTION"); - break; - // These are ppc only but shouldn't be a problem as they're - // unused on x86 - case MD_EXCEPTION_CODE_MAC_PPC_TRAP: - reason.append("EXC_PPC_TRAP"); - break; - case MD_EXCEPTION_CODE_MAC_PPC_MIGRATE: - reason.append("EXC_PPC_MIGRATE"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - case MD_EXCEPTION_MAC_BREAKPOINT: - reason = "EXC_BREAKPOINT / "; - switch (raw_system_info->processor_architecture) { - case MD_CPU_ARCHITECTURE_ARM: - case MD_CPU_ARCHITECTURE_ARM64: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_ARM_DA_ALIGN: - reason.append("EXC_ARM_DA_ALIGN"); - break; - case MD_EXCEPTION_CODE_MAC_ARM_DA_DEBUG: - reason.append("EXC_ARM_DA_DEBUG"); - break; - case MD_EXCEPTION_CODE_MAC_ARM_BREAKPOINT: - reason.append("EXC_ARM_BREAKPOINT"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - case MD_CPU_ARCHITECTURE_PPC: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_PPC_BREAKPOINT: - reason.append("EXC_PPC_BREAKPOINT"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - case MD_CPU_ARCHITECTURE_AMD64: - case MD_CPU_ARCHITECTURE_X86: { - switch (exception_flags) { - case MD_EXCEPTION_CODE_MAC_X86_SGL: - reason.append("EXC_I386_SGL"); - break; - case MD_EXCEPTION_CODE_MAC_X86_BPT: - reason.append("EXC_I386_BPT"); - break; - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - default: - reason.append(flags_string); - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - case MD_EXCEPTION_MAC_SYSCALL: - reason = "EXC_SYSCALL / "; - reason.append(flags_string); - break; - case MD_EXCEPTION_MAC_MACH_SYSCALL: - reason = "EXC_MACH_SYSCALL / "; - reason.append(flags_string); - break; - case MD_EXCEPTION_MAC_RPC_ALERT: - reason = "EXC_RPC_ALERT / "; - reason.append(flags_string); - break; - } - break; - } - - case MD_OS_WIN32_NT: - case MD_OS_WIN32_WINDOWS: { - switch (exception_code) { - case MD_EXCEPTION_CODE_WIN_CONTROL_C: - reason = "DBG_CONTROL_C"; - break; - case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION: - reason = "EXCEPTION_GUARD_PAGE"; - break; - case MD_EXCEPTION_CODE_WIN_DATATYPE_MISALIGNMENT: - reason = "EXCEPTION_DATATYPE_MISALIGNMENT"; - break; - case MD_EXCEPTION_CODE_WIN_BREAKPOINT: - reason = "EXCEPTION_BREAKPOINT"; - break; - case MD_EXCEPTION_CODE_WIN_SINGLE_STEP: - reason = "EXCEPTION_SINGLE_STEP"; - break; - case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION: - // For EXCEPTION_ACCESS_VIOLATION, Windows puts the address that - // caused the fault in exception_information[1]. - // exception_information[0] is 0 if the violation was caused by - // an attempt to read data, 1 if it was an attempt to write data, - // and 8 if this was a data execution violation. - // This information is useful in addition to the code address, which - // will be present in the crash thread's instruction field anyway. - if (raw_exception->exception_record.number_parameters >= 1) { - MDAccessViolationTypeWin av_type = - static_cast - (raw_exception->exception_record.exception_information[0]); - switch (av_type) { - case MD_ACCESS_VIOLATION_WIN_READ: - reason = "EXCEPTION_ACCESS_VIOLATION_READ"; - break; - case MD_ACCESS_VIOLATION_WIN_WRITE: - reason = "EXCEPTION_ACCESS_VIOLATION_WRITE"; - break; - case MD_ACCESS_VIOLATION_WIN_EXEC: - reason = "EXCEPTION_ACCESS_VIOLATION_EXEC"; - break; - default: - reason = "EXCEPTION_ACCESS_VIOLATION"; - break; - } - } else { - reason = "EXCEPTION_ACCESS_VIOLATION"; - } - if (address && - raw_exception->exception_record.number_parameters >= 2) { - *address = - raw_exception->exception_record.exception_information[1]; - } - break; - case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR: - // For EXCEPTION_IN_PAGE_ERROR, Windows puts the address that - // caused the fault in exception_information[1]. - // exception_information[0] is 0 if the violation was caused by - // an attempt to read data, 1 if it was an attempt to write data, - // and 8 if this was a data execution violation. - // exception_information[2] contains the underlying NTSTATUS code, - // which is the explanation for why this error occured. - // This information is useful in addition to the code address, which - // will be present in the crash thread's instruction field anyway. - if (raw_exception->exception_record.number_parameters >= 1) { - MDInPageErrorTypeWin av_type = - static_cast - (raw_exception->exception_record.exception_information[0]); - switch (av_type) { - case MD_IN_PAGE_ERROR_WIN_READ: - reason = "EXCEPTION_IN_PAGE_ERROR_READ"; - break; - case MD_IN_PAGE_ERROR_WIN_WRITE: - reason = "EXCEPTION_IN_PAGE_ERROR_WRITE"; - break; - case MD_IN_PAGE_ERROR_WIN_EXEC: - reason = "EXCEPTION_IN_PAGE_ERROR_EXEC"; - break; - default: - reason = "EXCEPTION_IN_PAGE_ERROR"; - break; - } - } else { - reason = "EXCEPTION_IN_PAGE_ERROR"; - } - if (address && - raw_exception->exception_record.number_parameters >= 2) { - *address = - raw_exception->exception_record.exception_information[1]; - } - if (raw_exception->exception_record.number_parameters >= 3) { - uint32_t ntstatus = - static_cast - (raw_exception->exception_record.exception_information[2]); - reason.append(" / "); - reason.append(NTStatusToString(ntstatus)); - } - break; - case MD_EXCEPTION_CODE_WIN_INVALID_HANDLE: - reason = "EXCEPTION_INVALID_HANDLE"; - break; - case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION: - reason = "EXCEPTION_ILLEGAL_INSTRUCTION"; - break; - case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION: - reason = "EXCEPTION_NONCONTINUABLE_EXCEPTION"; - break; - case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION: - reason = "EXCEPTION_INVALID_DISPOSITION"; - break; - case MD_EXCEPTION_CODE_WIN_ARRAY_BOUNDS_EXCEEDED: - reason = "EXCEPTION_BOUNDS_EXCEEDED"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_DENORMAL_OPERAND: - reason = "EXCEPTION_FLT_DENORMAL_OPERAND"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO: - reason = "EXCEPTION_FLT_DIVIDE_BY_ZERO"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT: - reason = "EXCEPTION_FLT_INEXACT_RESULT"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION: - reason = "EXCEPTION_FLT_INVALID_OPERATION"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW: - reason = "EXCEPTION_FLT_OVERFLOW"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_STACK_CHECK: - reason = "EXCEPTION_FLT_STACK_CHECK"; - break; - case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW: - reason = "EXCEPTION_FLT_UNDERFLOW"; - break; - case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO: - reason = "EXCEPTION_INT_DIVIDE_BY_ZERO"; - break; - case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW: - reason = "EXCEPTION_INT_OVERFLOW"; - break; - case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION: - reason = "EXCEPTION_PRIV_INSTRUCTION"; - break; - case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW: - reason = "EXCEPTION_STACK_OVERFLOW"; - break; - case MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK: - reason = "EXCEPTION_POSSIBLE_DEADLOCK"; - break; - case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN: - reason = "EXCEPTION_STACK_BUFFER_OVERRUN"; - break; - case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION: - reason = "EXCEPTION_HEAP_CORRUPTION"; - break; - case MD_EXCEPTION_OUT_OF_MEMORY: - reason = "Out of Memory"; - break; - case MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION: - reason = "Unhandled C++ Exception"; - break; - default: - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - - case MD_OS_ANDROID: - case MD_OS_LINUX: { - switch (exception_code) { - case MD_EXCEPTION_CODE_LIN_SIGHUP: - reason = "SIGHUP"; - break; - case MD_EXCEPTION_CODE_LIN_SIGINT: - reason = "SIGINT"; - break; - case MD_EXCEPTION_CODE_LIN_SIGQUIT: - reason = "SIGQUIT"; - break; - case MD_EXCEPTION_CODE_LIN_SIGILL: - reason = "SIGILL"; - break; - case MD_EXCEPTION_CODE_LIN_SIGTRAP: - reason = "SIGTRAP"; - break; - case MD_EXCEPTION_CODE_LIN_SIGABRT: - reason = "SIGABRT"; - break; - case MD_EXCEPTION_CODE_LIN_SIGBUS: - reason = "SIGBUS"; - break; - case MD_EXCEPTION_CODE_LIN_SIGFPE: - reason = "SIGFPE"; - break; - case MD_EXCEPTION_CODE_LIN_SIGKILL: - reason = "SIGKILL"; - break; - case MD_EXCEPTION_CODE_LIN_SIGUSR1: - reason = "SIGUSR1"; - break; - case MD_EXCEPTION_CODE_LIN_SIGSEGV: - reason = "SIGSEGV"; - break; - case MD_EXCEPTION_CODE_LIN_SIGUSR2: - reason = "SIGUSR2"; - break; - case MD_EXCEPTION_CODE_LIN_SIGPIPE: - reason = "SIGPIPE"; - break; - case MD_EXCEPTION_CODE_LIN_SIGALRM: - reason = "SIGALRM"; - break; - case MD_EXCEPTION_CODE_LIN_SIGTERM: - reason = "SIGTERM"; - break; - case MD_EXCEPTION_CODE_LIN_SIGSTKFLT: - reason = "SIGSTKFLT"; - break; - case MD_EXCEPTION_CODE_LIN_SIGCHLD: - reason = "SIGCHLD"; - break; - case MD_EXCEPTION_CODE_LIN_SIGCONT: - reason = "SIGCONT"; - break; - case MD_EXCEPTION_CODE_LIN_SIGSTOP: - reason = "SIGSTOP"; - break; - case MD_EXCEPTION_CODE_LIN_SIGTSTP: - reason = "SIGTSTP"; - break; - case MD_EXCEPTION_CODE_LIN_SIGTTIN: - reason = "SIGTTIN"; - break; - case MD_EXCEPTION_CODE_LIN_SIGTTOU: - reason = "SIGTTOU"; - break; - case MD_EXCEPTION_CODE_LIN_SIGURG: - reason = "SIGURG"; - break; - case MD_EXCEPTION_CODE_LIN_SIGXCPU: - reason = "SIGXCPU"; - break; - case MD_EXCEPTION_CODE_LIN_SIGXFSZ: - reason = "SIGXFSZ"; - break; - case MD_EXCEPTION_CODE_LIN_SIGVTALRM: - reason = "SIGVTALRM"; - break; - case MD_EXCEPTION_CODE_LIN_SIGPROF: - reason = "SIGPROF"; - break; - case MD_EXCEPTION_CODE_LIN_SIGWINCH: - reason = "SIGWINCH"; - break; - case MD_EXCEPTION_CODE_LIN_SIGIO: - reason = "SIGIO"; - break; - case MD_EXCEPTION_CODE_LIN_SIGPWR: - reason = "SIGPWR"; - break; - case MD_EXCEPTION_CODE_LIN_SIGSYS: - reason = "SIGSYS"; - break; - case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED: - reason = "DUMP_REQUESTED"; - break; - default: - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - - case MD_OS_SOLARIS: { - switch (exception_code) { - case MD_EXCEPTION_CODE_SOL_SIGHUP: - reason = "SIGHUP"; - break; - case MD_EXCEPTION_CODE_SOL_SIGINT: - reason = "SIGINT"; - break; - case MD_EXCEPTION_CODE_SOL_SIGQUIT: - reason = "SIGQUIT"; - break; - case MD_EXCEPTION_CODE_SOL_SIGILL: - reason = "SIGILL"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTRAP: - reason = "SIGTRAP"; - break; - case MD_EXCEPTION_CODE_SOL_SIGIOT: - reason = "SIGIOT | SIGABRT"; - break; - case MD_EXCEPTION_CODE_SOL_SIGEMT: - reason = "SIGEMT"; - break; - case MD_EXCEPTION_CODE_SOL_SIGFPE: - reason = "SIGFPE"; - break; - case MD_EXCEPTION_CODE_SOL_SIGKILL: - reason = "SIGKILL"; - break; - case MD_EXCEPTION_CODE_SOL_SIGBUS: - reason = "SIGBUS"; - break; - case MD_EXCEPTION_CODE_SOL_SIGSEGV: - reason = "SIGSEGV"; - break; - case MD_EXCEPTION_CODE_SOL_SIGSYS: - reason = "SIGSYS"; - break; - case MD_EXCEPTION_CODE_SOL_SIGPIPE: - reason = "SIGPIPE"; - break; - case MD_EXCEPTION_CODE_SOL_SIGALRM: - reason = "SIGALRM"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTERM: - reason = "SIGTERM"; - break; - case MD_EXCEPTION_CODE_SOL_SIGUSR1: - reason = "SIGUSR1"; - break; - case MD_EXCEPTION_CODE_SOL_SIGUSR2: - reason = "SIGUSR2"; - break; - case MD_EXCEPTION_CODE_SOL_SIGCLD: - reason = "SIGCLD | SIGCHLD"; - break; - case MD_EXCEPTION_CODE_SOL_SIGPWR: - reason = "SIGPWR"; - break; - case MD_EXCEPTION_CODE_SOL_SIGWINCH: - reason = "SIGWINCH"; - break; - case MD_EXCEPTION_CODE_SOL_SIGURG: - reason = "SIGURG"; - break; - case MD_EXCEPTION_CODE_SOL_SIGPOLL: - reason = "SIGPOLL | SIGIO"; - break; - case MD_EXCEPTION_CODE_SOL_SIGSTOP: - reason = "SIGSTOP"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTSTP: - reason = "SIGTSTP"; - break; - case MD_EXCEPTION_CODE_SOL_SIGCONT: - reason = "SIGCONT"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTTIN: - reason = "SIGTTIN"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTTOU: - reason = "SIGTTOU"; - break; - case MD_EXCEPTION_CODE_SOL_SIGVTALRM: - reason = "SIGVTALRM"; - break; - case MD_EXCEPTION_CODE_SOL_SIGPROF: - reason = "SIGPROF"; - break; - case MD_EXCEPTION_CODE_SOL_SIGXCPU: - reason = "SIGXCPU"; - break; - case MD_EXCEPTION_CODE_SOL_SIGXFSZ: - reason = "SIGXFSZ"; - break; - case MD_EXCEPTION_CODE_SOL_SIGWAITING: - reason = "SIGWAITING"; - break; - case MD_EXCEPTION_CODE_SOL_SIGLWP: - reason = "SIGLWP"; - break; - case MD_EXCEPTION_CODE_SOL_SIGFREEZE: - reason = "SIGFREEZE"; - break; - case MD_EXCEPTION_CODE_SOL_SIGTHAW: - reason = "SIGTHAW"; - break; - case MD_EXCEPTION_CODE_SOL_SIGCANCEL: - reason = "SIGCANCEL"; - break; - case MD_EXCEPTION_CODE_SOL_SIGLOST: - reason = "SIGLOST"; - break; - case MD_EXCEPTION_CODE_SOL_SIGXRES: - reason = "SIGXRES"; - break; - case MD_EXCEPTION_CODE_SOL_SIGJVM1: - reason = "SIGJVM1"; - break; - case MD_EXCEPTION_CODE_SOL_SIGJVM2: - reason = "SIGJVM2"; - break; - default: - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - break; - } - - case MD_OS_PS3: { - switch (exception_code) { - case MD_EXCEPTION_CODE_PS3_UNKNOWN: - reason = "UNKNOWN"; - break; - case MD_EXCEPTION_CODE_PS3_TRAP_EXCEP: - reason = "TRAP_EXCEP"; - break; - case MD_EXCEPTION_CODE_PS3_PRIV_INSTR: - reason = "PRIV_INSTR"; - break; - case MD_EXCEPTION_CODE_PS3_ILLEGAL_INSTR: - reason = "ILLEGAL_INSTR"; - break; - case MD_EXCEPTION_CODE_PS3_INSTR_STORAGE: - reason = "INSTR_STORAGE"; - break; - case MD_EXCEPTION_CODE_PS3_INSTR_SEGMENT: - reason = "INSTR_SEGMENT"; - break; - case MD_EXCEPTION_CODE_PS3_DATA_STORAGE: - reason = "DATA_STORAGE"; - break; - case MD_EXCEPTION_CODE_PS3_DATA_SEGMENT: - reason = "DATA_SEGMENT"; - break; - case MD_EXCEPTION_CODE_PS3_FLOAT_POINT: - reason = "FLOAT_POINT"; - break; - case MD_EXCEPTION_CODE_PS3_DABR_MATCH: - reason = "DABR_MATCH"; - break; - case MD_EXCEPTION_CODE_PS3_ALIGN_EXCEP: - reason = "ALIGN_EXCEP"; - break; - case MD_EXCEPTION_CODE_PS3_MEMORY_ACCESS: - reason = "MEMORY_ACCESS"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_ALIGN: - reason = "COPRO_ALIGN"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_INVALID_COM: - reason = "COPRO_INVALID_COM"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_ERR: - reason = "COPRO_ERR"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_FIR: - reason = "COPRO_FIR"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_DATA_SEGMENT: - reason = "COPRO_DATA_SEGMENT"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_DATA_STORAGE: - reason = "COPRO_DATA_STORAGE"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_STOP_INSTR: - reason = "COPRO_STOP_INSTR"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_HALT_INSTR: - reason = "COPRO_HALT_INSTR"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_HALTINST_UNKNOWN: - reason = "COPRO_HALTINSTR_UNKNOWN"; - break; - case MD_EXCEPTION_CODE_PS3_COPRO_MEMORY_ACCESS: - reason = "COPRO_MEMORY_ACCESS"; - break; - case MD_EXCEPTION_CODE_PS3_GRAPHIC: - reason = "GRAPHIC"; - break; - default: - BPLOG(INFO) << "Unknown exception reason "<< reason; - break; - } - break; - } - - default: { - BPLOG(INFO) << "Unknown exception reason " << reason; - break; - } - } - - return reason; -} - -// static -string MinidumpProcessor::GetAssertion(Minidump *dump) { - MinidumpAssertion *assertion = dump->GetAssertion(); - if (!assertion) - return ""; - - const MDRawAssertionInfo *raw_assertion = assertion->assertion(); - if (!raw_assertion) - return ""; - - string assertion_string; - switch (raw_assertion->type) { - case MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER: - assertion_string = "Invalid parameter passed to library function"; - break; - case MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL: - assertion_string = "Pure virtual function called"; - break; - default: { - char assertion_type[32]; - snprintf(assertion_type, sizeof(assertion_type), - "0x%08x", raw_assertion->type); - assertion_string = "Unknown assertion type "; - assertion_string += assertion_type; - break; - } - } - - string expression = assertion->expression(); - if (!expression.empty()) { - assertion_string.append(" " + expression); - } - - string function = assertion->function(); - if (!function.empty()) { - assertion_string.append(" in function " + function); - } - - string file = assertion->file(); - if (!file.empty()) { - assertion_string.append(", in file " + file); - } - - if (raw_assertion->line != 0) { - char assertion_line[32]; - snprintf(assertion_line, sizeof(assertion_line), "%u", raw_assertion->line); - assertion_string.append(" at line "); - assertion_string.append(assertion_line); - } - - return assertion_string; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc deleted file mode 100644 index d43c1fc97..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unit test for MinidumpProcessor. Uses a pre-generated minidump and -// corresponding symbol file, and checks the stack frames for correctness. - -#include - -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/minidump_processor.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/symbol_supplier.h" -#include "processor/logging.h" -#include "processor/stackwalker_unittest_utils.h" - -using std::map; - -namespace google_breakpad { -class MockMinidump : public Minidump { - public: - MockMinidump() : Minidump("") { - } - - MOCK_METHOD0(Read, bool()); - MOCK_CONST_METHOD0(path, string()); - MOCK_CONST_METHOD0(header, const MDRawHeader*()); - MOCK_METHOD0(GetThreadList, MinidumpThreadList*()); - MOCK_METHOD0(GetSystemInfo, MinidumpSystemInfo*()); - MOCK_METHOD0(GetMiscInfo, MinidumpMiscInfo*()); - MOCK_METHOD0(GetBreakpadInfo, MinidumpBreakpadInfo*()); - MOCK_METHOD0(GetException, MinidumpException*()); - MOCK_METHOD0(GetAssertion, MinidumpAssertion*()); - MOCK_METHOD0(GetModuleList, MinidumpModuleList*()); - MOCK_METHOD0(GetMemoryList, MinidumpMemoryList*()); -}; - -class MockMinidumpThreadList : public MinidumpThreadList { - public: - MockMinidumpThreadList() : MinidumpThreadList(NULL) {} - - MOCK_CONST_METHOD0(thread_count, unsigned int()); - MOCK_CONST_METHOD1(GetThreadAtIndex, MinidumpThread*(unsigned int)); -}; - -class MockMinidumpMemoryList : public MinidumpMemoryList { - public: - MockMinidumpMemoryList() : MinidumpMemoryList(NULL) {} - - MOCK_METHOD1(GetMemoryRegionForAddress, MinidumpMemoryRegion*(uint64_t)); -}; - -class MockMinidumpThread : public MinidumpThread { - public: - MockMinidumpThread() : MinidumpThread(NULL) {} - - MOCK_CONST_METHOD1(GetThreadID, bool(uint32_t*)); - MOCK_METHOD0(GetContext, MinidumpContext*()); - MOCK_METHOD0(GetMemory, MinidumpMemoryRegion*()); - MOCK_CONST_METHOD0(GetStartOfStackMemoryRange, uint64_t()); -}; - -// This is crappy, but MinidumpProcessor really does want a -// MinidumpMemoryRegion. -class MockMinidumpMemoryRegion : public MinidumpMemoryRegion { - public: - MockMinidumpMemoryRegion(uint64_t base, const string& contents) : - MinidumpMemoryRegion(NULL) { - region_.Init(base, contents); - } - - uint64_t GetBase() const { return region_.GetBase(); } - uint32_t GetSize() const { return region_.GetSize(); } - - bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { - return region_.GetMemoryAtAddress(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { - return region_.GetMemoryAtAddress(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { - return region_.GetMemoryAtAddress(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { - return region_.GetMemoryAtAddress(address, value); - } - - MockMemoryRegion region_; -}; - -// A test miscelaneous info stream, just returns values from the -// MDRawMiscInfo fed to it. -class TestMinidumpMiscInfo : public MinidumpMiscInfo { - public: - explicit TestMinidumpMiscInfo(const MDRawMiscInfo& misc_info) : - MinidumpMiscInfo(NULL) { - valid_ = true; - misc_info_ = misc_info; - } -}; - -} // namespace google_breakpad - -namespace { - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::MinidumpContext; -using google_breakpad::MinidumpMemoryRegion; -using google_breakpad::MinidumpMiscInfo; -using google_breakpad::MinidumpProcessor; -using google_breakpad::MinidumpSystemInfo; -using google_breakpad::MinidumpThreadList; -using google_breakpad::MinidumpThread; -using google_breakpad::MockMinidump; -using google_breakpad::MockMinidumpMemoryList; -using google_breakpad::MockMinidumpMemoryRegion; -using google_breakpad::MockMinidumpThread; -using google_breakpad::MockMinidumpThreadList; -using google_breakpad::ProcessState; -using google_breakpad::scoped_ptr; -using google_breakpad::SymbolSupplier; -using google_breakpad::SystemInfo; -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::DoAll; -using ::testing::Mock; -using ::testing::Ne; -using ::testing::Property; -using ::testing::Return; -using ::testing::SetArgumentPointee; - -static const char *kSystemInfoOS = "Windows NT"; -static const char *kSystemInfoOSShort = "windows"; -static const char *kSystemInfoOSVersion = "5.1.2600 Service Pack 2"; -static const char *kSystemInfoCPU = "x86"; -static const char *kSystemInfoCPUInfo = - "GenuineIntel family 6 model 13 stepping 8"; - -#define ASSERT_TRUE_ABORT(cond) \ - if (!(cond)) { \ - fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \ - abort(); \ - } - -#define ASSERT_EQ_ABORT(e1, e2) ASSERT_TRUE_ABORT((e1) == (e2)) - -class TestSymbolSupplier : public SymbolSupplier { - public: - TestSymbolSupplier() : interrupt_(false) {} - - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file); - - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data); - - virtual SymbolResult GetCStringSymbolData(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size); - - virtual void FreeSymbolData(const CodeModule *module); - - // When set to true, causes the SymbolSupplier to return INTERRUPT - void set_interrupt(bool interrupt) { interrupt_ = interrupt; } - - private: - bool interrupt_; - map memory_buffers_; -}; - -SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile( - const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file) { - ASSERT_TRUE_ABORT(module); - ASSERT_TRUE_ABORT(system_info); - ASSERT_EQ_ABORT(system_info->cpu, kSystemInfoCPU); - ASSERT_EQ_ABORT(system_info->cpu_info, kSystemInfoCPUInfo); - ASSERT_EQ_ABORT(system_info->os, kSystemInfoOS); - ASSERT_EQ_ABORT(system_info->os_short, kSystemInfoOSShort); - ASSERT_EQ_ABORT(system_info->os_version, kSystemInfoOSVersion); - - if (interrupt_) { - return INTERRUPT; - } - - if (module && module->code_file() == "c:\\test_app.exe") { - *symbol_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/symbols/test_app.pdb/" + - module->debug_identifier() + - "/test_app.sym"; - return FOUND; - } - - return NOT_FOUND; -} - -SymbolSupplier::SymbolResult TestSymbolSupplier::GetSymbolFile( - const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data) { - SymbolSupplier::SymbolResult s = GetSymbolFile(module, system_info, - symbol_file); - if (s == FOUND) { - std::ifstream in(symbol_file->c_str()); - std::getline(in, *symbol_data, string::traits_type::to_char_type( - string::traits_type::eof())); - in.close(); - } - - return s; -} - -SymbolSupplier::SymbolResult TestSymbolSupplier::GetCStringSymbolData( - const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size) { - string symbol_data_string; - SymbolSupplier::SymbolResult s = GetSymbolFile(module, - system_info, - symbol_file, - &symbol_data_string); - if (s == FOUND) { - *symbol_data_size = symbol_data_string.size() + 1; - *symbol_data = new char[*symbol_data_size]; - if (*symbol_data == NULL) { - BPLOG(ERROR) << "Memory allocation failed for module: " - << module->code_file() << " size: " << *symbol_data_size; - return INTERRUPT; - } - memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size()); - (*symbol_data)[symbol_data_string.size()] = '\0'; - memory_buffers_.insert(make_pair(module->code_file(), *symbol_data)); - } - - return s; -} - -void TestSymbolSupplier::FreeSymbolData(const CodeModule *module) { - map::iterator it = memory_buffers_.find(module->code_file()); - if (it != memory_buffers_.end()) { - delete [] it->second; - memory_buffers_.erase(it); - } -} - -// A test system info stream, just returns values from the -// MDRawSystemInfo fed to it. -class TestMinidumpSystemInfo : public MinidumpSystemInfo { - public: - explicit TestMinidumpSystemInfo(MDRawSystemInfo info) : - MinidumpSystemInfo(NULL) { - valid_ = true; - system_info_ = info; - csd_version_ = new string(""); - } -}; - -// A test minidump context, just returns the MDRawContextX86 -// fed to it. -class TestMinidumpContext : public MinidumpContext { - public: - explicit TestMinidumpContext(const MDRawContextX86& context) : - MinidumpContext(NULL) { - valid_ = true; - SetContextX86(new MDRawContextX86(context)); - SetContextFlags(MD_CONTEXT_X86); - } -}; - -class MinidumpProcessorTest : public ::testing::Test { -}; - -TEST_F(MinidumpProcessorTest, TestCorruptMinidumps) { - MockMinidump dump; - TestSymbolSupplier supplier; - BasicSourceLineResolver resolver; - MinidumpProcessor processor(&supplier, &resolver); - ProcessState state; - - EXPECT_EQ(processor.Process("nonexistent minidump", &state), - google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND); - - EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump")); - EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true)); - - MDRawHeader fakeHeader; - fakeHeader.time_date_stamp = 0; - EXPECT_CALL(dump, header()). - WillOnce(Return(reinterpret_cast(NULL))). - WillRepeatedly(Return(&fakeHeader)); - - EXPECT_EQ(processor.Process(&dump, &state), - google_breakpad::PROCESS_ERROR_NO_MINIDUMP_HEADER); - - EXPECT_CALL(dump, GetThreadList()). - WillOnce(Return(reinterpret_cast(NULL))); - EXPECT_CALL(dump, GetSystemInfo()). - WillRepeatedly(Return(reinterpret_cast(NULL))); - - EXPECT_EQ(processor.Process(&dump, &state), - google_breakpad::PROCESS_ERROR_NO_THREAD_LIST); -} - -// This test case verifies that the symbol supplier is only consulted -// once per minidump per module. -TEST_F(MinidumpProcessorTest, TestSymbolSupplierLookupCounts) { - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - MinidumpProcessor processor(&supplier, &resolver); - - string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/minidump2.dmp"; - ProcessState state; - EXPECT_CALL(supplier, GetCStringSymbolData( - Property(&google_breakpad::CodeModule::code_file, - "c:\\test_app.exe"), - _, _, _, _)).WillOnce(Return(SymbolSupplier::NOT_FOUND)); - EXPECT_CALL(supplier, GetCStringSymbolData( - Property(&google_breakpad::CodeModule::code_file, - Ne("c:\\test_app.exe")), - _, _, _, _)).WillRepeatedly(Return(SymbolSupplier::NOT_FOUND)); - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - ASSERT_EQ(processor.Process(minidump_file, &state), - google_breakpad::PROCESS_OK); - - ASSERT_TRUE(Mock::VerifyAndClearExpectations(&supplier)); - - // We need to verify that across minidumps, the processor will refetch - // symbol files, even with the same symbol supplier. - EXPECT_CALL(supplier, GetCStringSymbolData( - Property(&google_breakpad::CodeModule::code_file, - "c:\\test_app.exe"), - _, _, _, _)).WillOnce(Return(SymbolSupplier::NOT_FOUND)); - EXPECT_CALL(supplier, GetCStringSymbolData( - Property(&google_breakpad::CodeModule::code_file, - Ne("c:\\test_app.exe")), - _, _, _, _)).WillRepeatedly(Return(SymbolSupplier::NOT_FOUND)); - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - ASSERT_EQ(processor.Process(minidump_file, &state), - google_breakpad::PROCESS_OK); -} - -TEST_F(MinidumpProcessorTest, TestBasicProcessing) { - TestSymbolSupplier supplier; - BasicSourceLineResolver resolver; - MinidumpProcessor processor(&supplier, &resolver); - - string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/minidump2.dmp"; - - ProcessState state; - ASSERT_EQ(processor.Process(minidump_file, &state), - google_breakpad::PROCESS_OK); - ASSERT_EQ(state.system_info()->os, kSystemInfoOS); - ASSERT_EQ(state.system_info()->os_short, kSystemInfoOSShort); - ASSERT_EQ(state.system_info()->os_version, kSystemInfoOSVersion); - ASSERT_EQ(state.system_info()->cpu, kSystemInfoCPU); - ASSERT_EQ(state.system_info()->cpu_info, kSystemInfoCPUInfo); - ASSERT_TRUE(state.crashed()); - ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION_WRITE"); - ASSERT_EQ(state.crash_address(), 0x45U); - ASSERT_EQ(state.threads()->size(), size_t(1)); - EXPECT_EQ((*state.threads())[0]->tid(), 3060U); - ASSERT_EQ(state.requesting_thread(), 0); - EXPECT_EQ(1171480435U, state.time_date_stamp()); - EXPECT_EQ(1171480435U, state.process_create_time()); - - CallStack *stack = state.threads()->at(0); - ASSERT_TRUE(stack); - ASSERT_EQ(stack->frames()->size(), 4U); - - ASSERT_TRUE(stack->frames()->at(0)->module); - ASSERT_EQ(stack->frames()->at(0)->module->base_address(), 0x400000U); - ASSERT_EQ(stack->frames()->at(0)->module->code_file(), "c:\\test_app.exe"); - ASSERT_EQ(stack->frames()->at(0)->function_name, - "`anonymous namespace'::CrashFunction"); - ASSERT_EQ(stack->frames()->at(0)->source_file_name, "c:\\test_app.cc"); - ASSERT_EQ(stack->frames()->at(0)->source_line, 58); - - ASSERT_TRUE(stack->frames()->at(1)->module); - ASSERT_EQ(stack->frames()->at(1)->module->base_address(), 0x400000U); - ASSERT_EQ(stack->frames()->at(1)->module->code_file(), "c:\\test_app.exe"); - ASSERT_EQ(stack->frames()->at(1)->function_name, "main"); - ASSERT_EQ(stack->frames()->at(1)->source_file_name, "c:\\test_app.cc"); - ASSERT_EQ(stack->frames()->at(1)->source_line, 65); - - // This comes from the CRT - ASSERT_TRUE(stack->frames()->at(2)->module); - ASSERT_EQ(stack->frames()->at(2)->module->base_address(), 0x400000U); - ASSERT_EQ(stack->frames()->at(2)->module->code_file(), "c:\\test_app.exe"); - ASSERT_EQ(stack->frames()->at(2)->function_name, "__tmainCRTStartup"); - ASSERT_EQ(stack->frames()->at(2)->source_file_name, - "f:\\sp\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c"); - ASSERT_EQ(stack->frames()->at(2)->source_line, 327); - - // No debug info available for kernel32.dll - ASSERT_TRUE(stack->frames()->at(3)->module); - ASSERT_EQ(stack->frames()->at(3)->module->base_address(), 0x7c800000U); - ASSERT_EQ(stack->frames()->at(3)->module->code_file(), - "C:\\WINDOWS\\system32\\kernel32.dll"); - ASSERT_TRUE(stack->frames()->at(3)->function_name.empty()); - ASSERT_TRUE(stack->frames()->at(3)->source_file_name.empty()); - ASSERT_EQ(stack->frames()->at(3)->source_line, 0); - - ASSERT_EQ(state.modules()->module_count(), 13U); - ASSERT_TRUE(state.modules()->GetMainModule()); - ASSERT_EQ(state.modules()->GetMainModule()->code_file(), "c:\\test_app.exe"); - ASSERT_FALSE(state.modules()->GetModuleForAddress(0)); - ASSERT_EQ(state.modules()->GetMainModule(), - state.modules()->GetModuleForAddress(0x400000)); - ASSERT_EQ(state.modules()->GetModuleForAddress(0x7c801234)->debug_file(), - "kernel32.pdb"); - ASSERT_EQ(state.modules()->GetModuleForAddress(0x77d43210)->version(), - "5.1.2600.2622"); - - // Test that disabled exploitability engine defaults to - // EXPLOITABILITY_NOT_ANALYZED. - ASSERT_EQ(google_breakpad::EXPLOITABILITY_NOT_ANALYZED, - state.exploitability()); - - // Test that the symbol supplier can interrupt processing - state.Clear(); - supplier.set_interrupt(true); - ASSERT_EQ(processor.Process(minidump_file, &state), - google_breakpad::PROCESS_SYMBOL_SUPPLIER_INTERRUPTED); -} - -TEST_F(MinidumpProcessorTest, TestThreadMissingMemory) { - MockMinidump dump; - EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump")); - EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true)); - - MDRawHeader fake_header; - fake_header.time_date_stamp = 0; - EXPECT_CALL(dump, header()).WillRepeatedly(Return(&fake_header)); - - MDRawSystemInfo raw_system_info; - memset(&raw_system_info, 0, sizeof(raw_system_info)); - raw_system_info.processor_architecture = MD_CPU_ARCHITECTURE_X86; - raw_system_info.platform_id = MD_OS_WIN32_NT; - TestMinidumpSystemInfo dump_system_info(raw_system_info); - - EXPECT_CALL(dump, GetSystemInfo()). - WillRepeatedly(Return(&dump_system_info)); - - MockMinidumpThreadList thread_list; - EXPECT_CALL(dump, GetThreadList()). - WillOnce(Return(&thread_list)); - - MockMinidumpMemoryList memory_list; - EXPECT_CALL(dump, GetMemoryList()). - WillOnce(Return(&memory_list)); - - // Return a thread missing stack memory. - MockMinidumpThread no_memory_thread; - EXPECT_CALL(no_memory_thread, GetThreadID(_)). - WillRepeatedly(DoAll(SetArgumentPointee<0>(1), - Return(true))); - EXPECT_CALL(no_memory_thread, GetMemory()). - WillRepeatedly(Return(reinterpret_cast(NULL))); - - const uint64_t kTestStartOfMemoryRange = 0x1234; - EXPECT_CALL(no_memory_thread, GetStartOfStackMemoryRange()). - WillRepeatedly(Return(kTestStartOfMemoryRange)); - EXPECT_CALL(memory_list, GetMemoryRegionForAddress(kTestStartOfMemoryRange)). - WillRepeatedly(Return(reinterpret_cast(NULL))); - - MDRawContextX86 no_memory_thread_raw_context; - memset(&no_memory_thread_raw_context, 0, - sizeof(no_memory_thread_raw_context)); - no_memory_thread_raw_context.context_flags = MD_CONTEXT_X86_FULL; - const uint32_t kExpectedEIP = 0xabcd1234; - no_memory_thread_raw_context.eip = kExpectedEIP; - TestMinidumpContext no_memory_thread_context(no_memory_thread_raw_context); - EXPECT_CALL(no_memory_thread, GetContext()). - WillRepeatedly(Return(&no_memory_thread_context)); - - EXPECT_CALL(thread_list, thread_count()). - WillRepeatedly(Return(1)); - EXPECT_CALL(thread_list, GetThreadAtIndex(0)). - WillOnce(Return(&no_memory_thread)); - - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); - ProcessState state; - EXPECT_EQ(processor.Process(&dump, &state), - google_breakpad::PROCESS_OK); - - // Should have a single thread with a single frame in it. - ASSERT_EQ(1U, state.threads()->size()); - ASSERT_EQ(1U, state.threads()->at(0)->frames()->size()); - ASSERT_EQ(kExpectedEIP, state.threads()->at(0)->frames()->at(0)->instruction); -} - -TEST_F(MinidumpProcessorTest, GetProcessCreateTime) { - const uint32_t kProcessCreateTime = 2000; - const uint32_t kTimeDateStamp = 5000; - MockMinidump dump; - EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump")); - EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true)); - - // Set time of crash. - MDRawHeader fake_header; - fake_header.time_date_stamp = kTimeDateStamp; - EXPECT_CALL(dump, header()).WillRepeatedly(Return(&fake_header)); - - // Set process create time. - MDRawMiscInfo raw_misc_info; - memset(&raw_misc_info, 0, sizeof(raw_misc_info)); - raw_misc_info.process_create_time = kProcessCreateTime; - raw_misc_info.flags1 |= MD_MISCINFO_FLAGS1_PROCESS_TIMES; - google_breakpad::TestMinidumpMiscInfo dump_misc_info(raw_misc_info); - EXPECT_CALL(dump, GetMiscInfo()).WillRepeatedly(Return(&dump_misc_info)); - - // No threads - MockMinidumpThreadList thread_list; - EXPECT_CALL(dump, GetThreadList()).WillOnce(Return(&thread_list)); - EXPECT_CALL(thread_list, thread_count()).WillRepeatedly(Return(0)); - - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); - ProcessState state; - EXPECT_EQ(google_breakpad::PROCESS_OK, processor.Process(&dump, &state)); - - // Verify the time stamps. - ASSERT_EQ(kTimeDateStamp, state.time_date_stamp()); - ASSERT_EQ(kProcessCreateTime, state.process_create_time()); -} - -TEST_F(MinidumpProcessorTest, TestThreadMissingContext) { - MockMinidump dump; - EXPECT_CALL(dump, path()).WillRepeatedly(Return("mock minidump")); - EXPECT_CALL(dump, Read()).WillRepeatedly(Return(true)); - - MDRawHeader fake_header; - fake_header.time_date_stamp = 0; - EXPECT_CALL(dump, header()).WillRepeatedly(Return(&fake_header)); - - MDRawSystemInfo raw_system_info; - memset(&raw_system_info, 0, sizeof(raw_system_info)); - raw_system_info.processor_architecture = MD_CPU_ARCHITECTURE_X86; - raw_system_info.platform_id = MD_OS_WIN32_NT; - TestMinidumpSystemInfo dump_system_info(raw_system_info); - - EXPECT_CALL(dump, GetSystemInfo()). - WillRepeatedly(Return(&dump_system_info)); - - MockMinidumpThreadList thread_list; - EXPECT_CALL(dump, GetThreadList()). - WillOnce(Return(&thread_list)); - - MockMinidumpMemoryList memory_list; - EXPECT_CALL(dump, GetMemoryList()). - WillOnce(Return(&memory_list)); - - // Return a thread missing a thread context. - MockMinidumpThread no_context_thread; - EXPECT_CALL(no_context_thread, GetThreadID(_)). - WillRepeatedly(DoAll(SetArgumentPointee<0>(1), - Return(true))); - EXPECT_CALL(no_context_thread, GetContext()). - WillRepeatedly(Return(reinterpret_cast(NULL))); - - // The memory contents don't really matter here, since it won't be used. - MockMinidumpMemoryRegion no_context_thread_memory(0x1234, "xxx"); - EXPECT_CALL(no_context_thread, GetMemory()). - WillRepeatedly(Return(&no_context_thread_memory)); - EXPECT_CALL(no_context_thread, GetStartOfStackMemoryRange()). - Times(0); - EXPECT_CALL(memory_list, GetMemoryRegionForAddress(_)). - Times(0); - - EXPECT_CALL(thread_list, thread_count()). - WillRepeatedly(Return(1)); - EXPECT_CALL(thread_list, GetThreadAtIndex(0)). - WillOnce(Return(&no_context_thread)); - - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); - ProcessState state; - EXPECT_EQ(processor.Process(&dump, &state), - google_breakpad::PROCESS_OK); - - // Should have a single thread with zero frames. - ASSERT_EQ(1U, state.threads()->size()); - ASSERT_EQ(0U, state.threads()->at(0)->frames()->size()); -} - -} // namespace - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk.cc deleted file mode 100644 index 8f83969fe..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_stackwalk.cc: Process a minidump with MinidumpProcessor, printing -// the results, including stack traces. -// -// Author: Mark Mentovai - -#include -#include - -#include -#include - -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/minidump_processor.h" -#include "google_breakpad/processor/process_state.h" -#include "processor/logging.h" -#include "processor/simple_symbol_supplier.h" -#include "processor/stackwalk_common.h" - - -namespace { - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::Minidump; -using google_breakpad::MinidumpProcessor; -using google_breakpad::ProcessState; -using google_breakpad::SimpleSymbolSupplier; -using google_breakpad::scoped_ptr; - -// Processes |minidump_file| using MinidumpProcessor. |symbol_path|, if -// non-empty, is the base directory of a symbol storage area, laid out in -// the format required by SimpleSymbolSupplier. If such a storage area -// is specified, it is made available for use by the MinidumpProcessor. -// -// Returns the value of MinidumpProcessor::Process. If processing succeeds, -// prints identifying OS and CPU information from the minidump, crash -// information if the minidump was produced as a result of a crash, and -// call stacks for each thread contained in the minidump. All information -// is printed to stdout. -bool PrintMinidumpProcess(const string &minidump_file, - const std::vector &symbol_paths, - bool machine_readable, - bool output_stack_contents) { - scoped_ptr symbol_supplier; - if (!symbol_paths.empty()) { - // TODO(mmentovai): check existence of symbol_path if specified? - symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths)); - } - - BasicSourceLineResolver resolver; - MinidumpProcessor minidump_processor(symbol_supplier.get(), &resolver); - - // Process the minidump. - Minidump dump(minidump_file); - if (!dump.Read()) { - BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read"; - return false; - } - ProcessState process_state; - if (minidump_processor.Process(&dump, &process_state) != - google_breakpad::PROCESS_OK) { - BPLOG(ERROR) << "MinidumpProcessor::Process failed"; - return false; - } - - if (machine_readable) { - PrintProcessStateMachineReadable(process_state); - } else { - PrintProcessState(process_state, output_stack_contents, &resolver); - } - - return true; -} - -void usage(const char *program_name) { - fprintf(stderr, "usage: %s [-m|-s] [symbol-path ...]\n" - " -m : Output in machine-readable format\n" - " -s : Output stack contents\n", - program_name); -} - -} // namespace - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - if (argc < 2) { - usage(argv[0]); - return 1; - } - - const char *minidump_file; - bool machine_readable = false; - bool output_stack_contents = false; - int symbol_path_arg; - - if (strcmp(argv[1], "-m") == 0) { - if (argc < 3) { - usage(argv[0]); - return 1; - } - - machine_readable = true; - minidump_file = argv[2]; - symbol_path_arg = 3; - } else if (strcmp(argv[1], "-s") == 0) { - if (argc < 3) { - usage(argv[0]); - return 1; - } - - output_stack_contents = true; - minidump_file = argv[2]; - symbol_path_arg = 3; - } else { - minidump_file = argv[1]; - symbol_path_arg = 2; - } - - // extra arguments are symbol paths - std::vector symbol_paths; - if (argc > symbol_path_arg) { - for (int argi = symbol_path_arg; argi < argc; ++argi) - symbol_paths.push_back(argv[argi]); - } - - return PrintMinidumpProcess(minidump_file, - symbol_paths, - machine_readable, - output_stack_contents) ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_machine_readable_test b/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_machine_readable_test deleted file mode 100755 index 2aadb2412..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_machine_readable_test +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -testdata_dir=$srcdir/src/processor/testdata -./src/processor/minidump_stackwalk -m $testdata_dir/minidump2.dmp \ - $testdata_dir/symbols | \ - tr -d '\015' | \ - diff -u $testdata_dir/minidump2.stackwalk.machine_readable.out - -exit $? diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_test b/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_test deleted file mode 100755 index f97902791..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_test +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2006, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -testdata_dir=$srcdir/src/processor/testdata -./src/processor/minidump_stackwalk $testdata_dir/minidump2.dmp \ - $testdata_dir/symbols | \ - tr -d '\015' | \ - diff -u $testdata_dir/minidump2.stackwalk.out - -exit $? diff --git a/toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc deleted file mode 100644 index d29e9f4e5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc +++ /dev/null @@ -1,1521 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Unit test for Minidump. Uses a pre-generated minidump and -// verifies that certain streams are correct. - -#include -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/minidump.h" -#include "processor/logging.h" -#include "processor/synth_minidump.h" - -namespace { - -using google_breakpad::Minidump; -using google_breakpad::MinidumpContext; -using google_breakpad::MinidumpException; -using google_breakpad::MinidumpMemoryInfo; -using google_breakpad::MinidumpMemoryInfoList; -using google_breakpad::MinidumpMemoryList; -using google_breakpad::MinidumpMemoryRegion; -using google_breakpad::MinidumpModule; -using google_breakpad::MinidumpModuleList; -using google_breakpad::MinidumpSystemInfo; -using google_breakpad::MinidumpThread; -using google_breakpad::MinidumpThreadList; -using google_breakpad::SynthMinidump::Context; -using google_breakpad::SynthMinidump::Dump; -using google_breakpad::SynthMinidump::Exception; -using google_breakpad::SynthMinidump::Memory; -using google_breakpad::SynthMinidump::Module; -using google_breakpad::SynthMinidump::Section; -using google_breakpad::SynthMinidump::Stream; -using google_breakpad::SynthMinidump::String; -using google_breakpad::SynthMinidump::SystemInfo; -using google_breakpad::SynthMinidump::Thread; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using std::ifstream; -using std::istringstream; -using std::vector; -using ::testing::Return; - -class MinidumpTest : public ::testing::Test { -public: - void SetUp() { - minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/minidump2.dmp"; - } - string minidump_file_; -}; - -TEST_F(MinidumpTest, TestMinidumpFromFile) { - Minidump minidump(minidump_file_); - ASSERT_EQ(minidump.path(), minidump_file_); - ASSERT_TRUE(minidump.Read()); - const MDRawHeader* header = minidump.header(); - ASSERT_NE(header, (MDRawHeader*)NULL); - ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); - - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); - ASSERT_EQ("c:\\test_app.exe", md_module->code_file()); - ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file()); - ASSERT_EQ("45D35F6C2d000", md_module->code_identifier()); - ASSERT_EQ("5A9832E5287241C1838ED98914E9B7FF1", md_module->debug_identifier()); -} - -TEST_F(MinidumpTest, TestMinidumpFromStream) { - // read minidump contents into memory, construct a stringstream around them - ifstream file_stream(minidump_file_.c_str(), std::ios::in); - ASSERT_TRUE(file_stream.good()); - vector bytes; - file_stream.seekg(0, std::ios_base::end); - ASSERT_TRUE(file_stream.good()); - bytes.resize(file_stream.tellg()); - file_stream.seekg(0, std::ios_base::beg); - ASSERT_TRUE(file_stream.good()); - file_stream.read(&bytes[0], bytes.size()); - ASSERT_TRUE(file_stream.good()); - string str(&bytes[0], bytes.size()); - istringstream stream(str); - ASSERT_TRUE(stream.good()); - - // now read minidump from stringstream - Minidump minidump(stream); - ASSERT_EQ(minidump.path(), ""); - ASSERT_TRUE(minidump.Read()); - const MDRawHeader* header = minidump.header(); - ASSERT_NE(header, (MDRawHeader*)NULL); - ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); - //TODO: add more checks here -} - -TEST(Dump, ReadBackEmpty) { - Dump dump(0); - dump.Finish(); - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream stream(contents); - Minidump minidump(stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(0U, minidump.GetDirectoryEntryCount()); -} - -TEST(Dump, ReadBackEmptyBigEndian) { - Dump big_minidump(0, kBigEndian); - big_minidump.Finish(); - string contents; - ASSERT_TRUE(big_minidump.GetContents(&contents)); - istringstream stream(contents); - Minidump minidump(stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(0U, minidump.GetDirectoryEntryCount()); -} - -TEST(Dump, OneStream) { - Dump dump(0, kBigEndian); - Stream stream(dump, 0xfbb7fa2bU); - stream.Append("stream contents"); - dump.Add(&stream); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); - EXPECT_EQ(0xfbb7fa2bU, dir->stream_type); - - uint32_t stream_length; - ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length)); - ASSERT_EQ(15U, stream_length); - char stream_contents[15]; - ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents))); - EXPECT_EQ(string("stream contents"), - string(stream_contents, sizeof(stream_contents))); - - EXPECT_FALSE(minidump.GetThreadList()); - EXPECT_FALSE(minidump.GetModuleList()); - EXPECT_FALSE(minidump.GetMemoryList()); - EXPECT_FALSE(minidump.GetException()); - EXPECT_FALSE(minidump.GetAssertion()); - EXPECT_FALSE(minidump.GetSystemInfo()); - EXPECT_FALSE(minidump.GetMiscInfo()); - EXPECT_FALSE(minidump.GetBreakpadInfo()); -} - -TEST(Dump, OneMemory) { - Dump dump(0, kBigEndian); - Memory memory(dump, 0x309d68010bd21b2cULL); - memory.Append("memory contents"); - dump.Add(&memory); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); - EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type); - - MinidumpMemoryList *memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(memory_list != NULL); - ASSERT_EQ(1U, memory_list->region_count()); - - MinidumpMemoryRegion *region1 = memory_list->GetMemoryRegionAtIndex(0); - ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase()); - ASSERT_EQ(15U, region1->GetSize()); - const uint8_t *region1_bytes = region1->GetMemory(); - ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0); -} - -// One thread --- and its requisite entourage. -TEST(Dump, OneThread) { - Dump dump(0, kLittleEndian); - Memory stack(dump, 0x2326a0fa); - stack.Append("stack for thread"); - - MDRawContextX86 raw_context; - const uint32_t kExpectedEIP = 0x6913f540; - raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL; - raw_context.edi = 0x3ecba80d; - raw_context.esi = 0x382583b9; - raw_context.ebx = 0x7fccc03f; - raw_context.edx = 0xf62f8ec2; - raw_context.ecx = 0x46a6a6a8; - raw_context.eax = 0x6a5025e2; - raw_context.ebp = 0xd9fabb4a; - raw_context.eip = kExpectedEIP; - raw_context.cs = 0xbffe6eda; - raw_context.eflags = 0xb2ce1e2d; - raw_context.esp = 0x659caaa4; - raw_context.ss = 0x2e951ef7; - Context context(dump, raw_context); - - Thread thread(dump, 0xa898f11b, stack, context, - 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL); - - dump.Add(&stack); - dump.Add(&context); - dump.Add(&thread); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - MinidumpMemoryList *md_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(md_memory_list != NULL); - ASSERT_EQ(1U, md_memory_list->region_count()); - - MinidumpMemoryRegion *md_region = md_memory_list->GetMemoryRegionAtIndex(0); - ASSERT_EQ(0x2326a0faU, md_region->GetBase()); - ASSERT_EQ(16U, md_region->GetSize()); - const uint8_t *region_bytes = md_region->GetMemory(); - ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0); - - MinidumpThreadList *thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); - ASSERT_EQ(1U, thread_list->thread_count()); - - MinidumpThread *md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); - uint32_t thread_id; - ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); - ASSERT_EQ(0xa898f11bU, thread_id); - MinidumpMemoryRegion *md_stack = md_thread->GetMemory(); - ASSERT_TRUE(md_stack != NULL); - ASSERT_EQ(0x2326a0faU, md_stack->GetBase()); - ASSERT_EQ(16U, md_stack->GetSize()); - const uint8_t *md_stack_bytes = md_stack->GetMemory(); - ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0); - - MinidumpContext *md_context = md_thread->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); - - uint64_t eip; - ASSERT_TRUE(md_context->GetInstructionPointer(&eip)); - EXPECT_EQ(kExpectedEIP, eip); - - const MDRawContextX86 *md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), - (md_raw_context->context_flags - & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); - EXPECT_EQ(0x3ecba80dU, raw_context.edi); - EXPECT_EQ(0x382583b9U, raw_context.esi); - EXPECT_EQ(0x7fccc03fU, raw_context.ebx); - EXPECT_EQ(0xf62f8ec2U, raw_context.edx); - EXPECT_EQ(0x46a6a6a8U, raw_context.ecx); - EXPECT_EQ(0x6a5025e2U, raw_context.eax); - EXPECT_EQ(0xd9fabb4aU, raw_context.ebp); - EXPECT_EQ(kExpectedEIP, raw_context.eip); - EXPECT_EQ(0xbffe6edaU, raw_context.cs); - EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags); - EXPECT_EQ(0x659caaa4U, raw_context.esp); - EXPECT_EQ(0x2e951ef7U, raw_context.ss); -} - -TEST(Dump, ThreadMissingMemory) { - Dump dump(0, kLittleEndian); - Memory stack(dump, 0x2326a0fa); - // Stack has no contents. - - MDRawContextX86 raw_context; - memset(&raw_context, 0, sizeof(raw_context)); - raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL; - Context context(dump, raw_context); - - Thread thread(dump, 0xa898f11b, stack, context, - 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL); - - dump.Add(&stack); - dump.Add(&context); - dump.Add(&thread); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - // This should succeed even though the thread has no stack memory. - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); - ASSERT_EQ(1U, thread_list->thread_count()); - - MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); - ASSERT_EQ(0xa898f11bU, thread_id); - - MinidumpContext* md_context = md_thread->GetContext(); - ASSERT_NE(reinterpret_cast(NULL), md_context); - - MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); - ASSERT_EQ(reinterpret_cast(NULL), md_stack); -} - -TEST(Dump, ThreadMissingContext) { - Dump dump(0, kLittleEndian); - Memory stack(dump, 0x2326a0fa); - stack.Append("stack for thread"); - - // Context is empty. - Context context(dump); - - Thread thread(dump, 0xa898f11b, stack, context, - 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL); - - dump.Add(&stack); - dump.Add(&context); - dump.Add(&thread); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - // This should succeed even though the thread has no stack memory. - MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); - ASSERT_EQ(1U, thread_list->thread_count()); - - MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); - ASSERT_EQ(0xa898f11bU, thread_id); - MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); - ASSERT_NE(reinterpret_cast(NULL), md_stack); - - MinidumpContext* md_context = md_thread->GetContext(); - ASSERT_EQ(reinterpret_cast(NULL), md_context); -} - -static const MDVSFixedFileInfo fixed_file_info = { - 0xb2fba33a, // signature - 0x33d7a728, // struct_version - 0x31afcb20, // file_version_hi - 0xe51cdab1, // file_version_lo - 0xd1ea6907, // product_version_hi - 0x03032857, // product_version_lo - 0x11bf71d7, // file_flags_mask - 0x5fb8cdbf, // file_flags - 0xe45d0d5d, // file_os - 0x107d9562, // file_type - 0x5a8844d4, // file_subtype - 0xa8d30b20, // file_date_hi - 0x651c3e4e // file_date_lo -}; - -TEST(Dump, OneModule) { - Dump dump(0, kBigEndian); - String module_name(dump, "single module"); - Section cv_info(dump); - cv_info - .D32(MD_CVINFOPDB70_SIGNATURE) // signature - // signature, a MDGUID - .D32(0xabcd1234) - .D16(0xf00d) - .D16(0xbeef) - .Append("\x01\x02\x03\x04\x05\x06\x07\x08") - .D32(1) // age - .AppendCString("c:\\foo\\file.pdb"); // pdb_file_name - - String csd_version(dump, "Windows 9000"); - SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); - - Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, - module_name, - 0xb1054d2a, - 0x34571371, - fixed_file_info, // from synth_minidump_unittest_data.h - &cv_info, nullptr); - - dump.Add(&module); - dump.Add(&module_name); - dump.Add(&cv_info); - dump.Add(&system_info); - dump.Add(&csd_version); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(1); - ASSERT_TRUE(dir != NULL); - EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type); - - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - ASSERT_EQ(1U, md_module_list->module_count()); - - const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); - ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); - ASSERT_EQ(0xada542bd, md_module->size()); - ASSERT_EQ("single module", md_module->code_file()); - ASSERT_EQ("c:\\foo\\file.pdb", md_module->debug_file()); - // time_date_stamp and size_of_image concatenated - ASSERT_EQ("B1054D2Aada542bd", md_module->code_identifier()); - ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier()); - - const MDRawModule *md_raw_module = md_module->module(); - ASSERT_TRUE(md_raw_module != NULL); - ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); - ASSERT_EQ(0x34571371U, md_raw_module->checksum); - ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, - sizeof(fixed_file_info)) == 0); -} - -// Test that a module with a MDCVInfoELF CV record is handled properly. -TEST(Dump, OneModuleCVELF) { - Dump dump(0, kLittleEndian); - String module_name(dump, "elf module"); - Section cv_info(dump); - cv_info - .D32(MD_CVINFOELF_SIGNATURE) // signature - // build_id - .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf" - "\x37\x38\xce\xa3\x4a\x87"); - - const MDRawSystemInfo linux_x86 = { - MD_CPU_ARCHITECTURE_X86, // processor_architecture - 6, // processor_level - 0xd08, // processor_revision - 1, // number_of_processors - 0, // product_type - 0, // major_version - 0, // minor_version - 0, // build_number - MD_OS_LINUX, // platform_id - 0xdeadbeef, // csd_version_rva - 0x100, // suite_mask - 0, // reserved2 - { // cpu - { // x86_cpu_info - { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id - 0x6d8, // version_information - 0xafe9fbff, // feature_information - 0xffffffff // amd_extended_cpu_features - } - } - }; - String csd_version(dump, "Literally Linux"); - SystemInfo system_info(dump, linux_x86, csd_version); - - Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, - module_name, - 0xb1054d2a, - 0x34571371, - fixed_file_info, // from synth_minidump_unittest_data.h - &cv_info, nullptr); - - dump.Add(&module); - dump.Add(&module_name); - dump.Add(&cv_info); - dump.Add(&system_info); - dump.Add(&csd_version); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - ASSERT_EQ(1U, md_module_list->module_count()); - - const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); - ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); - ASSERT_EQ(0xada542bd, md_module->size()); - ASSERT_EQ("elf module", md_module->code_file()); - // debug_file == code_file - ASSERT_EQ("elf module", md_module->debug_file()); - // just the build_id, directly - ASSERT_EQ("5fa9cdb41053df1b86fab733b4df3738cea34a87", - md_module->code_identifier()); - // build_id truncted to GUID length and treated as such, with zero - // age appended - ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier()); - - const MDRawModule *md_raw_module = md_module->module(); - ASSERT_TRUE(md_raw_module != NULL); - ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); - ASSERT_EQ(0x34571371U, md_raw_module->checksum); - ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, - sizeof(fixed_file_info)) == 0); -} - -// Test that a build_id that's shorter than a GUID is handled properly. -TEST(Dump, CVELFShort) { - Dump dump(0, kLittleEndian); - String module_name(dump, "elf module"); - Section cv_info(dump); - cv_info - .D32(MD_CVINFOELF_SIGNATURE) // signature - // build_id, shorter than a GUID - .Append("\x5f\xa9\xcd\xb4"); - - const MDRawSystemInfo linux_x86 = { - MD_CPU_ARCHITECTURE_X86, // processor_architecture - 6, // processor_level - 0xd08, // processor_revision - 1, // number_of_processors - 0, // product_type - 0, // major_version - 0, // minor_version - 0, // build_number - MD_OS_LINUX, // platform_id - 0xdeadbeef, // csd_version_rva - 0x100, // suite_mask - 0, // reserved2 - { // cpu - { // x86_cpu_info - { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id - 0x6d8, // version_information - 0xafe9fbff, // feature_information - 0xffffffff // amd_extended_cpu_features - } - } - }; - String csd_version(dump, "Literally Linux"); - SystemInfo system_info(dump, linux_x86, csd_version); - - Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, - module_name, - 0xb1054d2a, - 0x34571371, - fixed_file_info, // from synth_minidump_unittest_data.h - &cv_info, nullptr); - - dump.Add(&module); - dump.Add(&module_name); - dump.Add(&cv_info); - dump.Add(&system_info); - dump.Add(&csd_version); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - ASSERT_EQ(1U, md_module_list->module_count()); - - const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); - // just the build_id, directly - ASSERT_EQ("5fa9cdb4", md_module->code_identifier()); - // build_id expanded to GUID length and treated as such, with zero - // age appended - ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier()); -} - -// Test that a build_id that's very long is handled properly. -TEST(Dump, CVELFLong) { - Dump dump(0, kLittleEndian); - String module_name(dump, "elf module"); - Section cv_info(dump); - cv_info - .D32(MD_CVINFOELF_SIGNATURE) // signature - // build_id, lots of bytes - .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf" - "\x37\x38\xce\xa3\x4a\x87\x01\x02\x03\x04\x05\x06\x07\x08" - "\x09\x0a\x0b\x0c\x0d\x0e\x0f"); - - - const MDRawSystemInfo linux_x86 = { - MD_CPU_ARCHITECTURE_X86, // processor_architecture - 6, // processor_level - 0xd08, // processor_revision - 1, // number_of_processors - 0, // product_type - 0, // major_version - 0, // minor_version - 0, // build_number - MD_OS_LINUX, // platform_id - 0xdeadbeef, // csd_version_rva - 0x100, // suite_mask - 0, // reserved2 - { // cpu - { // x86_cpu_info - { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id - 0x6d8, // version_information - 0xafe9fbff, // feature_information - 0xffffffff // amd_extended_cpu_features - } - } - }; - String csd_version(dump, "Literally Linux"); - SystemInfo system_info(dump, linux_x86, csd_version); - - Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd, - module_name, - 0xb1054d2a, - 0x34571371, - fixed_file_info, // from synth_minidump_unittest_data.h - &cv_info, nullptr); - - dump.Add(&module); - dump.Add(&module_name); - dump.Add(&cv_info); - dump.Add(&system_info); - dump.Add(&csd_version); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - ASSERT_EQ(1U, md_module_list->module_count()); - - const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); - // just the build_id, directly - ASSERT_EQ( - "5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f", - md_module->code_identifier()); - // build_id truncated to GUID length and treated as such, with zero - // age appended. - ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier()); -} - -TEST(Dump, OneSystemInfo) { - Dump dump(0, kLittleEndian); - String csd_version(dump, "Petulant Pierogi"); - SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); - - dump.Add(&system_info); - dump.Add(&csd_version); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); - EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type); - - MinidumpSystemInfo *md_system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(md_system_info != NULL); - ASSERT_EQ("windows", md_system_info->GetOS()); - ASSERT_EQ("x86", md_system_info->GetCPU()); - ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion()); - ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor()); -} - -TEST(Dump, BigDump) { - Dump dump(0, kLittleEndian); - - // A SystemInfo stream. - String csd_version(dump, "Munificent Macaque"); - SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); - dump.Add(&csd_version); - dump.Add(&system_info); - - // Five threads! - Memory stack0(dump, 0x70b9ebfc); - stack0.Append("stack for thread zero"); - MDRawContextX86 raw_context0; - raw_context0.context_flags = MD_CONTEXT_X86_INTEGER; - raw_context0.eip = 0xaf0709e4; - Context context0(dump, raw_context0); - Thread thread0(dump, 0xbbef4432, stack0, context0, - 0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL); - dump.Add(&stack0); - dump.Add(&context0); - dump.Add(&thread0); - - Memory stack1(dump, 0xf988cc45); - stack1.Append("stack for thread one"); - MDRawContextX86 raw_context1; - raw_context1.context_flags = MD_CONTEXT_X86_INTEGER; - raw_context1.eip = 0xe4f56f81; - Context context1(dump, raw_context1); - Thread thread1(dump, 0x657c3f58, stack1, context1, - 0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL); - dump.Add(&stack1); - dump.Add(&context1); - dump.Add(&thread1); - - Memory stack2(dump, 0xc8a92e7c); - stack2.Append("stack for thread two"); - MDRawContextX86 raw_context2; - raw_context2.context_flags = MD_CONTEXT_X86_INTEGER; - raw_context2.eip = 0xb336a438; - Context context2(dump, raw_context2); - Thread thread2(dump, 0xdf4b8a71, stack2, context2, - 0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL); - dump.Add(&stack2); - dump.Add(&context2); - dump.Add(&thread2); - - Memory stack3(dump, 0x36d08e08); - stack3.Append("stack for thread three"); - MDRawContextX86 raw_context3; - raw_context3.context_flags = MD_CONTEXT_X86_INTEGER; - raw_context3.eip = 0xdf99a60c; - Context context3(dump, raw_context3); - Thread thread3(dump, 0x86e6c341, stack3, context3, - 0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL); - dump.Add(&stack3); - dump.Add(&context3); - dump.Add(&thread3); - - Memory stack4(dump, 0x1e0ab4fa); - stack4.Append("stack for thread four"); - MDRawContextX86 raw_context4; - raw_context4.context_flags = MD_CONTEXT_X86_INTEGER; - raw_context4.eip = 0xaa646267; - Context context4(dump, raw_context4); - Thread thread4(dump, 0x261a28d4, stack4, context4, - 0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL); - dump.Add(&stack4); - dump.Add(&context4); - dump.Add(&thread4); - - // Three modules! - String module1_name(dump, "module one"); - Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name); - dump.Add(&module1_name); - dump.Add(&module1); - - String module2_name(dump, "module two"); - Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name); - dump.Add(&module2_name); - dump.Add(&module2); - - String module3_name(dump, "module three"); - Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name); - dump.Add(&module3_name); - dump.Add(&module3); - - // Add one more memory region, on top of the five stacks. - Memory memory5(dump, 0x61979e828040e564ULL); - memory5.Append("contents of memory 5"); - dump.Add(&memory5); - - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(4U, minidump.GetDirectoryEntryCount()); - - // Check the threads. - MinidumpThreadList *thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); - ASSERT_EQ(5U, thread_list->thread_count()); - uint32_t thread_id; - ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id)); - ASSERT_EQ(0xbbef4432U, thread_id); - ASSERT_EQ(0x70b9ebfcU, - thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase()); - ASSERT_EQ(0xaf0709e4U, - thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86() - ->eip); - - ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id)); - ASSERT_EQ(0x657c3f58U, thread_id); - ASSERT_EQ(0xf988cc45U, - thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase()); - ASSERT_EQ(0xe4f56f81U, - thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86() - ->eip); - - ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id)); - ASSERT_EQ(0xdf4b8a71U, thread_id); - ASSERT_EQ(0xc8a92e7cU, - thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase()); - ASSERT_EQ(0xb336a438U, - thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86() - ->eip); - - ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id)); - ASSERT_EQ(0x86e6c341U, thread_id); - ASSERT_EQ(0x36d08e08U, - thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase()); - ASSERT_EQ(0xdf99a60cU, - thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86() - ->eip); - - ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id)); - ASSERT_EQ(0x261a28d4U, thread_id); - ASSERT_EQ(0x1e0ab4faU, - thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase()); - ASSERT_EQ(0xaa646267U, - thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86() - ->eip); - - // Check the modules. - MinidumpModuleList *md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); - ASSERT_EQ(3U, md_module_list->module_count()); - EXPECT_EQ(0xeb77da57b5d4cbdaULL, - md_module_list->GetModuleAtIndex(0)->base_address()); - EXPECT_EQ(0x8675884adfe5ac90ULL, - md_module_list->GetModuleAtIndex(1)->base_address()); - EXPECT_EQ(0x95fc1544da321b6cULL, - md_module_list->GetModuleAtIndex(2)->base_address()); -} - -TEST(Dump, OneMemoryInfo) { - Dump dump(0, kBigEndian); - Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM); - - // Add the MDRawMemoryInfoList header. - const uint64_t kNumberOfEntries = 1; - stream.D32(sizeof(MDRawMemoryInfoList)) // size_of_header - .D32(sizeof(MDRawMemoryInfo)) // size_of_entry - .D64(kNumberOfEntries); // number_of_entries - - - // Now add a MDRawMemoryInfo entry. - const uint64_t kBaseAddress = 0x1000; - const uint64_t kRegionSize = 0x2000; - stream.D64(kBaseAddress) // base_address - .D64(kBaseAddress) // allocation_base - .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE) // allocation_protection - .D32(0) // __alignment1 - .D64(kRegionSize) // region_size - .D32(MD_MEMORY_STATE_COMMIT) // state - .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE) // protection - .D32(MD_MEMORY_TYPE_PRIVATE) // type - .D32(0); // __alignment2 - - dump.Add(&stream); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); - EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type); - - MinidumpMemoryInfoList *info_list = minidump.GetMemoryInfoList(); - ASSERT_TRUE(info_list != NULL); - ASSERT_EQ(1U, info_list->info_count()); - - const MinidumpMemoryInfo *info1 = info_list->GetMemoryInfoAtIndex(0); - ASSERT_EQ(kBaseAddress, info1->GetBase()); - ASSERT_EQ(kRegionSize, info1->GetSize()); - ASSERT_TRUE(info1->IsExecutable()); - ASSERT_TRUE(info1->IsWritable()); - - // Should get back the same memory region here. - const MinidumpMemoryInfo *info2 = - info_list->GetMemoryInfoForAddress(kBaseAddress + kRegionSize / 2); - ASSERT_EQ(kBaseAddress, info2->GetBase()); - ASSERT_EQ(kRegionSize, info2->GetSize()); -} - -TEST(Dump, OneExceptionX86) { - Dump dump(0, kLittleEndian); - - MDRawContextX86 raw_context; - raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL; - raw_context.edi = 0x3ecba80d; - raw_context.esi = 0x382583b9; - raw_context.ebx = 0x7fccc03f; - raw_context.edx = 0xf62f8ec2; - raw_context.ecx = 0x46a6a6a8; - raw_context.eax = 0x6a5025e2; - raw_context.ebp = 0xd9fabb4a; - raw_context.eip = 0x6913f540; - raw_context.cs = 0xbffe6eda; - raw_context.eflags = 0xb2ce1e2d; - raw_context.esp = 0x659caaa4; - raw_context.ss = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); - const MDRawContextX86 *md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), - (md_raw_context->context_flags - & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); - EXPECT_EQ(0x3ecba80dU, raw_context.edi); - EXPECT_EQ(0x382583b9U, raw_context.esi); - EXPECT_EQ(0x7fccc03fU, raw_context.ebx); - EXPECT_EQ(0xf62f8ec2U, raw_context.edx); - EXPECT_EQ(0x46a6a6a8U, raw_context.ecx); - EXPECT_EQ(0x6a5025e2U, raw_context.eax); - EXPECT_EQ(0xd9fabb4aU, raw_context.ebp); - EXPECT_EQ(0x6913f540U, raw_context.eip); - EXPECT_EQ(0xbffe6edaU, raw_context.cs); - EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags); - EXPECT_EQ(0x659caaa4U, raw_context.esp); - EXPECT_EQ(0x2e951ef7U, raw_context.ss); -} - -TEST(Dump, OneExceptionX86XState) { - Dump dump(0, kLittleEndian); - - MDRawContextX86 raw_context; - raw_context.context_flags = MD_CONTEXT_X86_INTEGER | - MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE; - raw_context.edi = 0x3ecba80d; - raw_context.esi = 0x382583b9; - raw_context.ebx = 0x7fccc03f; - raw_context.edx = 0xf62f8ec2; - raw_context.ecx = 0x46a6a6a8; - raw_context.eax = 0x6a5025e2; - raw_context.ebp = 0xd9fabb4a; - raw_context.eip = 0x6913f540; - raw_context.cs = 0xbffe6eda; - raw_context.eflags = 0xb2ce1e2d; - raw_context.esp = 0x659caaa4; - raw_context.ss = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); - const MDRawContextX86 *md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), - (md_raw_context->context_flags - & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); - EXPECT_EQ(0x3ecba80dU, raw_context.edi); - EXPECT_EQ(0x382583b9U, raw_context.esi); - EXPECT_EQ(0x7fccc03fU, raw_context.ebx); - EXPECT_EQ(0xf62f8ec2U, raw_context.edx); - EXPECT_EQ(0x46a6a6a8U, raw_context.ecx); - EXPECT_EQ(0x6a5025e2U, raw_context.eax); - EXPECT_EQ(0xd9fabb4aU, raw_context.ebp); - EXPECT_EQ(0x6913f540U, raw_context.eip); - EXPECT_EQ(0xbffe6edaU, raw_context.cs); - EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags); - EXPECT_EQ(0x659caaa4U, raw_context.esp); - EXPECT_EQ(0x2e951ef7U, raw_context.ss); -} - -// Testing that the CPU type can be loaded from a system info stream when -// the CPU flags are missing from the context_flags of an exception record -TEST(Dump, OneExceptionX86NoCPUFlags) { - Dump dump(0, kLittleEndian); - - MDRawContextX86 raw_context; - // Intentionally not setting CPU type in the context_flags - raw_context.context_flags = 0; - raw_context.edi = 0x3ecba80d; - raw_context.esi = 0x382583b9; - raw_context.ebx = 0x7fccc03f; - raw_context.edx = 0xf62f8ec2; - raw_context.ecx = 0x46a6a6a8; - raw_context.eax = 0x6a5025e2; - raw_context.ebp = 0xd9fabb4a; - raw_context.eip = 0x6913f540; - raw_context.cs = 0xbffe6eda; - raw_context.eflags = 0xb2ce1e2d; - raw_context.esp = 0x659caaa4; - raw_context.ss = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - - // Add system info. This is needed as an alternative source for CPU type - // information. Note, that the CPU flags were intentionally skipped from - // the context_flags and this alternative source is required. - String csd_version(dump, "Service Pack 2"); - SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version); - dump.Add(&system_info); - dump.Add(&csd_version); - - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - - ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); - const MDRawContextX86 *md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); - - // Even though the CPU flags were missing from the context_flags, the - // GetContext call above is expected to load the missing CPU flags from the - // system info stream and set the CPU type bits in context_flags. - ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags); - - EXPECT_EQ(0x3ecba80dU, raw_context.edi); - EXPECT_EQ(0x382583b9U, raw_context.esi); - EXPECT_EQ(0x7fccc03fU, raw_context.ebx); - EXPECT_EQ(0xf62f8ec2U, raw_context.edx); - EXPECT_EQ(0x46a6a6a8U, raw_context.ecx); - EXPECT_EQ(0x6a5025e2U, raw_context.eax); - EXPECT_EQ(0xd9fabb4aU, raw_context.ebp); - EXPECT_EQ(0x6913f540U, raw_context.eip); - EXPECT_EQ(0xbffe6edaU, raw_context.cs); - EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags); - EXPECT_EQ(0x659caaa4U, raw_context.esp); - EXPECT_EQ(0x2e951ef7U, raw_context.ss); -} - -// This test covers a scenario where a dump contains an exception but the -// context record of the exception is missing the CPU type information in its -// context_flags. The dump has no system info stream so it is imposible to -// deduce the CPU type, hence the context record is unusable. -TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) { - Dump dump(0, kLittleEndian); - - MDRawContextX86 raw_context; - // Intentionally not setting CPU type in the context_flags - raw_context.context_flags = 0; - raw_context.edi = 0x3ecba80d; - raw_context.esi = 0x382583b9; - raw_context.ebx = 0x7fccc03f; - raw_context.edx = 0xf62f8ec2; - raw_context.ecx = 0x46a6a6a8; - raw_context.eax = 0x6a5025e2; - raw_context.ebp = 0xd9fabb4a; - raw_context.eip = 0x6913f540; - raw_context.cs = 0xbffe6eda; - raw_context.eflags = 0xb2ce1e2d; - raw_context.esp = 0x659caaa4; - raw_context.ss = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - // The context record of the exception is unusable because the context_flags - // don't have CPU type information and at the same time the minidump lacks - // system info stream so it is impossible to deduce the CPU type. - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_EQ(NULL, md_context); -} - -TEST(Dump, OneExceptionARM) { - Dump dump(0, kLittleEndian); - - MDRawContextARM raw_context; - raw_context.context_flags = MD_CONTEXT_ARM_INTEGER; - raw_context.iregs[0] = 0x3ecba80d; - raw_context.iregs[1] = 0x382583b9; - raw_context.iregs[2] = 0x7fccc03f; - raw_context.iregs[3] = 0xf62f8ec2; - raw_context.iregs[4] = 0x46a6a6a8; - raw_context.iregs[5] = 0x6a5025e2; - raw_context.iregs[6] = 0xd9fabb4a; - raw_context.iregs[7] = 0x6913f540; - raw_context.iregs[8] = 0xbffe6eda; - raw_context.iregs[9] = 0xb2ce1e2d; - raw_context.iregs[10] = 0x659caaa4; - raw_context.iregs[11] = 0xf0e0d0c0; - raw_context.iregs[12] = 0xa9b8c7d6; - raw_context.iregs[13] = 0x12345678; - raw_context.iregs[14] = 0xabcd1234; - raw_context.iregs[15] = 0x10203040; - raw_context.cpsr = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU()); - const MDRawContextARM *md_raw_context = md_context->GetContextARM(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER, - (md_raw_context->context_flags - & MD_CONTEXT_ARM_INTEGER)); - EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]); - EXPECT_EQ(0x382583b9U, raw_context.iregs[1]); - EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]); - EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]); - EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]); - EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]); - EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]); - EXPECT_EQ(0x6913f540U, raw_context.iregs[7]); - EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]); - EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]); - EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]); - EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]); - EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]); - EXPECT_EQ(0x12345678U, raw_context.iregs[13]); - EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]); - EXPECT_EQ(0x10203040U, raw_context.iregs[15]); - EXPECT_EQ(0x2e951ef7U, raw_context.cpsr); -} - -TEST(Dump, OneExceptionARMOldFlags) { - Dump dump(0, kLittleEndian); - - MDRawContextARM raw_context; - // MD_CONTEXT_ARM_INTEGER, but with _OLD - raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002; - raw_context.iregs[0] = 0x3ecba80d; - raw_context.iregs[1] = 0x382583b9; - raw_context.iregs[2] = 0x7fccc03f; - raw_context.iregs[3] = 0xf62f8ec2; - raw_context.iregs[4] = 0x46a6a6a8; - raw_context.iregs[5] = 0x6a5025e2; - raw_context.iregs[6] = 0xd9fabb4a; - raw_context.iregs[7] = 0x6913f540; - raw_context.iregs[8] = 0xbffe6eda; - raw_context.iregs[9] = 0xb2ce1e2d; - raw_context.iregs[10] = 0x659caaa4; - raw_context.iregs[11] = 0xf0e0d0c0; - raw_context.iregs[12] = 0xa9b8c7d6; - raw_context.iregs[13] = 0x12345678; - raw_context.iregs[14] = 0xabcd1234; - raw_context.iregs[15] = 0x10203040; - raw_context.cpsr = 0x2e951ef7; - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, - raw_exception->exception_record.exception_address); - - MinidumpContext *md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU()); - const MDRawContextARM *md_raw_context = md_context->GetContextARM(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER, - (md_raw_context->context_flags - & MD_CONTEXT_ARM_INTEGER)); - EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]); - EXPECT_EQ(0x382583b9U, raw_context.iregs[1]); - EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]); - EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]); - EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]); - EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]); - EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]); - EXPECT_EQ(0x6913f540U, raw_context.iregs[7]); - EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]); - EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]); - EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]); - EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]); - EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]); - EXPECT_EQ(0x12345678U, raw_context.iregs[13]); - EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]); - EXPECT_EQ(0x10203040U, raw_context.iregs[15]); - EXPECT_EQ(0x2e951ef7U, raw_context.cpsr); -} - -TEST(Dump, OneExceptionMIPS) { - Dump dump(0, kLittleEndian); - - MDRawContextMIPS raw_context; - raw_context.context_flags = MD_CONTEXT_MIPS_INTEGER; - raw_context.iregs[0] = 0x3ecba80d; - raw_context.iregs[1] = 0x382583b9; - raw_context.iregs[2] = 0x7fccc03f; - raw_context.iregs[3] = 0xf62f8ec2; - raw_context.iregs[4] = 0x46a6a6a8; - raw_context.iregs[5] = 0x6a5025e2; - raw_context.iregs[6] = 0xd9fabb4a; - raw_context.iregs[7] = 0x6913f540; - raw_context.iregs[8] = 0xbffe6eda; - raw_context.iregs[9] = 0xb2ce1e2d; - raw_context.iregs[10] = 0x659caaa4; - raw_context.iregs[11] = 0xf0e0d0c0; - raw_context.iregs[12] = 0xa9b8c7d6; - raw_context.iregs[13] = 0x12345678; - raw_context.iregs[14] = 0xabcd1234; - raw_context.iregs[15] = 0x10203040; - raw_context.iregs[16] = 0xa80d3ecb; - raw_context.iregs[17] = 0x83b93825; - raw_context.iregs[18] = 0xc03f7fcc; - raw_context.iregs[19] = 0x8ec2f62f; - raw_context.iregs[20] = 0xa6a846a6; - raw_context.iregs[21] = 0x25e26a50; - raw_context.iregs[22] = 0xbb4ad9fa; - raw_context.iregs[23] = 0xf5406913; - raw_context.iregs[24] = 0x6edabffe; - raw_context.iregs[25] = 0x1e2db2ce; - raw_context.iregs[26] = 0xaaa4659c; - raw_context.iregs[27] = 0xd0c0f0e0; - raw_context.iregs[28] = 0xc7d6a9b8; - raw_context.iregs[29] = 0x56781234; - raw_context.iregs[30] = 0x1234abcd; - raw_context.iregs[31] = 0x30401020; - - Context context(dump, raw_context); - - Exception exception(dump, context, - 0x1234abcd, // Thread id. - 0xdcba4321, // Exception code. - 0xf0e0d0c0, // Exception flags. - 0x0919a9b9); // Exception address. - - dump.Add(&context); - dump.Add(&exception); - dump.Finish(); - - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - - istringstream minidump_stream(contents); - Minidump minidump(minidump_stream); - ASSERT_TRUE(minidump.Read()); - ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); - - MinidumpException *md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); - - uint32_t thread_id; - ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); - ASSERT_EQ(0x1234abcdU, thread_id); - - const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); - EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); - EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); - EXPECT_EQ(0x0919a9b9U, - raw_exception->exception_record.exception_address); - - MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS, md_context->GetContextCPU()); - const MDRawContextMIPS* md_raw_context = md_context->GetContextMIPS(); - ASSERT_TRUE(md_raw_context != NULL); - ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS_INTEGER, - (md_raw_context->context_flags & MD_CONTEXT_MIPS_INTEGER)); - EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]); - EXPECT_EQ(0x382583b9U, raw_context.iregs[1]); - EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]); - EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]); - EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]); - EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]); - EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]); - EXPECT_EQ(0x6913f540U, raw_context.iregs[7]); - EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]); - EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]); - EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]); - EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]); - EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]); - EXPECT_EQ(0x12345678U, raw_context.iregs[13]); - EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]); - EXPECT_EQ(0x10203040U, raw_context.iregs[15]); - EXPECT_EQ(0xa80d3ecbU, raw_context.iregs[16]); - EXPECT_EQ(0x83b93825U, raw_context.iregs[17]); - EXPECT_EQ(0xc03f7fccU, raw_context.iregs[18]); - EXPECT_EQ(0x8ec2f62fU, raw_context.iregs[19]); - EXPECT_EQ(0xa6a846a6U, raw_context.iregs[20]); - EXPECT_EQ(0x25e26a50U, raw_context.iregs[21]); - EXPECT_EQ(0xbb4ad9faU, raw_context.iregs[22]); - EXPECT_EQ(0xf5406913U, raw_context.iregs[23]); - EXPECT_EQ(0x6edabffeU, raw_context.iregs[24]); - EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]); - EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]); - EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]); - EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]); - EXPECT_EQ(0x56781234U, raw_context.iregs[29]); - EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]); - EXPECT_EQ(0x30401020U, raw_context.iregs[31]); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc b/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc deleted file mode 100644 index 025ab883a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// module_comparer.cc: ModuleComparer implementation. -// See module_comparer.h for documentation. -// -// Author: lambxsy@google.com (Siyang Xie) - -#include "processor/module_comparer.h" - -#include -#include - -#include "common/scoped_ptr.h" -#include "processor/basic_code_module.h" -#include "processor/logging.h" - -#define ASSERT_TRUE(condition) \ - if (!(condition)) { \ - BPLOG(ERROR) << "FAIL: " << #condition << " @ " \ - << __FILE__ << ":" << __LINE__; \ - return false; \ - } - -#define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition)) - -namespace google_breakpad { - -bool ModuleComparer::Compare(const string &symbol_data) { - scoped_ptr basic_module(new BasicModule("test_module")); - scoped_ptr fast_module(new FastModule("test_module")); - - // Load symbol data into basic_module - scoped_array buffer(new char[symbol_data.size() + 1]); - memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size()); - buffer.get()[symbol_data.size()] = '\0'; - ASSERT_TRUE(basic_module->LoadMapFromMemory(buffer.get(), - symbol_data.size() + 1)); - buffer.reset(); - - // Serialize BasicSourceLineResolver::Module. - unsigned int serialized_size = 0; - scoped_array serialized_data( - serializer_.Serialize(*(basic_module.get()), &serialized_size)); - ASSERT_TRUE(serialized_data.get()); - BPLOG(INFO) << "Serialized size = " << serialized_size << " Bytes"; - - // Load FastSourceLineResolver::Module using serialized data. - ASSERT_TRUE(fast_module->LoadMapFromMemory(serialized_data.get(), - serialized_size)); - ASSERT_TRUE(fast_module->IsCorrupt() == basic_module->IsCorrupt()); - - // Compare FastSourceLineResolver::Module with - // BasicSourceLineResolver::Module. - ASSERT_TRUE(CompareModule(basic_module.get(), fast_module.get())); - - return true; -} - -// Traversal the content of module and do comparison -bool ModuleComparer::CompareModule(const BasicModule *basic_module, - const FastModule *fast_module) const { - // Compare name_. - ASSERT_TRUE(basic_module->name_ == fast_module->name_); - - // Compare files_: - { - BasicModule::FileMap::const_iterator iter1 = basic_module->files_.begin(); - FastModule::FileMap::iterator iter2 = fast_module->files_.begin(); - while (iter1 != basic_module->files_.end() - && iter2 != fast_module->files_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - string tmp(iter2.GetValuePtr()); - ASSERT_TRUE(iter1->second == tmp); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_module->files_.end()); - ASSERT_TRUE(iter2 == fast_module->files_.end()); - } - - // Compare functions_: - { - RangeMap >::MapConstIterator iter1; - StaticRangeMap::MapConstIterator iter2; - iter1 = basic_module->functions_.map_.begin(); - iter2 = fast_module->functions_.map_.begin(); - while (iter1 != basic_module->functions_.map_.end() - && iter2 != fast_module->functions_.map_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base()); - ASSERT_TRUE(CompareFunction( - iter1->second.entry().get(), iter2.GetValuePtr()->entryptr())); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_module->functions_.map_.end()); - ASSERT_TRUE(iter2 == fast_module->functions_.map_.end()); - } - - // Compare public_symbols_: - { - AddressMap >::MapConstIterator iter1; - StaticAddressMap::MapConstIterator iter2; - iter1 = basic_module->public_symbols_.map_.begin(); - iter2 = fast_module->public_symbols_.map_.begin(); - while (iter1 != basic_module->public_symbols_.map_.end() - && iter2 != fast_module->public_symbols_.map_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - ASSERT_TRUE(ComparePubSymbol( - iter1->second.get(), iter2.GetValuePtr())); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_module->public_symbols_.map_.end()); - ASSERT_TRUE(iter2 == fast_module->public_symbols_.map_.end()); - } - - // Compare windows_frame_info_[]: - for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) { - ASSERT_TRUE(CompareCRM(&(basic_module->windows_frame_info_[i]), - &(fast_module->windows_frame_info_[i]))); - } - - // Compare cfi_initial_rules_: - { - RangeMap::MapConstIterator iter1; - StaticRangeMap::MapConstIterator iter2; - iter1 = basic_module->cfi_initial_rules_.map_.begin(); - iter2 = fast_module->cfi_initial_rules_.map_.begin(); - while (iter1 != basic_module->cfi_initial_rules_.map_.end() - && iter2 != fast_module->cfi_initial_rules_.map_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base()); - string tmp(iter2.GetValuePtr()->entryptr()); - ASSERT_TRUE(iter1->second.entry() == tmp); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_module->cfi_initial_rules_.map_.end()); - ASSERT_TRUE(iter2 == fast_module->cfi_initial_rules_.map_.end()); - } - - // Compare cfi_delta_rules_: - { - map::const_iterator iter1; - StaticMap::iterator iter2; - iter1 = basic_module->cfi_delta_rules_.begin(); - iter2 = fast_module->cfi_delta_rules_.begin(); - while (iter1 != basic_module->cfi_delta_rules_.end() - && iter2 != fast_module->cfi_delta_rules_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - string tmp(iter2.GetValuePtr()); - ASSERT_TRUE(iter1->second == tmp); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_module->cfi_delta_rules_.end()); - ASSERT_TRUE(iter2 == fast_module->cfi_delta_rules_.end()); - } - - return true; -} - -bool ModuleComparer::CompareFunction(const BasicFunc *basic_func, - const FastFunc *fast_func_raw) const { - FastFunc* fast_func = new FastFunc(); - fast_func->CopyFrom(fast_func_raw); - ASSERT_TRUE(basic_func->name == fast_func->name); - ASSERT_TRUE(basic_func->address == fast_func->address); - ASSERT_TRUE(basic_func->size == fast_func->size); - - // compare range map of lines: - RangeMap >::MapConstIterator iter1; - StaticRangeMap::MapConstIterator iter2; - iter1 = basic_func->lines.map_.begin(); - iter2 = fast_func->lines.map_.begin(); - while (iter1 != basic_func->lines.map_.end() - && iter2 != fast_func->lines.map_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base()); - ASSERT_TRUE(CompareLine(iter1->second.entry().get(), - iter2.GetValuePtr()->entryptr())); - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_func->lines.map_.end()); - ASSERT_TRUE(iter2 == fast_func->lines.map_.end()); - - delete fast_func; - return true; -} - -bool ModuleComparer::CompareLine(const BasicLine *basic_line, - const FastLine *fast_line_raw) const { - FastLine *fast_line = new FastLine; - fast_line->CopyFrom(fast_line_raw); - - ASSERT_TRUE(basic_line->address == fast_line->address); - ASSERT_TRUE(basic_line->size == fast_line->size); - ASSERT_TRUE(basic_line->source_file_id == fast_line->source_file_id); - ASSERT_TRUE(basic_line->line == fast_line->line); - - delete fast_line; - return true; -} - -bool ModuleComparer::ComparePubSymbol(const BasicPubSymbol* basic_ps, - const FastPubSymbol* fastps_raw) const { - FastPubSymbol *fast_ps = new FastPubSymbol; - fast_ps->CopyFrom(fastps_raw); - ASSERT_TRUE(basic_ps->name == fast_ps->name); - ASSERT_TRUE(basic_ps->address == fast_ps->address); - ASSERT_TRUE(basic_ps->parameter_size == fast_ps->parameter_size); - delete fast_ps; - return true; -} - -bool ModuleComparer::CompareWFI(const WindowsFrameInfo& wfi1, - const WindowsFrameInfo& wfi2) const { - ASSERT_TRUE(wfi1.type_ == wfi2.type_); - ASSERT_TRUE(wfi1.valid == wfi2.valid); - ASSERT_TRUE(wfi1.prolog_size == wfi2.prolog_size); - ASSERT_TRUE(wfi1.epilog_size == wfi2.epilog_size); - ASSERT_TRUE(wfi1.parameter_size == wfi2.parameter_size); - ASSERT_TRUE(wfi1.saved_register_size == wfi2.saved_register_size); - ASSERT_TRUE(wfi1.local_size == wfi2.local_size); - ASSERT_TRUE(wfi1.max_stack_size == wfi2.max_stack_size); - ASSERT_TRUE(wfi1.allocates_base_pointer == wfi2.allocates_base_pointer); - ASSERT_TRUE(wfi1.program_string == wfi2.program_string); - return true; -} - -// Compare ContainedRangeMap -bool ModuleComparer::CompareCRM( - const ContainedRangeMap >* basic_crm, - const StaticContainedRangeMap* fast_crm) const { - ASSERT_TRUE(basic_crm->base_ == fast_crm->base_); - - if (!basic_crm->entry_.get() || !fast_crm->entry_ptr_) { - // empty entry: - ASSERT_TRUE(!basic_crm->entry_.get() && !fast_crm->entry_ptr_); - } else { - WFI newwfi; - newwfi.CopyFrom(fast_resolver_->CopyWFI(fast_crm->entry_ptr_)); - ASSERT_TRUE(CompareWFI(*(basic_crm->entry_.get()), newwfi)); - } - - if ((!basic_crm->map_ || basic_crm->map_->empty()) - || fast_crm->map_.empty()) { - ASSERT_TRUE((!basic_crm->map_ || basic_crm->map_->empty()) - && fast_crm->map_.empty()); - } else { - ContainedRangeMap >::MapConstIterator iter1; - StaticContainedRangeMap::MapConstIterator iter2; - iter1 = basic_crm->map_->begin(); - iter2 = fast_crm->map_.begin(); - while (iter1 != basic_crm->map_->end() - && iter2 != fast_crm->map_.end()) { - ASSERT_TRUE(iter1->first == iter2.GetKey()); - StaticContainedRangeMap *child = - new StaticContainedRangeMap( - reinterpret_cast(iter2.GetValuePtr())); - ASSERT_TRUE(CompareCRM(iter1->second, child)); - delete child; - ++iter1; - ++iter2; - } - ASSERT_TRUE(iter1 == basic_crm->map_->end()); - ASSERT_TRUE(iter2 == fast_crm->map_.end()); - } - - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.h b/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.h deleted file mode 100644 index fcbd51775..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// module_comparer.h: ModuleComparer reads a string format of symbol file, and -// loads the symbol into both BasicSourceLineResolver::Module and -// FastSourceLineResolve::Module. It then traverses both Modules and compare -// the content of data to verify the correctness of new fast module. -// ModuleCompare class is a tool to verify correctness of a loaded -// FastSourceLineResolver::Module instance, i.e., in-memory representation of -// parsed symbol. ModuleComparer class should be used for testing purpose only, -// e.g., in fast_source_line_resolver_unittest. -// -// Author: lambxsy@google.com (Siyang Xie) - -#ifndef PROCESSOR_MODULE_COMPARER_H__ -#define PROCESSOR_MODULE_COMPARER_H__ - -#include - -#include "processor/basic_source_line_resolver_types.h" -#include "processor/fast_source_line_resolver_types.h" -#include "processor/module_serializer.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -class ModuleComparer { - public: - ModuleComparer(): fast_resolver_(new FastSourceLineResolver), - basic_resolver_(new BasicSourceLineResolver) { } - ~ModuleComparer() { - delete fast_resolver_; - delete basic_resolver_; - } - - // BasicSourceLineResolver loads its module using the symbol data, - // ModuleSerializer serialize the loaded module into a memory chunk, - // FastSourceLineResolver loads its module using the serialized memory chunk, - // Then, traverse both modules together and compare underlying data - // return true if both modules contain exactly same data. - bool Compare(const string &symbol_data); - - private: - typedef BasicSourceLineResolver::Module BasicModule; - typedef FastSourceLineResolver::Module FastModule; - typedef BasicSourceLineResolver::Function BasicFunc; - typedef FastSourceLineResolver::Function FastFunc; - typedef BasicSourceLineResolver::Line BasicLine; - typedef FastSourceLineResolver::Line FastLine; - typedef BasicSourceLineResolver::PublicSymbol BasicPubSymbol; - typedef FastSourceLineResolver::PublicSymbol FastPubSymbol; - typedef WindowsFrameInfo WFI; - - bool CompareModule(const BasicModule *oldmodule, - const FastModule *newmodule) const; - bool CompareFunction(const BasicFunc *oldfunc, const FastFunc *newfunc) const; - bool CompareLine(const BasicLine *oldline, const FastLine *newline) const; - bool ComparePubSymbol(const BasicPubSymbol*, const FastPubSymbol*) const; - bool CompareWFI(const WindowsFrameInfo&, const WindowsFrameInfo&) const; - - // Compare ContainedRangeMap - bool CompareCRM(const ContainedRangeMap >*, - const StaticContainedRangeMap*) const; - - FastSourceLineResolver *fast_resolver_; - BasicSourceLineResolver *basic_resolver_; - ModuleSerializer serializer_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_MODULE_COMPARER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/module_factory.h b/toolkit/crashreporter/google-breakpad/src/processor/module_factory.h deleted file mode 100644 index 7aa7caa59..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/module_factory.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// module_factory.h: ModuleFactory a factory that provides -// an interface for creating a Module and deferring instantiation to subclasses -// BasicModuleFactory and FastModuleFactory. - -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_MODULE_FACTORY_H__ -#define PROCESSOR_MODULE_FACTORY_H__ - -#include "processor/basic_source_line_resolver_types.h" -#include "processor/fast_source_line_resolver_types.h" -#include "processor/source_line_resolver_base_types.h" - -namespace google_breakpad { - -class ModuleFactory { - public: - virtual ~ModuleFactory() { }; - virtual SourceLineResolverBase::Module* CreateModule( - const string &name) const = 0; -}; - -class BasicModuleFactory : public ModuleFactory { - public: - virtual ~BasicModuleFactory() { } - virtual BasicSourceLineResolver::Module* CreateModule( - const string &name) const { - return new BasicSourceLineResolver::Module(name); - } -}; - -class FastModuleFactory : public ModuleFactory { - public: - virtual ~FastModuleFactory() { } - virtual FastSourceLineResolver::Module* CreateModule( - const string &name) const { - return new FastSourceLineResolver::Module(name); - } -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_MODULE_FACTORY_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.cc b/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.cc deleted file mode 100644 index 6ac60c1fc..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.cc +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// module_serializer.cc: ModuleSerializer implementation. -// -// See module_serializer.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include "processor/module_serializer.h" - -#include -#include - -#include "processor/basic_code_module.h" -#include "processor/logging.h" - -namespace google_breakpad { - -// Definition of static member variable in SimplerSerializer, which -// is declared in file "simple_serializer-inl.h" -RangeMapSerializer< MemAddr, linked_ptr > -SimpleSerializer::range_map_serializer_; - -size_t ModuleSerializer::SizeOf(const BasicSourceLineResolver::Module &module) { - size_t total_size_alloc_ = 0; - - // Size of the "is_corrupt" flag. - total_size_alloc_ += SimpleSerializer::SizeOf(module.is_corrupt_); - - // Compute memory size for each map component in Module class. - int map_index = 0; - map_sizes_[map_index++] = files_serializer_.SizeOf(module.files_); - map_sizes_[map_index++] = functions_serializer_.SizeOf(module.functions_); - map_sizes_[map_index++] = pubsym_serializer_.SizeOf(module.public_symbols_); - for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) - map_sizes_[map_index++] = - wfi_serializer_.SizeOf(&(module.windows_frame_info_[i])); - map_sizes_[map_index++] = cfi_init_rules_serializer_.SizeOf( - module.cfi_initial_rules_); - map_sizes_[map_index++] = cfi_delta_rules_serializer_.SizeOf( - module.cfi_delta_rules_); - - // Header size. - total_size_alloc_ += kNumberMaps_ * sizeof(uint32_t); - - for (int i = 0; i < kNumberMaps_; ++i) { - total_size_alloc_ += map_sizes_[i]; - } - - // Extra one byte for null terminator for C-string copy safety. - total_size_alloc_ += SimpleSerializer::SizeOf(0); - - return total_size_alloc_; -} - -char *ModuleSerializer::Write(const BasicSourceLineResolver::Module &module, - char *dest) { - // Write the is_corrupt flag. - dest = SimpleSerializer::Write(module.is_corrupt_, dest); - // Write header. - memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint32_t)); - dest += kNumberMaps_ * sizeof(uint32_t); - // Write each map. - dest = files_serializer_.Write(module.files_, dest); - dest = functions_serializer_.Write(module.functions_, dest); - dest = pubsym_serializer_.Write(module.public_symbols_, dest); - for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) - dest = wfi_serializer_.Write(&(module.windows_frame_info_[i]), dest); - dest = cfi_init_rules_serializer_.Write(module.cfi_initial_rules_, dest); - dest = cfi_delta_rules_serializer_.Write(module.cfi_delta_rules_, dest); - // Write a null terminator. - dest = SimpleSerializer::Write(0, dest); - return dest; -} - -char* ModuleSerializer::Serialize( - const BasicSourceLineResolver::Module &module, unsigned int *size) { - // Compute size of memory to allocate. - unsigned int size_to_alloc = SizeOf(module); - - // Allocate memory for serialized data. - char *serialized_data = new char[size_to_alloc]; - if (!serialized_data) { - BPLOG(ERROR) << "ModuleSerializer: memory allocation failed, " - << "size to alloc: " << size_to_alloc; - if (size) *size = 0; - return NULL; - } - - // Write serialized data to allocated memory chunk. - char *end_address = Write(module, serialized_data); - // Verify the allocated memory size is equal to the size of data been written. - unsigned int size_written = - static_cast(end_address - serialized_data); - if (size_to_alloc != size_written) { - BPLOG(ERROR) << "size_to_alloc differs from size_written: " - << size_to_alloc << " vs " << size_written; - } - - // Set size and return the start address of memory chunk. - if (size) - *size = size_to_alloc; - return serialized_data; -} - -bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver( - const BasicSourceLineResolver::ModuleMap::const_iterator &iter, - FastSourceLineResolver *fast_resolver) { - BPLOG(INFO) << "Converting symbol " << iter->first.c_str(); - - // Cast SourceLineResolverBase::Module* to BasicSourceLineResolver::Module*. - BasicSourceLineResolver::Module* basic_module = - dynamic_cast(iter->second); - - unsigned int size = 0; - scoped_array symbol_data(Serialize(*basic_module, &size)); - if (!symbol_data.get()) { - BPLOG(ERROR) << "Serialization failed for module: " << basic_module->name_; - return false; - } - BPLOG(INFO) << "Serialized Symbol Size " << size; - - // Copy the data into string. - // Must pass string to LoadModuleUsingMapBuffer(), instead of passing char* to - // LoadModuleUsingMemoryBuffer(), becaused of data ownership/lifetime issue. - string symbol_data_string(symbol_data.get(), size); - symbol_data.reset(); - - scoped_ptr code_module( - new BasicCodeModule(0, 0, iter->first, "", "", "", "")); - - return fast_resolver->LoadModuleUsingMapBuffer(code_module.get(), - symbol_data_string); -} - -void ModuleSerializer::ConvertAllModules( - const BasicSourceLineResolver *basic_resolver, - FastSourceLineResolver *fast_resolver) { - // Check for NULL pointer. - if (!basic_resolver || !fast_resolver) - return; - - // Traverse module list in basic resolver. - BasicSourceLineResolver::ModuleMap::const_iterator iter; - iter = basic_resolver->modules_->begin(); - for (; iter != basic_resolver->modules_->end(); ++iter) - SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver); -} - -bool ModuleSerializer::ConvertOneModule( - const string &moduleid, - const BasicSourceLineResolver *basic_resolver, - FastSourceLineResolver *fast_resolver) { - // Check for NULL pointer. - if (!basic_resolver || !fast_resolver) - return false; - - BasicSourceLineResolver::ModuleMap::const_iterator iter; - iter = basic_resolver->modules_->find(moduleid); - if (iter == basic_resolver->modules_->end()) - return false; - - return SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver); -} - -char* ModuleSerializer::SerializeSymbolFileData( - const string &symbol_data, unsigned int *size) { - scoped_ptr module( - new BasicSourceLineResolver::Module("no name")); - scoped_array buffer(new char[symbol_data.size() + 1]); - memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size()); - buffer.get()[symbol_data.size()] = '\0'; - if (!module->LoadMapFromMemory(buffer.get(), symbol_data.size() + 1)) { - return NULL; - } - buffer.reset(NULL); - return Serialize(*(module.get()), size); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.h b/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.h deleted file mode 100644 index effb00916..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/module_serializer.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// module_serializer.h: ModuleSerializer serializes a loaded symbol, -// i.e., a loaded BasicSouceLineResolver::Module instance, into a memory -// chunk of data. The serialized data can be read and loaded by -// FastSourceLineResolver without CPU & memory-intensive parsing. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_MODULE_SERIALIZER_H__ -#define PROCESSOR_MODULE_SERIALIZER_H__ - -#include -#include - -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/fast_source_line_resolver.h" -#include "processor/basic_source_line_resolver_types.h" -#include "processor/fast_source_line_resolver_types.h" -#include "processor/linked_ptr.h" -#include "processor/map_serializers-inl.h" -#include "processor/simple_serializer-inl.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -// ModuleSerializer serializes a loaded BasicSourceLineResolver::Module into a -// chunk of memory data. ModuleSerializer also provides interface to compute -// memory size of the serialized data, write serialized data directly into -// memory, convert ASCII format symbol data into serialized binary data, and -// convert loaded BasicSourceLineResolver::Module into -// FastSourceLineResolver::Module. -class ModuleSerializer { - public: - // Compute the size of memory required to serialize a module. Return the - // total size needed for serialization. - size_t SizeOf(const BasicSourceLineResolver::Module &module); - - // Write a module into an allocated memory chunk with required size. - // Return the "end" of data, i.e., the address after the final byte of data. - char* Write(const BasicSourceLineResolver::Module &module, char *dest); - - // Serializes a loaded Module object into a chunk of memory data and returns - // the address of memory chunk. If size != NULL, *size is set to the memory - // size allocated for the serialized data. - // Caller takes the ownership of the memory chunk (allocated on heap), and - // owner should call delete [] to free the memory after use. - char* Serialize(const BasicSourceLineResolver::Module &module, - unsigned int *size = NULL); - - // Given the string format symbol_data, produces a chunk of serialized data. - // Caller takes ownership of the serialized data (on heap), and owner should - // call delete [] to free the memory after use. - char* SerializeSymbolFileData(const string &symbol_data, - unsigned int *size = NULL); - - // Serializes one loaded module with given moduleid in the basic source line - // resolver, and loads the serialized data into the fast source line resolver. - // Return false if the basic source line doesn't have a module with the given - // moduleid. - bool ConvertOneModule(const string &moduleid, - const BasicSourceLineResolver *basic_resolver, - FastSourceLineResolver *fast_resolver); - - // Serializes all the loaded modules in a basic source line resolver, and - // loads the serialized data into a fast source line resolver. - void ConvertAllModules(const BasicSourceLineResolver *basic_resolver, - FastSourceLineResolver *fast_resolver); - - private: - // Convenient type names. - typedef BasicSourceLineResolver::Line Line; - typedef BasicSourceLineResolver::Function Function; - typedef BasicSourceLineResolver::PublicSymbol PublicSymbol; - - // Internal implementation for ConvertOneModule and ConvertAllModules methods. - bool SerializeModuleAndLoadIntoFastResolver( - const BasicSourceLineResolver::ModuleMap::const_iterator &iter, - FastSourceLineResolver *fast_resolver); - - // Number of Maps that Module class contains. - static const int32_t kNumberMaps_ = - FastSourceLineResolver::Module::kNumberMaps_; - - // Memory sizes required to serialize map components in Module. - uint32_t map_sizes_[kNumberMaps_]; - - // Serializers for each individual map component in Module class. - StdMapSerializer files_serializer_; - RangeMapSerializer > functions_serializer_; - AddressMapSerializer > pubsym_serializer_; - ContainedRangeMapSerializer > wfi_serializer_; - RangeMapSerializer cfi_init_rules_serializer_; - StdMapSerializer cfi_delta_rules_serializer_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_MODULE_SERIALIZER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/moz.build b/toolkit/crashreporter/google-breakpad/src/processor/moz.build deleted file mode 100644 index 1a2fac39e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/moz.build +++ /dev/null @@ -1,66 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SOURCES += [ - '../third_party/libdisasm/ia32_invariant.c', - 'disassembler_x86.cc', - 'exploitability_win.cc', -] - -UNIFIED_SOURCES += [ - '../third_party/libdisasm/ia32_implicit.c', - '../third_party/libdisasm/ia32_insn.c', - '../third_party/libdisasm/ia32_modrm.c', - '../third_party/libdisasm/ia32_opcode_tables.c', - '../third_party/libdisasm/ia32_operand.c', - '../third_party/libdisasm/ia32_reg.c', - '../third_party/libdisasm/ia32_settings.c', - '../third_party/libdisasm/x86_disasm.c', - '../third_party/libdisasm/x86_imm.c', - '../third_party/libdisasm/x86_insn.c', - '../third_party/libdisasm/x86_misc.c', - '../third_party/libdisasm/x86_operand_list.c', - 'basic_code_modules.cc', - 'basic_source_line_resolver.cc', - 'call_stack.cc', - 'cfi_frame_info.cc', - 'dump_context.cc', - 'dump_object.cc', - 'exploitability.cc', - 'exploitability_linux.cc', - 'logging.cc', - 'minidump.cc', - 'minidump_processor.cc', - 'pathname_stripper.cc', - 'proc_maps_linux.cc', - 'process_state.cc', - 'source_line_resolver_base.cc', - 'stack_frame_symbolizer.cc', - 'stackwalk_common.cc', - 'stackwalker.cc', - 'stackwalker_amd64.cc', - 'stackwalker_arm.cc', - 'stackwalker_arm64.cc', - 'stackwalker_mips.cc', - 'stackwalker_ppc.cc', - 'stackwalker_ppc64.cc', - 'stackwalker_sparc.cc', - 'stackwalker_x86.cc', - 'symbolic_constants_win.cc', - 'tokenize.cc', -] - -DEFINES['BPLOG_MINIMUM_SEVERITY'] = 'SEVERITY_ERROR' - -Library('breakpad_processor') - -# Don't use the STL wrappers in the crashreporter clients -DISABLE_STL_WRAPPING = True - -# We allow warnings for third-party code that can be updated from upstream. -ALLOW_COMPILER_WARNINGS = True - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc b/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc deleted file mode 100644 index 839287bdb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// pathname_stripper.cc: Manipulates pathnames into their component parts. -// -// See pathname_stripper.h for documentation. -// -// Author: Mark Mentovai - -#include "processor/pathname_stripper.h" - -namespace google_breakpad { - -// static -string PathnameStripper::File(const string &path) { - string::size_type slash = path.rfind('/'); - string::size_type backslash = path.rfind('\\'); - - string::size_type file_start = 0; - if (slash != string::npos && - (backslash == string::npos || slash > backslash)) { - file_start = slash + 1; - } else if (backslash != string::npos) { - file_start = backslash + 1; - } - - return path.substr(file_start); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h b/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h deleted file mode 100644 index 423ca0d05..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// pathname_stripper.h: Manipulates pathnames into their component parts. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_PATHNAME_STRIPPER_H__ -#define PROCESSOR_PATHNAME_STRIPPER_H__ - -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -class PathnameStripper { - public: - // Given path, a pathname with components separated by slashes (/) or - // backslashes (\), returns the trailing component, without any separator. - // If path ends in a separator character, returns an empty string. - static string File(const string &path); -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_PATHNAME_STRIPPER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc deleted file mode 100644 index 1bff4cb01..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include "processor/pathname_stripper.h" -#include "processor/logging.h" - -#define ASSERT_TRUE(condition) \ - if (!(condition)) { \ - fprintf(stderr, "FAIL: %s @ %s:%d\n", #condition, __FILE__, __LINE__); \ - return false; \ - } - -#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2)) - -namespace { - -using google_breakpad::PathnameStripper; - -static bool RunTests() { - ASSERT_EQ(PathnameStripper::File("/dir/file"), "file"); - ASSERT_EQ(PathnameStripper::File("\\dir\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("/dir\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("\\dir/file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir/file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir/\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir\\/file"), "file"); - ASSERT_EQ(PathnameStripper::File("file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir/"), ""); - ASSERT_EQ(PathnameStripper::File("dir\\"), ""); - ASSERT_EQ(PathnameStripper::File("dir/dir/"), ""); - ASSERT_EQ(PathnameStripper::File("dir\\dir\\"), ""); - ASSERT_EQ(PathnameStripper::File("dir1/dir2/file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir1\\dir2\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir1/dir2\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir1\\dir2/file"), "file"); - ASSERT_EQ(PathnameStripper::File(""), ""); - ASSERT_EQ(PathnameStripper::File("1"), "1"); - ASSERT_EQ(PathnameStripper::File("1/2"), "2"); - ASSERT_EQ(PathnameStripper::File("1\\2"), "2"); - ASSERT_EQ(PathnameStripper::File("/1/2"), "2"); - ASSERT_EQ(PathnameStripper::File("\\1\\2"), "2"); - ASSERT_EQ(PathnameStripper::File("dir//file"), "file"); - ASSERT_EQ(PathnameStripper::File("dir\\\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("/dir//file"), "file"); - ASSERT_EQ(PathnameStripper::File("\\dir\\\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("c:\\dir\\file"), "file"); - ASSERT_EQ(PathnameStripper::File("c:\\dir\\file.ext"), "file.ext"); - - return true; -} - -} // namespace - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h deleted file mode 100644 index d7dbeac20..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h +++ /dev/null @@ -1,363 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// postfix_evaluator-inl.h: Postfix (reverse Polish) notation expression -// evaluator. -// -// Documentation in postfix_evaluator.h. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_POSTFIX_EVALUATOR_INL_H__ -#define PROCESSOR_POSTFIX_EVALUATOR_INL_H__ - -#include "processor/postfix_evaluator.h" - -#include - -#include - -#include "google_breakpad/processor/memory_region.h" -#include "processor/logging.h" - -namespace google_breakpad { - -using std::istringstream; -using std::ostringstream; - - -// A small class used in Evaluate to make sure to clean up the stack -// before returning failure. -class AutoStackClearer { - public: - explicit AutoStackClearer(vector *stack) : stack_(stack) {} - ~AutoStackClearer() { stack_->clear(); } - - private: - vector *stack_; -}; - - -template -bool PostfixEvaluator::EvaluateToken( - const string &token, - const string &expression, - DictionaryValidityType *assigned) { - // There are enough binary operations that do exactly the same thing - // (other than the specific operation, of course) that it makes sense - // to share as much code as possible. - enum BinaryOperation { - BINARY_OP_NONE = 0, - BINARY_OP_ADD, - BINARY_OP_SUBTRACT, - BINARY_OP_MULTIPLY, - BINARY_OP_DIVIDE_QUOTIENT, - BINARY_OP_DIVIDE_MODULUS, - BINARY_OP_ALIGN - }; - - BinaryOperation operation = BINARY_OP_NONE; - if (token == "+") - operation = BINARY_OP_ADD; - else if (token == "-") - operation = BINARY_OP_SUBTRACT; - else if (token == "*") - operation = BINARY_OP_MULTIPLY; - else if (token == "/") - operation = BINARY_OP_DIVIDE_QUOTIENT; - else if (token == "%") - operation = BINARY_OP_DIVIDE_MODULUS; - else if (token == "@") - operation = BINARY_OP_ALIGN; - - if (operation != BINARY_OP_NONE) { - // Get the operands. - ValueType operand1 = ValueType(); - ValueType operand2 = ValueType(); - if (!PopValues(&operand1, &operand2)) { - BPLOG(ERROR) << "Could not PopValues to get two values for binary " - "operation " << token << ": " << expression; - return false; - } - - // Perform the operation. - ValueType result; - switch (operation) { - case BINARY_OP_ADD: - result = operand1 + operand2; - break; - case BINARY_OP_SUBTRACT: - result = operand1 - operand2; - break; - case BINARY_OP_MULTIPLY: - result = operand1 * operand2; - break; - case BINARY_OP_DIVIDE_QUOTIENT: - result = operand1 / operand2; - break; - case BINARY_OP_DIVIDE_MODULUS: - result = operand1 % operand2; - break; - case BINARY_OP_ALIGN: - result = - operand1 & (static_cast(-1) ^ (operand2 - 1)); - break; - case BINARY_OP_NONE: - // This will not happen, but compilers will want a default or - // BINARY_OP_NONE case. - BPLOG(ERROR) << "Not reached!"; - return false; - break; - } - - // Save the result. - PushValue(result); - } else if (token == "^") { - // ^ for unary dereference. Can't dereference without memory. - if (!memory_) { - BPLOG(ERROR) << "Attempt to dereference without memory: " << - expression; - return false; - } - - ValueType address; - if (!PopValue(&address)) { - BPLOG(ERROR) << "Could not PopValue to get value to derefence: " << - expression; - return false; - } - - ValueType value; - if (!memory_->GetMemoryAtAddress(address, &value)) { - BPLOG(ERROR) << "Could not dereference memory at address " << - HexString(address) << ": " << expression; - return false; - } - - PushValue(value); - } else if (token == "=") { - // = for assignment. - ValueType value; - if (!PopValue(&value)) { - BPLOG(INFO) << "Could not PopValue to get value to assign: " << - expression; - return false; - } - - // Assignment is only meaningful when assigning into an identifier. - // The identifier must name a variable, not a constant. Variables - // begin with '$'. - string identifier; - if (PopValueOrIdentifier(NULL, &identifier) != POP_RESULT_IDENTIFIER) { - BPLOG(ERROR) << "PopValueOrIdentifier returned a value, but an " - "identifier is needed to assign " << - HexString(value) << ": " << expression; - return false; - } - if (identifier.empty() || identifier[0] != '$') { - BPLOG(ERROR) << "Can't assign " << HexString(value) << " to " << - identifier << ": " << expression; - return false; - } - - (*dictionary_)[identifier] = value; - if (assigned) - (*assigned)[identifier] = true; - } else { - // The token is not an operator, it's a literal value or an identifier. - // Push it onto the stack as-is. Use push_back instead of PushValue - // because PushValue pushes ValueType as a string, but token is already - // a string. - stack_.push_back(token); - } - return true; -} - -template -bool PostfixEvaluator::EvaluateInternal( - const string &expression, - DictionaryValidityType *assigned) { - // Tokenize, splitting on whitespace. - istringstream stream(expression); - string token; - while (stream >> token) { - // Normally, tokens are whitespace-separated, but occasionally, the - // assignment operator is smashed up against the next token, i.e. - // $T0 $ebp 128 + =$eip $T0 4 + ^ =$ebp $T0 ^ = - // This has been observed in program strings produced by MSVS 2010 in LTO - // mode. - if (token.size() > 1 && token[0] == '=') { - if (!EvaluateToken("=", expression, assigned)) { - return false; - } - - if (!EvaluateToken(token.substr(1), expression, assigned)) { - return false; - } - } else if (!EvaluateToken(token, expression, assigned)) { - return false; - } - } - - return true; -} - -template -bool PostfixEvaluator::Evaluate(const string &expression, - DictionaryValidityType *assigned) { - // Ensure that the stack is cleared before returning. - AutoStackClearer clearer(&stack_); - - if (!EvaluateInternal(expression, assigned)) - return false; - - // If there's anything left on the stack, it indicates incomplete execution. - // This is a failure case. If the stack is empty, evalution was complete - // and successful. - if (stack_.empty()) - return true; - - BPLOG(ERROR) << "Incomplete execution: " << expression; - return false; -} - -template -bool PostfixEvaluator::EvaluateForValue(const string &expression, - ValueType *result) { - // Ensure that the stack is cleared before returning. - AutoStackClearer clearer(&stack_); - - if (!EvaluateInternal(expression, NULL)) - return false; - - // A successful execution should leave exactly one value on the stack. - if (stack_.size() != 1) { - BPLOG(ERROR) << "Expression yielded bad number of results: " - << "'" << expression << "'"; - return false; - } - - return PopValue(result); -} - -template -typename PostfixEvaluator::PopResult -PostfixEvaluator::PopValueOrIdentifier( - ValueType *value, string *identifier) { - // There needs to be at least one element on the stack to pop. - if (!stack_.size()) - return POP_RESULT_FAIL; - - string token = stack_.back(); - stack_.pop_back(); - - // First, try to treat the value as a literal. Literals may have leading - // '-' sign, and the entire remaining string must be parseable as - // ValueType. If this isn't possible, it can't be a literal, so treat it - // as an identifier instead. - // - // Some versions of the libstdc++, the GNU standard C++ library, have - // stream extractors for unsigned integer values that permit a leading - // '-' sign (6.0.13); others do not (6.0.9). Since we require it, we - // handle it explicitly here. - istringstream token_stream(token); - ValueType literal = ValueType(); - bool negative; - if (token_stream.peek() == '-') { - negative = true; - token_stream.get(); - } else { - negative = false; - } - if (token_stream >> literal && token_stream.peek() == EOF) { - if (value) { - *value = literal; - } - if (negative) - *value = -*value; - return POP_RESULT_VALUE; - } else { - if (identifier) { - *identifier = token; - } - return POP_RESULT_IDENTIFIER; - } -} - - -template -bool PostfixEvaluator::PopValue(ValueType *value) { - ValueType literal = ValueType(); - string token; - PopResult result; - if ((result = PopValueOrIdentifier(&literal, &token)) == POP_RESULT_FAIL) { - return false; - } else if (result == POP_RESULT_VALUE) { - // This is the easy case. - *value = literal; - } else { // result == POP_RESULT_IDENTIFIER - // There was an identifier at the top of the stack. Resolve it to a - // value by looking it up in the dictionary. - typename DictionaryType::const_iterator iterator = - dictionary_->find(token); - if (iterator == dictionary_->end()) { - // The identifier wasn't found in the dictionary. Don't imply any - // default value, just fail. - BPLOG(INFO) << "Identifier " << token << " not in dictionary"; - return false; - } - - *value = iterator->second; - } - - return true; -} - - -template -bool PostfixEvaluator::PopValues(ValueType *value1, - ValueType *value2) { - return PopValue(value2) && PopValue(value1); -} - - -template -void PostfixEvaluator::PushValue(const ValueType &value) { - ostringstream token_stream; - token_stream << value; - stack_.push_back(token_stream.str()); -} - - -} // namespace google_breakpad - - -#endif // PROCESSOR_POSTFIX_EVALUATOR_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h b/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h deleted file mode 100644 index 94b66190d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h +++ /dev/null @@ -1,179 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// postfix_evaluator.h: Postfix (reverse Polish) notation expression evaluator. -// -// PostfixEvaluator evaluates an expression, using the expression itself -// in postfix (reverse Polish) notation and a dictionary mapping constants -// and variables to their values. The evaluator supports standard -// arithmetic operations, assignment into variables, and when an optional -// MemoryRange is provided, dereferencing. (Any unary key-to-value operation -// may be used with a MemoryRange implementation that returns the appropriate -// values, but PostfixEvaluator was written with dereferencing in mind.) -// -// The expression language is simple. Expressions are supplied as strings, -// with operands and operators delimited by whitespace. Operands may be -// either literal values suitable for ValueType, or constants or variables, -// which reference the dictionary. The supported binary operators are + -// (addition), - (subtraction), * (multiplication), / (quotient of division), -// % (modulus of division), and @ (data alignment). The alignment operator (@) -// accepts a value and an alignment size, and produces a result that is a -// multiple of the alignment size by truncating the input value. -// The unary ^ (dereference) operator is also provided. These operators -// allow any operand to be either a literal value, constant, or variable. -// Assignment (=) of any type of operand into a variable is also supported. -// -// The dictionary is provided as a map with string keys. Keys beginning -// with the '$' character are treated as variables. All other keys are -// treated as constants. Any results must be assigned into variables in the -// dictionary. These variables do not need to exist prior to calling -// Evaluate, unless used in an expression prior to being assigned to. The -// internal stack state is not made available after evaluation, and any -// values remaining on the stack are treated as evidence of incomplete -// execution and cause the evaluator to indicate failure. -// -// PostfixEvaluator is intended to support evaluation of "program strings" -// obtained from MSVC frame data debugging information in pdb files as -// returned by the DIA APIs. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_POSTFIX_EVALUATOR_H__ -#define PROCESSOR_POSTFIX_EVALUATOR_H__ - - -#include -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -using std::map; -using std::vector; - -class MemoryRegion; - -template -class PostfixEvaluator { - public: - typedef map DictionaryType; - typedef map DictionaryValidityType; - - // Create a PostfixEvaluator object that may be used (with Evaluate) on - // one or more expressions. PostfixEvaluator does not take ownership of - // either argument. |memory| may be NULL, in which case dereferencing - // (^) will not be supported. |dictionary| may be NULL, but evaluation - // will fail in that case unless set_dictionary is used before calling - // Evaluate. - PostfixEvaluator(DictionaryType *dictionary, const MemoryRegion *memory) - : dictionary_(dictionary), memory_(memory), stack_() {} - - // Evaluate the expression, starting with an empty stack. The results of - // execution will be stored in one (or more) variables in the dictionary. - // Returns false if any failures occur during execution, leaving - // variables in the dictionary in an indeterminate state. If assigned is - // non-NULL, any keys set in the dictionary as a result of evaluation - // will also be set to true in assigned, providing a way to determine if - // an expression modifies any of its input variables. - bool Evaluate(const string &expression, DictionaryValidityType *assigned); - - // Like Evaluate, but provides the value left on the stack to the - // caller. If evaluation succeeds and leaves exactly one value on - // the stack, pop that value, store it in *result, and return true. - // Otherwise, return false. - bool EvaluateForValue(const string &expression, ValueType *result); - - DictionaryType* dictionary() const { return dictionary_; } - - // Reset the dictionary. PostfixEvaluator does not take ownership. - void set_dictionary(DictionaryType *dictionary) {dictionary_ = dictionary; } - - private: - // Return values for PopValueOrIdentifier - enum PopResult { - POP_RESULT_FAIL = 0, - POP_RESULT_VALUE, - POP_RESULT_IDENTIFIER - }; - - // Retrieves the topmost literal value, constant, or variable from the - // stack. Returns POP_RESULT_VALUE if the topmost entry is a literal - // value, and sets |value| accordingly. Returns POP_RESULT_IDENTIFIER - // if the topmost entry is a constant or variable identifier, and sets - // |identifier| accordingly. Returns POP_RESULT_FAIL on failure, such - // as when the stack is empty. - PopResult PopValueOrIdentifier(ValueType *value, string *identifier); - - // Retrieves the topmost value on the stack. If the topmost entry is - // an identifier, the dictionary is queried for the identifier's value. - // Returns false on failure, such as when the stack is empty or when - // a nonexistent identifier is named. - bool PopValue(ValueType *value); - - // Retrieves the top two values on the stack, in the style of PopValue. - // value2 is popped before value1, so that value1 corresponds to the - // entry that was pushed prior to value2. Returns false on failure. - bool PopValues(ValueType *value1, ValueType *value2); - - // Pushes a new value onto the stack. - void PushValue(const ValueType &value); - - // Evaluate expression, updating *assigned if it is non-zero. Return - // true if evaluation completes successfully. Do not clear the stack - // upon successful evaluation. - bool EvaluateInternal(const string &expression, - DictionaryValidityType *assigned); - - bool EvaluateToken(const string &token, - const string &expression, - DictionaryValidityType *assigned); - - // The dictionary mapping constant and variable identifiers (strings) to - // values. Keys beginning with '$' are treated as variable names, and - // PostfixEvaluator is free to create and modify these keys. Weak pointer. - DictionaryType *dictionary_; - - // If non-NULL, the MemoryRegion used for dereference (^) operations. - // If NULL, dereferencing is unsupported and will fail. Weak pointer. - const MemoryRegion *memory_; - - // The stack contains state information as execution progresses. Values - // are pushed on to it as the expression string is read and as operations - // yield values; values are popped when used as operands to operators. - vector stack_; -}; - -} // namespace google_breakpad - - -#endif // PROCESSOR_POSTFIX_EVALUATOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc deleted file mode 100644 index f11898284..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// postfix_evaluator_unittest.cc: Unit tests for PostfixEvaluator. -// -// Author: Mark Mentovai - -#include -#include - -#include -#include - -#include "processor/postfix_evaluator-inl.h" - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/memory_region.h" -#include "processor/logging.h" - - -namespace { - - -using std::map; -using google_breakpad::MemoryRegion; -using google_breakpad::PostfixEvaluator; - - -// FakeMemoryRegion is used to test PostfixEvaluator's dereference (^) -// operator. The result of dereferencing a value is one greater than -// the value. -class FakeMemoryRegion : public MemoryRegion { - public: - virtual uint64_t GetBase() const { return 0; } - virtual uint32_t GetSize() const { return 0; } - virtual bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { - *value = address + 1; - return true; - } - virtual bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { - *value = address + 1; - return true; - } - virtual bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { - *value = address + 1; - return true; - } - virtual bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { - *value = address + 1; - return true; - } - virtual void Print() const { - assert(false); - } -}; - - -struct EvaluateTest { - // Expression passed to PostfixEvaluator::Evaluate. - const string expression; - - // True if the expression is expected to be evaluable, false if evaluation - // is expected to fail. - bool evaluable; -}; - - -struct EvaluateTestSet { - // The dictionary used for all tests in the set. - PostfixEvaluator::DictionaryType *dictionary; - - // The list of tests. - const EvaluateTest *evaluate_tests; - - // The number of tests. - unsigned int evaluate_test_count; - - // Identifiers and their expected values upon completion of the Evaluate - // tests in the set. - map *validate_data; -}; - - -struct EvaluateForValueTest { - // Expression passed to PostfixEvaluator::Evaluate. - const string expression; - - // True if the expression is expected to be evaluable, false if evaluation - // is expected to fail. - bool evaluable; - - // If evaluable, the value we expect it to yield. - unsigned int value; -}; - -static bool RunTests() { - // The first test set checks the basic operations and failure modes. - PostfixEvaluator::DictionaryType dictionary_0; - const EvaluateTest evaluate_tests_0[] = { - { "$rAdd 2 2 + =", true }, // $rAdd = 2 + 2 = 4 - { "$rAdd $rAdd 2 + =", true }, // $rAdd = $rAdd + 2 = 6 - { "$rAdd 2 $rAdd + =", true }, // $rAdd = 2 + $rAdd = 8 - { "99", false }, // put some junk on the stack... - { "$rAdd2 2 2 + =", true }, // ...and make sure things still work - { "$rAdd2\t2\n2 + =", true }, // same but with different whitespace - { "$rAdd2 2 2 + = ", true }, // trailing whitespace - { " $rAdd2 2 2 + =", true }, // leading whitespace - { "$rAdd2 2 2 + =", true }, // extra whitespace - { "$T0 2 = +", false }, // too few operands for add - { "2 + =", false }, // too few operands for add - { "2 +", false }, // too few operands for add - { "+", false }, // too few operands for add - { "^", false }, // too few operands for dereference - { "=", false }, // too few operands for assignment - { "2 =", false }, // too few operands for assignment - { "2 2 + =", false }, // too few operands for assignment - { "2 2 =", false }, // can't assign into a literal - { "k 2 =", false }, // can't assign into a constant - { "2", false }, // leftover data on stack - { "2 2 +", false }, // leftover data on stack - { "$rAdd", false }, // leftover data on stack - { "0 $T1 0 0 + =", false }, // leftover data on stack - { "$T2 $T2 2 + =", false }, // can't operate on an undefined value - { "$rMul 9 6 * =", true }, // $rMul = 9 * 6 = 54 - { "$rSub 9 6 - =", true }, // $rSub = 9 - 6 = 3 - { "$rDivQ 9 6 / =", true }, // $rDivQ = 9 / 6 = 1 - { "$rDivM 9 6 % =", true }, // $rDivM = 9 % 6 = 3 - { "$rDeref 9 ^ =", true }, // $rDeref = ^9 = 10 (FakeMemoryRegion) - { "$rAlign 36 8 @ =", true }, // $rAlign = 36 @ 8 - { "$rAdd3 2 2 + =$rMul2 9 6 * =", true } // smashed-equals tokenization - }; - map validate_data_0; - validate_data_0["$rAdd"] = 8; - validate_data_0["$rAdd2"] = 4; - validate_data_0["$rSub"] = 3; - validate_data_0["$rMul"] = 54; - validate_data_0["$rDivQ"] = 1; - validate_data_0["$rDivM"] = 3; - validate_data_0["$rDeref"] = 10; - validate_data_0["$rAlign"] = 32; - validate_data_0["$rAdd3"] = 4; - validate_data_0["$rMul2"] = 54; - - // The second test set simulates a couple of MSVC program strings. - // The data is fudged a little bit because the tests use FakeMemoryRegion - // instead of a real stack snapshot, but the program strings are real and - // the implementation doesn't know or care that the data is not real. - PostfixEvaluator::DictionaryType dictionary_1; - dictionary_1["$ebp"] = 0xbfff0010; - dictionary_1["$eip"] = 0x10000000; - dictionary_1["$esp"] = 0xbfff0000; - dictionary_1[".cbSavedRegs"] = 4; - dictionary_1[".cbParams"] = 4; - dictionary_1[".raSearchStart"] = 0xbfff0020; - const EvaluateTest evaluate_tests_1[] = { - { "$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = " - "$L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =", true }, - // Intermediate state: $T0 = 0xbfff0010, $eip = 0xbfff0015, - // $ebp = 0xbfff0011, $esp = 0xbfff0018, - // $L = 0xbfff000c, $P = 0xbfff001c - { "$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = " - "$L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 28 - ^ =", - true }, - // Intermediate state: $T0 = 0xbfff0011, $eip = 0xbfff0016, - // $ebp = 0xbfff0012, $esp = 0xbfff0019, - // $L = 0xbfff000d, $P = 0xbfff001d, - // $ebx = 0xbffefff6 - { "$T0 $ebp = $T2 $esp = $T1 .raSearchStart = $eip $T1 ^ = $ebp $T0 = " - "$esp $T1 4 + = $L $T0 .cbSavedRegs - = $P $T1 4 + .cbParams + = " - "$ebx $T0 28 - ^ =", - true } - }; - map validate_data_1; - validate_data_1["$T0"] = 0xbfff0012; - validate_data_1["$T1"] = 0xbfff0020; - validate_data_1["$T2"] = 0xbfff0019; - validate_data_1["$eip"] = 0xbfff0021; - validate_data_1["$ebp"] = 0xbfff0012; - validate_data_1["$esp"] = 0xbfff0024; - validate_data_1["$L"] = 0xbfff000e; - validate_data_1["$P"] = 0xbfff0028; - validate_data_1["$ebx"] = 0xbffefff7; - validate_data_1[".cbSavedRegs"] = 4; - validate_data_1[".cbParams"] = 4; - - EvaluateTestSet evaluate_test_sets[] = { - { &dictionary_0, evaluate_tests_0, - sizeof(evaluate_tests_0) / sizeof(EvaluateTest), &validate_data_0 }, - { &dictionary_1, evaluate_tests_1, - sizeof(evaluate_tests_1) / sizeof(EvaluateTest), &validate_data_1 }, - }; - - unsigned int evaluate_test_set_count = sizeof(evaluate_test_sets) / - sizeof(EvaluateTestSet); - - FakeMemoryRegion fake_memory; - PostfixEvaluator postfix_evaluator = - PostfixEvaluator(NULL, &fake_memory); - - for (unsigned int evaluate_test_set_index = 0; - evaluate_test_set_index < evaluate_test_set_count; - ++evaluate_test_set_index) { - EvaluateTestSet *evaluate_test_set = - &evaluate_test_sets[evaluate_test_set_index]; - const EvaluateTest *evaluate_tests = evaluate_test_set->evaluate_tests; - unsigned int evaluate_test_count = evaluate_test_set->evaluate_test_count; - - // The same dictionary will be used for each test in the set. Earlier - // tests can affect the state of the dictionary for later tests. - postfix_evaluator.set_dictionary(evaluate_test_set->dictionary); - - // Use a new validity dictionary for each test set. - PostfixEvaluator::DictionaryValidityType assigned; - - for (unsigned int evaluate_test_index = 0; - evaluate_test_index < evaluate_test_count; - ++evaluate_test_index) { - const EvaluateTest *evaluate_test = &evaluate_tests[evaluate_test_index]; - - // Do the test. - bool result = postfix_evaluator.Evaluate(evaluate_test->expression, - &assigned); - if (result != evaluate_test->evaluable) { - fprintf(stderr, "FAIL: evaluate set %d/%d, test %d/%d, " - "expression \"%s\", expected %s, observed %s\n", - evaluate_test_set_index, evaluate_test_set_count, - evaluate_test_index, evaluate_test_count, - evaluate_test->expression.c_str(), - evaluate_test->evaluable ? "evaluable" : "not evaluable", - result ? "evaluted" : "not evaluated"); - return false; - } - } - - // Validate the results. - for (map::const_iterator validate_iterator = - evaluate_test_set->validate_data->begin(); - validate_iterator != evaluate_test_set->validate_data->end(); - ++validate_iterator) { - const string identifier = validate_iterator->first; - unsigned int expected_value = validate_iterator->second; - - map::const_iterator dictionary_iterator = - evaluate_test_set->dictionary->find(identifier); - - // The identifier must exist in the dictionary. - if (dictionary_iterator == evaluate_test_set->dictionary->end()) { - fprintf(stderr, "FAIL: evaluate test set %d/%d, " - "validate identifier \"%s\", " - "expected %d, observed not found\n", - evaluate_test_set_index, evaluate_test_set_count, - identifier.c_str(), expected_value); - return false; - } - - // The value in the dictionary must be the same as the expected value. - unsigned int observed_value = dictionary_iterator->second; - if (expected_value != observed_value) { - fprintf(stderr, "FAIL: evaluate test set %d/%d, " - "validate identifier \"%s\", " - "expected %d, observed %d\n", - evaluate_test_set_index, evaluate_test_set_count, - identifier.c_str(), expected_value, observed_value); - return false; - } - - // The value must be set in the "assigned" dictionary if it was a - // variable. It must not have been assigned if it was a constant. - bool expected_assigned = identifier[0] == '$'; - bool observed_assigned = false; - PostfixEvaluator::DictionaryValidityType::const_iterator - iterator_assigned = assigned.find(identifier); - if (iterator_assigned != assigned.end()) { - observed_assigned = iterator_assigned->second; - } - if (expected_assigned != observed_assigned) { - fprintf(stderr, "FAIL: evaluate test set %d/%d, " - "validate assignment of \"%s\", " - "expected %d, observed %d\n", - evaluate_test_set_index, evaluate_test_set_count, - identifier.c_str(), expected_assigned, observed_assigned); - return false; - } - } - } - - // EvaluateForValue tests. - PostfixEvaluator::DictionaryType dictionary_2; - dictionary_2["$ebp"] = 0xbfff0010; - dictionary_2["$eip"] = 0x10000000; - dictionary_2["$esp"] = 0xbfff0000; - dictionary_2[".cbSavedRegs"] = 4; - dictionary_2[".cbParams"] = 4; - dictionary_2[".raSearchStart"] = 0xbfff0020; - const EvaluateForValueTest evaluate_for_value_tests_2[] = { - { "28907223", true, 28907223 }, // simple constant - { "89854293 40010015 +", true, 89854293 + 40010015 }, // arithmetic - { "-870245 8769343 +", true, 7899098 }, // negative constants - { "$ebp $esp - $eip +", true, 0x10000010 }, // variable references - { "18929794 34015074", false, 0 }, // too many values - { "$ebp $ebp 4 - =", false, 0 }, // too few values - { "$new $eip = $new", true, 0x10000000 }, // make new variable - { "$new 4 +", true, 0x10000004 }, // see prior assignments - { ".cfa 42 = 10", false, 0 } // can't set constants - }; - const int evaluate_for_value_tests_2_size - = (sizeof (evaluate_for_value_tests_2) - / sizeof (evaluate_for_value_tests_2[0])); - map validate_data_2; - validate_data_2["$eip"] = 0x10000000; - validate_data_2["$ebp"] = 0xbfff000c; - validate_data_2["$esp"] = 0xbfff0000; - validate_data_2["$new"] = 0x10000000; - validate_data_2[".cbSavedRegs"] = 4; - validate_data_2[".cbParams"] = 4; - validate_data_2[".raSearchStart"] = 0xbfff0020; - - postfix_evaluator.set_dictionary(&dictionary_2); - for (int i = 0; i < evaluate_for_value_tests_2_size; i++) { - const EvaluateForValueTest *test = &evaluate_for_value_tests_2[i]; - unsigned int result; - if (postfix_evaluator.EvaluateForValue(test->expression, &result) - != test->evaluable) { - fprintf(stderr, "FAIL: evaluate for value test %d, " - "expected evaluation to %s, but it %s\n", - i, test->evaluable ? "succeed" : "fail", - test->evaluable ? "failed" : "succeeded"); - return false; - } - if (test->evaluable && result != test->value) { - fprintf(stderr, "FAIL: evaluate for value test %d, " - "expected value to be 0x%x, but it was 0x%x\n", - i, test->value, result); - return false; - } - } - - for (map::iterator v = validate_data_2.begin(); - v != validate_data_2.end(); v++) { - map::iterator a = dictionary_2.find(v->first); - if (a == dictionary_2.end()) { - fprintf(stderr, "FAIL: evaluate for value dictionary check: " - "expected dict[\"%s\"] to be 0x%x, but it was unset\n", - v->first.c_str(), v->second); - return false; - } else if (a->second != v->second) { - fprintf(stderr, "FAIL: evaluate for value dictionary check: " - "expected dict[\"%s\"] to be 0x%x, but it was 0x%x\n", - v->first.c_str(), v->second, a->second); - return false; - } - dictionary_2.erase(a); - } - - map::iterator remaining = dictionary_2.begin(); - if (remaining != dictionary_2.end()) { - fprintf(stderr, "FAIL: evaluation of test expressions put unexpected " - "values in dictionary:\n"); - for (; remaining != dictionary_2.end(); remaining++) - fprintf(stderr, " dict[\"%s\"] == 0x%x\n", - remaining->first.c_str(), remaining->second); - return false; - } - - return true; -} - - -} // namespace - - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux.cc b/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux.cc deleted file mode 100644 index 3c0dea25d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif - -#include "google_breakpad/processor/proc_maps_linux.h" - -#include -#include -#include - -#include "common/using_std_string.h" -#include "processor/logging.h" - -#if defined(OS_ANDROID) && !defined(__LP64__) -// In 32-bit mode, Bionic's inttypes.h defines PRI/SCNxPTR as an -// unsigned long int, which is incompatible with Bionic's stdint.h -// defining uintptr_t as an unsigned int: -// https://code.google.com/p/android/issues/detail?id=57218 -#undef SCNxPTR -#define SCNxPTR "x" -#endif - -namespace google_breakpad { - -bool ParseProcMaps(const string& input, - std::vector* regions_out) { - std::vector regions; - - // This isn't async safe nor terribly efficient, but it doesn't need to be at - // this point in time. - - // Split the string by newlines. - std::vector lines; - string l = ""; - for (size_t i = 0; i < input.size(); i++) { - if (input[i] != '\n' && input[i] != '\r') { - l.push_back(input[i]); - } else if (l.size() > 0) { - lines.push_back(l); - l.clear(); - } - } - if (l.size() > 0) { - BPLOG(ERROR) << "Input doesn't end in newline"; - return false; - } - - for (size_t i = 0; i < lines.size(); ++i) { - MappedMemoryRegion region; - const char* line = lines[i].c_str(); - char permissions[5] = {'\0'}; // Ensure NUL-terminated string. - int path_index = 0; - - // Sample format from man 5 proc: - // - // address perms offset dev inode pathname - // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm - // - // The final %n term captures the offset in the input string, which is used - // to determine the path name. It *does not* increment the return value. - // Refer to man 3 sscanf for details. - if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %4c %" SCNx64" %hhx:%hhx %" - SCNd64 " %n", ®ion.start, ®ion.end, permissions, - ®ion.offset, ®ion.major_device, ®ion.minor_device, - ®ion.inode, &path_index) < 7) { - BPLOG(ERROR) << "sscanf failed for line: " << line; - return false; - } - - region.permissions = 0; - - if (permissions[0] == 'r') - region.permissions |= MappedMemoryRegion::READ; - else if (permissions[0] != '-') - return false; - - if (permissions[1] == 'w') - region.permissions |= MappedMemoryRegion::WRITE; - else if (permissions[1] != '-') - return false; - - if (permissions[2] == 'x') - region.permissions |= MappedMemoryRegion::EXECUTE; - else if (permissions[2] != '-') - return false; - - if (permissions[3] == 'p') - region.permissions |= MappedMemoryRegion::PRIVATE; - else if (permissions[3] != 's' && permissions[3] != 'S') // Shared memory. - return false; - - // Pushing then assigning saves us a string copy. - regions.push_back(region); - regions.back().path.assign(line + path_index); - regions.back().line.assign(line); - } - - regions_out->swap(regions); - return true; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux_unittest.cc deleted file mode 100644 index 466f23455..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux_unittest.cc +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/proc_maps_linux.h" - -namespace { - -TEST(ProcMapsTest, Empty) { - std::vector regions; - EXPECT_TRUE(ParseProcMaps("", ®ions)); - EXPECT_EQ(0u, regions.size()); -} - -TEST(ProcMapsTest, NoSpaces) { - static const char kNoSpaces[] = - "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kNoSpaces, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0x00400000u, regions[0].start); - EXPECT_EQ(0x0040b000u, regions[0].end); - EXPECT_EQ(0x00002200u, regions[0].offset); - EXPECT_EQ("/bin/cat", regions[0].path); -} - -TEST(ProcMapsTest, Spaces) { - static const char kSpaces[] = - "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/space cat\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kSpaces, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0x00400000u, regions[0].start); - EXPECT_EQ(0x0040b000u, regions[0].end); - EXPECT_EQ(0x00002200u, regions[0].offset); - EXPECT_EQ("/bin/space cat", regions[0].path); -} - -TEST(ProcMapsTest, NoNewline) { - static const char kNoSpaces[] = - "00400000-0040b000 r-xp 00002200 fc:00 794418 /bin/cat"; - - std::vector regions; - ASSERT_FALSE(ParseProcMaps(kNoSpaces, ®ions)); -} - -TEST(ProcMapsTest, NoPath) { - static const char kNoPath[] = - "00400000-0040b000 rw-p 00000000 00:00 0 \n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kNoPath, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0x00400000u, regions[0].start); - EXPECT_EQ(0x0040b000u, regions[0].end); - EXPECT_EQ(0x00000000u, regions[0].offset); - EXPECT_EQ("", regions[0].path); -} - -TEST(ProcMapsTest, Heap) { - static const char kHeap[] = - "022ac000-022cd000 rw-p 00000000 00:00 0 [heap]\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kHeap, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0x022ac000u, regions[0].start); - EXPECT_EQ(0x022cd000u, regions[0].end); - EXPECT_EQ(0x00000000u, regions[0].offset); - EXPECT_EQ("[heap]", regions[0].path); -} - -#if defined(ARCH_CPU_32_BITS) -TEST(ProcMapsTest, Stack32) { - static const char kStack[] = - "beb04000-beb25000 rw-p 00000000 00:00 0 [stack]\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0xbeb04000u, regions[0].start); - EXPECT_EQ(0xbeb25000u, regions[0].end); - EXPECT_EQ(0x00000000u, regions[0].offset); - EXPECT_EQ("[stack]", regions[0].path); -} -#elif defined(ARCH_CPU_64_BITS) -TEST(ProcMapsTest, Stack64) { - static const char kStack[] = - "7fff69c5b000-7fff69c7d000 rw-p 00000000 00:00 0 [stack]\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kStack, ®ions)); - ASSERT_EQ(1u, regions.size()); - - EXPECT_EQ(0x7fff69c5b000u, regions[0].start); - EXPECT_EQ(0x7fff69c7d000u, regions[0].end); - EXPECT_EQ(0x00000000u, regions[0].offset); - EXPECT_EQ("[stack]", regions[0].path); -} -#endif - -TEST(ProcMapsTest, Multiple) { - static const char kMultiple[] = - "00400000-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n" - "0060a000-0060b000 r--p 0000a000 fc:00 794418 /bin/cat\n" - "0060b000-0060c000 rw-p 0000b000 fc:00 794418 /bin/cat\n"; - - std::vector regions; - ASSERT_TRUE(ParseProcMaps(kMultiple, ®ions)); - ASSERT_EQ(3u, regions.size()); - - EXPECT_EQ(0x00400000u, regions[0].start); - EXPECT_EQ(0x0040b000u, regions[0].end); - EXPECT_EQ(0x00000000u, regions[0].offset); - EXPECT_EQ("/bin/cat", regions[0].path); - - EXPECT_EQ(0x0060a000u, regions[1].start); - EXPECT_EQ(0x0060b000u, regions[1].end); - EXPECT_EQ(0x0000a000u, regions[1].offset); - EXPECT_EQ("/bin/cat", regions[1].path); - - EXPECT_EQ(0x0060b000u, regions[2].start); - EXPECT_EQ(0x0060c000u, regions[2].end); - EXPECT_EQ(0x0000b000u, regions[2].offset); - EXPECT_EQ("/bin/cat", regions[2].path); -} - -TEST(ProcMapsTest, Permissions) { - static struct { - const char* input; - uint8_t permissions; - } kTestCases[] = { - {"00400000-0040b000 ---s 00000000 fc:00 794418 /bin/cat\n", 0}, - {"00400000-0040b000 ---S 00000000 fc:00 794418 /bin/cat\n", 0}, - {"00400000-0040b000 r--s 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::READ}, - {"00400000-0040b000 -w-s 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::WRITE}, - {"00400000-0040b000 --xs 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::EXECUTE}, - {"00400000-0040b000 rwxs 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::READ - | google_breakpad::MappedMemoryRegion::WRITE - | google_breakpad::MappedMemoryRegion::EXECUTE}, - {"00400000-0040b000 ---p 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::PRIVATE}, - {"00400000-0040b000 r--p 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::READ - | google_breakpad::MappedMemoryRegion::PRIVATE}, - {"00400000-0040b000 -w-p 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::WRITE - | google_breakpad::MappedMemoryRegion::PRIVATE}, - {"00400000-0040b000 --xp 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::EXECUTE - | google_breakpad::MappedMemoryRegion::PRIVATE}, - {"00400000-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", - google_breakpad::MappedMemoryRegion::READ - | google_breakpad::MappedMemoryRegion::WRITE - | google_breakpad::MappedMemoryRegion::EXECUTE - | google_breakpad::MappedMemoryRegion::PRIVATE}, - }; - - for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { - std::vector regions; - EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, ®ions)); - EXPECT_EQ(1u, regions.size()); - if (regions.empty()) - continue; - EXPECT_EQ(kTestCases[i].permissions, regions[0].permissions); - } -} - -TEST(ProcMapsTest, MissingFields) { - static const char* kTestCases[] = { - "00400000\n", // Missing end + beyond. - "00400000-0040b000\n", // Missing perms + beyond. - "00400000-0040b000 r-xp\n", // Missing offset + beyond. - "00400000-0040b000 r-xp 00000000\n", // Missing device + beyond. - "00400000-0040b000 r-xp 00000000 fc:00\n", // Missing inode + beyond. - "00400000-0040b000 00000000 fc:00 794418 /bin/cat\n", // Missing perms. - "00400000-0040b000 r-xp fc:00 794418 /bin/cat\n", // Missing offset. - "00400000-0040b000 r-xp 00000000 fc:00 /bin/cat\n", // Missing inode. - "00400000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing end. - "-0040b000 r-xp 00000000 fc:00 794418 /bin/cat\n", // Missing start. - "00400000-0040b000 r-xp 00000000 794418 /bin/cat\n", // Missing device. - }; - - for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { - std::vector regions; - EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); - } -} - -TEST(ProcMapsTest, InvalidInput) { - static const char* kTestCases[] = { - "thisisal-0040b000 rwxp 00000000 fc:00 794418 /bin/cat\n", - "0040000d-linvalid rwxp 00000000 fc:00 794418 /bin/cat\n", - "00400000-0040b000 inpu 00000000 fc:00 794418 /bin/cat\n", - "00400000-0040b000 rwxp tforproc fc:00 794418 /bin/cat\n", - "00400000-0040b000 rwxp 00000000 ma:ps 794418 /bin/cat\n", - "00400000-0040b000 rwxp 00000000 fc:00 parse! /bin/cat\n", - }; - - for (size_t i = 0; i < sizeof(kTestCases) / sizeof(kTestCases[0]); ++i) { - std::vector regions; - EXPECT_FALSE(ParseProcMaps(kTestCases[i], ®ions)); - } -} - -TEST(ProcMapsTest, ParseProcMapsEmptyString) { - std::vector regions; - EXPECT_TRUE(ParseProcMaps("", ®ions)); - EXPECT_EQ(0ULL, regions.size()); -} - -// Testing a couple of remotely possible weird things in the input: -// - Line ending with \r\n or \n\r. -// - File name contains quotes. -// - File name has whitespaces. -TEST(ProcMapsTest, ParseProcMapsWeirdCorrectInput) { - std::vector regions; - const string kContents = - "00400000-0040b000 r-xp 00000000 fc:00 2106562 " - " /bin/cat\r\n" - "7f53b7dad000-7f53b7f62000 r-xp 00000000 fc:00 263011 " - " /lib/x86_64-linux-gnu/libc-2.15.so\n\r" - "7f53b816d000-7f53b818f000 r-xp 00000000 fc:00 264284 " - " /lib/x86_64-linux-gnu/ld-2.15.so\n" - "7fff9c7ff000-7fff9c800000 r-xp 00000000 00:00 0 " - " \"vd so\"\n" - "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 " - " [vsys call]\n"; - EXPECT_TRUE(ParseProcMaps(kContents, ®ions)); - EXPECT_EQ(5ULL, regions.size()); - EXPECT_EQ("/bin/cat", regions[0].path); - EXPECT_EQ("/lib/x86_64-linux-gnu/libc-2.15.so", regions[1].path); - EXPECT_EQ("/lib/x86_64-linux-gnu/ld-2.15.so", regions[2].path); - EXPECT_EQ("\"vd so\"", regions[3].path); - EXPECT_EQ("[vsys call]", regions[4].path); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/processor/process_state.cc b/toolkit/crashreporter/google-breakpad/src/processor/process_state.cc deleted file mode 100644 index 5a5cd7f62..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/process_state.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// process_state.cc: A snapshot of a process, in a fully-digested state. -// -// See process_state.h for documentation. -// -// Author: Mark Mentovai - -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_modules.h" - -namespace google_breakpad { - -ProcessState::~ProcessState() { - Clear(); -} - -void ProcessState::Clear() { - time_date_stamp_ = 0; - process_create_time_ = 0; - crashed_ = false; - crash_reason_.clear(); - crash_address_ = 0; - assertion_.clear(); - requesting_thread_ = -1; - for (vector::const_iterator iterator = threads_.begin(); - iterator != threads_.end(); - ++iterator) { - delete *iterator; - } - threads_.clear(); - system_info_.Clear(); - // modules_without_symbols_ and modules_with_corrupt_symbols_ DO NOT own - // the underlying CodeModule pointers. Just clear the vectors. - modules_without_symbols_.clear(); - modules_with_corrupt_symbols_.clear(); - delete modules_; - modules_ = NULL; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/processor.gyp b/toolkit/crashreporter/google-breakpad/src/processor/processor.gyp deleted file mode 100644 index 083a3237f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/processor.gyp +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../build/common.gypi', - 'processor_tools.gypi', - ], - 'targets': [ - { - 'target_name': 'processor', - 'type': 'static_library', - 'sources': [ - 'address_map-inl.h', - 'address_map.h', - 'basic_code_module.h', - 'basic_code_modules.cc', - 'basic_code_modules.h', - 'basic_source_line_resolver.cc', - 'basic_source_line_resolver_types.h', - 'call_stack.cc', - 'cfi_frame_info-inl.h', - 'cfi_frame_info.cc', - 'cfi_frame_info.h', - 'contained_range_map-inl.h', - 'contained_range_map.h', - 'disassembler_x86.cc', - 'disassembler_x86.h', - 'dump_context.cc', - 'dump_object.cc', - 'exploitability.cc', - 'exploitability_linux.cc', - 'exploitability_linux.h', - 'exploitability_win.cc', - 'exploitability_win.h', - 'fast_source_line_resolver.cc', - 'fast_source_line_resolver_types.h', - 'linked_ptr.h', - 'logging.cc', - 'logging.h', - 'map_serializers-inl.h', - 'map_serializers.h', - 'microdump_processor.cc', - 'minidump.cc', - 'minidump_processor.cc', - 'module_comparer.cc', - 'module_comparer.h', - 'module_factory.h', - 'module_serializer.cc', - 'module_serializer.h', - 'pathname_stripper.cc', - 'pathname_stripper.h', - 'postfix_evaluator-inl.h', - 'postfix_evaluator.h', - 'proc_maps_linux.cc', - 'process_state.cc', - 'range_map-inl.h', - 'range_map.h', - 'simple_serializer-inl.h', - 'simple_serializer.h', - 'simple_symbol_supplier.cc', - 'simple_symbol_supplier.h', - 'source_line_resolver_base.cc', - 'source_line_resolver_base_types.h', - 'stack_frame_cpu.cc', - 'stack_frame_symbolizer.cc', - 'stackwalk_common.cc', - 'stackwalk_common.h', - 'stackwalker.cc', - 'stackwalker_address_list.cc', - 'stackwalker_address_list.h', - 'stackwalker_amd64.cc', - 'stackwalker_amd64.h', - 'stackwalker_arm.cc', - 'stackwalker_arm.h', - 'stackwalker_arm64.cc', - 'stackwalker_arm64.h', - 'stackwalker_mips.cc', - 'stackwalker_mips.h', - 'stackwalker_ppc.cc', - 'stackwalker_ppc.h', - 'stackwalker_ppc64.cc', - 'stackwalker_ppc64.h', - 'stackwalker_selftest.cc', - 'stackwalker_sparc.cc', - 'stackwalker_sparc.h', - 'stackwalker_x86.cc', - 'stackwalker_x86.h', - 'static_address_map-inl.h', - 'static_address_map.h', - 'static_contained_range_map-inl.h', - 'static_contained_range_map.h', - 'static_map-inl.h', - 'static_map.h', - 'static_map_iterator-inl.h', - 'static_map_iterator.h', - 'static_range_map-inl.h', - 'static_range_map.h', - 'symbolic_constants_win.cc', - 'symbolic_constants_win.h', - 'synth_minidump.cc', - 'synth_minidump.h', - 'tokenize.cc', - 'tokenize.h', - 'windows_frame_info.h', - ], - 'include_dirs': [ - '..', - ], - 'dependencies': [ - '../common/common.gyp:common', - '../third_party/libdisasm/libdisasm.gyp:libdisasm', - ], - }, - { - 'target_name': 'processor_unittests', - 'type': 'executable', - 'sources': [ - 'address_map_unittest.cc', - 'basic_source_line_resolver_unittest.cc', - 'cfi_frame_info_unittest.cc', - 'contained_range_map_unittest.cc', - 'disassembler_x86_unittest.cc', - 'exploitability_unittest.cc', - 'fast_source_line_resolver_unittest.cc', - 'map_serializers_unittest.cc', - 'microdump_processor_unittest.cc', - 'minidump_processor_unittest.cc', - 'minidump_unittest.cc', - 'pathname_stripper_unittest.cc', - 'postfix_evaluator_unittest.cc', - 'range_map_shrink_down_unittest.cc', - 'range_map_unittest.cc', - 'stackwalker_address_list_unittest.cc', - 'stackwalker_amd64_unittest.cc', - 'stackwalker_arm64_unittest.cc', - 'stackwalker_arm_unittest.cc', - 'stackwalker_mips_unittest.cc', - 'stackwalker_mips64_unittest.cc', - 'stackwalker_unittest_utils.h', - 'stackwalker_x86_unittest.cc', - 'static_address_map_unittest.cc', - 'static_contained_range_map_unittest.cc', - 'static_map_unittest.cc', - 'static_range_map_unittest.cc', - 'synth_minidump_unittest.cc', - 'synth_minidump_unittest_data.h', - ], - 'include_dirs': [ - '..', - ], - 'dependencies': [ - 'processor', - '../build/testing.gypi:gmock', - '../build/testing.gypi:gtest', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/processor_tools.gypi b/toolkit/crashreporter/google-breakpad/src/processor/processor_tools.gypi deleted file mode 100644 index ecb450d60..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/processor_tools.gypi +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'target_defaults': { - 'include_dirs': [ - '..', - ], - }, - 'targets': [ - { - 'target_name': 'minidump_dump', - 'type': 'executable', - 'sources': [ - 'minidump_dump.cc', - ], - 'dependencies': [ - 'processor', - ], - }, - { - 'target_name': 'minidump_stackwalk', - 'type': 'executable', - 'sources': [ - 'minidump_stackwalk.cc', - ], - 'dependencies': [ - 'processor', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/proto/README b/toolkit/crashreporter/google-breakpad/src/processor/proto/README deleted file mode 100644 index df37b6f39..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/proto/README +++ /dev/null @@ -1,20 +0,0 @@ -If you wish to use these protobufs, you must generate their source files -using protoc from the protobuf project (http://code.google.com/p/protobuf/). - ------ -Troubleshooting for Protobuf: - -Install: -If you are getting permission errors install, make sure you are not trying to -install from an NFS. - - -Running protoc: -protoc: error while loading shared libraries: libprotobuf.so.0: cannot open -shared object file: No such file or directory - -The issue is that Ubuntu 8.04 doesn't include /usr/local/lib in -library paths. - -To fix it for your current terminal session, just type in -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib diff --git a/toolkit/crashreporter/google-breakpad/src/processor/proto/process_state.proto b/toolkit/crashreporter/google-breakpad/src/processor/proto/process_state.proto deleted file mode 100644 index d3e02dc3f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/proto/process_state.proto +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// process_state_proto.proto: A client proto representation of a process, -// in a fully-digested state. -// -// Derived from earlier struct and class based models of a client-side -// processed minidump found under src/google_breakpad/processor. The -// file process_state.h holds the top level representation of this model, -// supported by additional classes. We've added a proto representation -// to ease serialization and parsing for server-side storage of crash -// reports processed on the client. -// -// Author: Jess Gray - -syntax = "proto2"; - -package google_breakpad; - -// A proto representation of a process, in a fully-digested state. -// See src/google_breakpad/processor/process_state.h -message ProcessStateProto { - // Next value: 14 - - // The time-date stamp of the original minidump (time_t format) - optional int64 time_date_stamp = 1; - - // The time-date stamp when the process was created (time_t format) - optional int64 process_create_time = 13; - - message Crash { - // The type of crash. OS- and possibly CPU- specific. For example, - // "EXCEPTION_ACCESS_VIOLATION" (Windows), "EXC_BAD_ACCESS / - // KERN_INVALID_ADDRESS" (Mac OS X), "SIGSEGV" (other Unix). - required string reason = 1; - - // If crash_reason implicates memory, the memory address that caused the - // crash. For data access errors, this will be the data address that - // caused the fault. For code errors, this will be the address of the - // instruction that caused the fault. - required int64 address = 2; - } - optional Crash crash = 2; - - - // If there was an assertion that was hit, a textual representation - // of that assertion, possibly including the file and line at which - // it occurred. - optional string assertion = 3; - - // The index of the thread that requested a dump be written in the - // threads vector. If a dump was produced as a result of a crash, this - // will point to the thread that crashed. If the dump was produced as - // by user code without crashing, and the dump contains extended Breakpad - // information, this will point to the thread that requested the dump. - optional int32 requesting_thread = 4; - - message Thread { - // Stack for the given thread - repeated StackFrame frames = 1; - } - - // Stacks for each thread (except possibly the exception handler - // thread) at the time of the crash. - repeated Thread threads = 5; - - // The modules that were loaded into the process represented by the - // ProcessState. - repeated CodeModule modules = 6; - - // System Info: OS and CPU - - // A string identifying the operating system, such as "Windows NT", - // "Mac OS X", or "Linux". If the information is present in the dump but - // its value is unknown, this field will contain a numeric value. If - // the information is not present in the dump, this field will be empty. - optional string os = 7; - - // A short form of the os string, using lowercase letters and no spaces, - // suitable for use in a filesystem. Possible values are "windows", - // "mac", and "linux". Empty if the information is not present in the dump - // or if the OS given by the dump is unknown. The values stored in this - // field should match those used by MinidumpSystemInfo::GetOS. - optional string os_short = 8; - - // A string identifying the version of the operating system, such as - // "5.1.2600 Service Pack 2" or "10.4.8 8L2127". If the dump does not - // contain this information, this field will be empty. - optional string os_version = 9; - - // A string identifying the basic CPU family, such as "x86" or "ppc". - // If this information is present in the dump but its value is unknown, - // this field will contain a numeric value. If the information is not - // present in the dump, this field will be empty. The values stored in - // this field should match those used by MinidumpSystemInfo::GetCPU. - optional string cpu = 10; - - // A string further identifying the specific CPU, such as - // "GenuineIntel level 6 model 13 stepping 8". If the information is not - // present in the dump, or additional identifying information is not - // defined for the CPU family, this field will be empty. - optional string cpu_info = 11; - - // The number of processors in the system. Will be greater than one for - // multi-core systems. - optional int32 cpu_count = 12; - - // Leave the ability to add the raw minidump to this representation -} - - -// Represents a single frame in a stack -// See src/google_breakpad/processor/code_module.h -message StackFrame { - // Next value: 8 - - // The program counter location as an absolute virtual address. For the - // innermost called frame in a stack, this will be an exact program counter - // or instruction pointer value. For all other frames, this will be within - // the instruction that caused execution to branch to a called function, - // but may not necessarily point to the exact beginning of that instruction. - required int64 instruction = 1; - - // The module in which the instruction resides. - optional CodeModule module = 2; - - // The function name, may be omitted if debug symbols are not available. - optional string function_name = 3; - - // The start address of the function, may be omitted if debug symbols - // are not available. - optional int64 function_base = 4; - - // The source file name, may be omitted if debug symbols are not available. - optional string source_file_name = 5; - - // The (1-based) source line number, may be omitted if debug symbols are - // not available. - optional int32 source_line = 6; - - // The start address of the source line, may be omitted if debug symbols - // are not available. - optional int64 source_line_base = 7; -} - - -// Carries information about code modules that are loaded into a process. -// See src/google_breakpad/processor/code_module.h -message CodeModule { - // Next value: 8 - - // The base address of this code module as it was loaded by the process. - optional int64 base_address = 1; - - // The size of the code module. - optional int64 size = 2; - - // The path or file name that the code module was loaded from. - optional string code_file = 3; - - // An identifying string used to discriminate between multiple versions and - // builds of the same code module. This may contain a uuid, timestamp, - // version number, or any combination of this or other information, in an - // implementation-defined format. - optional string code_identifier = 4; - - // The filename containing debugging information associated with the code - // module. If debugging information is stored in a file separate from the - // code module itself (as is the case when .pdb or .dSYM files are used), - // this will be different from code_file. If debugging information is - // stored in the code module itself (possibly prior to stripping), this - // will be the same as code_file. - optional string debug_file = 5; - - // An identifying string similar to code_identifier, but identifies a - // specific version and build of the associated debug file. This may be - // the same as code_identifier when the debug_file and code_file are - // identical or when the same identifier is used to identify distinct - // debug and code files. - optional string debug_identifier = 6; - - // A human-readable representation of the code module's version. - optional string version = 7; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h deleted file mode 100644 index 9fe74c502..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// range_map-inl.h: Range map implementation. -// -// See range_map.h for documentation. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_RANGE_MAP_INL_H__ -#define PROCESSOR_RANGE_MAP_INL_H__ - - -#include - -#include "processor/range_map.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" - - -namespace google_breakpad { - -template -void RangeMap::SetEnableShrinkDown( - bool enable_shrink_down) { - enable_shrink_down_ = enable_shrink_down; -} - -template -bool RangeMap::IsShrinkDownEnabled() const { - return enable_shrink_down_; -} - -template -bool RangeMap::StoreRange(const AddressType &base, - const AddressType &size, - const EntryType &entry) { - return StoreRangeInternal(base, 0 /* delta */, size, entry); -} - -template -bool RangeMap::StoreRangeInternal( - const AddressType &base, const AddressType &delta, - const AddressType &size, const EntryType &entry) { - AddressType high = base + (size - 1); - - // Check for undersize or overflow. - if (size <= 0 || high < base) { - // The processor will hit this case too frequently with common symbol - // files in the size == 0 case, which is more suited to a DEBUG channel. - // Filter those out since there's no DEBUG channel at the moment. - BPLOG_IF(INFO, size != 0) << "StoreRangeInternal failed, " - << HexString(base) << "+" << HexString(size) - << ", " << HexString(high) - << ", delta: " << HexString(delta); - return false; - } - - // Ensure that this range does not overlap with another one already in the - // map. - MapConstIterator iterator_base = map_.lower_bound(base); - MapConstIterator iterator_high = map_.lower_bound(high); - - if (iterator_base != iterator_high) { - // Some other range begins in the space used by this range. It may be - // contained within the space used by this range, or it may extend lower. - // If enable_shrink_down_ is true, shrink the current range down, otherwise - // this is an error. - if (enable_shrink_down_) { - AddressType additional_delta = iterator_base->first - base + 1; - return StoreRangeInternal(base + additional_delta, - delta + additional_delta, - size - additional_delta, entry); - } else { - // The processor hits this case too frequently with common symbol files. - // This is most appropriate for a DEBUG channel, but since none exists - // now simply comment out this logging. - // AddressType other_base = iterator_base->second.base(); - // AddressType other_size = iterator_base->first - other_base + 1; - // BPLOG(INFO) << "StoreRangeInternal failed, an existing range is " - // << "overlapping with the new range: new " - // << HexString(base) << "+" << HexString(size) - // << ", existing " << HexString(other_base) << "+" - // << HexString(other_size); - return false; - } - } - - if (iterator_high != map_.end()) { - if (iterator_high->second.base() <= high) { - // The range above this one overlaps with this one. It may fully - // contain this range, or it may begin within this range and extend - // higher. If enable_shrink_down_ is true, shrink the other range down, - // otherwise this is an error. - if (enable_shrink_down_ && iterator_high->first > high) { - // Shrink the other range down. - AddressType other_high = iterator_high->first; - AddressType additional_delta = - high - iterator_high->second.base() + 1; - EntryType other_entry; - AddressType other_base = AddressType(); - AddressType other_size = AddressType(); - AddressType other_delta = AddressType(); - RetrieveRange(other_high, &other_entry, &other_base, &other_delta, - &other_size); - map_.erase(iterator_high); - map_.insert(MapValue(other_high, - Range(other_base + additional_delta, - other_delta + additional_delta, - other_entry))); - // Retry to store this range. - return StoreRangeInternal(base, delta, size, entry); - } else { - // The processor hits this case too frequently with common symbol files. - // This is most appropriate for a DEBUG channel, but since none exists - // now simply comment out this logging. - // - // AddressType other_base = iterator_high->second.base(); - // AddressType other_size = iterator_high->first - other_base + 1; - // BPLOG(INFO) << "StoreRangeInternal failed, an existing range " - // << "contains or extends higher than the new range: new " - // << HexString(base) << "+" << HexString(size) - // << ", existing " << HexString(other_base) << "+" - // << HexString(other_size); - return false; - } - } - } - - // Store the range in the map by its high address, so that lower_bound can - // be used to quickly locate a range by address. - map_.insert(MapValue(high, Range(base, delta, entry))); - return true; -} - - -template -bool RangeMap::RetrieveRange( - const AddressType &address, EntryType *entry, AddressType *entry_base, - AddressType *entry_delta, AddressType *entry_size) const { - BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRange requires |entry|"; - assert(entry); - - MapConstIterator iterator = map_.lower_bound(address); - if (iterator == map_.end()) - return false; - - // The map is keyed by the high address of each range, so |address| is - // guaranteed to be lower than the range's high address. If |range| is - // not directly preceded by another range, it's possible for address to - // be below the range's low address, though. When that happens, address - // references something not within any range, so return false. - if (address < iterator->second.base()) - return false; - - *entry = iterator->second.entry(); - if (entry_base) - *entry_base = iterator->second.base(); - if (entry_delta) - *entry_delta = iterator->second.delta(); - if (entry_size) - *entry_size = iterator->first - iterator->second.base() + 1; - - return true; -} - - -template -bool RangeMap::RetrieveNearestRange( - const AddressType &address, EntryType *entry, AddressType *entry_base, - AddressType *entry_delta, AddressType *entry_size) const { - BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveNearestRange requires |entry|"; - assert(entry); - - // If address is within a range, RetrieveRange can handle it. - if (RetrieveRange(address, entry, entry_base, entry_delta, entry_size)) - return true; - - // upper_bound gives the first element whose key is greater than address, - // but we want the first element whose key is less than or equal to address. - // Decrement the iterator to get there, but not if the upper_bound already - // points to the beginning of the map - in that case, address is lower than - // the lowest stored key, so return false. - MapConstIterator iterator = map_.upper_bound(address); - if (iterator == map_.begin()) - return false; - --iterator; - - *entry = iterator->second.entry(); - if (entry_base) - *entry_base = iterator->second.base(); - if (entry_delta) - *entry_delta = iterator->second.delta(); - if (entry_size) - *entry_size = iterator->first - iterator->second.base() + 1; - - return true; -} - - -template -bool RangeMap::RetrieveRangeAtIndex( - int index, EntryType *entry, AddressType *entry_base, - AddressType *entry_delta, AddressType *entry_size) const { - BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRangeAtIndex requires |entry|"; - assert(entry); - - if (index >= GetCount()) { - BPLOG(ERROR) << "Index out of range: " << index << "/" << GetCount(); - return false; - } - - // Walk through the map. Although it's ordered, it's not a vector, so it - // can't be addressed directly by index. - MapConstIterator iterator = map_.begin(); - for (int this_index = 0; this_index < index; ++this_index) - ++iterator; - - *entry = iterator->second.entry(); - if (entry_base) - *entry_base = iterator->second.base(); - if (entry_delta) - *entry_delta = iterator->second.delta(); - if (entry_size) - *entry_size = iterator->first - iterator->second.base() + 1; - - return true; -} - - -template -int RangeMap::GetCount() const { - return map_.size(); -} - - -template -void RangeMap::Clear() { - map_.clear(); -} - - -} // namespace google_breakpad - - -#endif // PROCESSOR_RANGE_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/range_map.h b/toolkit/crashreporter/google-breakpad/src/processor/range_map.h deleted file mode 100644 index d90a67327..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/range_map.h +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// range_map.h: Range maps. -// -// A range map associates a range of addresses with a specific object. This -// is useful when certain objects of variable size are located within an -// address space. The range map makes it simple to determine which object is -// associated with a specific address, which may be any address within the -// range associated with an object. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_RANGE_MAP_H__ -#define PROCESSOR_RANGE_MAP_H__ - - -#include - - -namespace google_breakpad { - -// Forward declarations (for later friend declarations of specialized template). -template class RangeMapSerializer; - -template -class RangeMap { - public: - RangeMap() : enable_shrink_down_(false), map_() {} - - // |enable_shrink_down| tells whether overlapping ranges can be shrunk down. - // If true, then adding a new range that overlaps with an existing one can - // be a successful operation. The range which ends at the higher address - // will be shrunk down by moving its start position to a higher address so - // that it does not overlap anymore. - void SetEnableShrinkDown(bool enable_shrink_down); - bool IsShrinkDownEnabled() const; - - // Inserts a range into the map. Returns false for a parameter error, - // or if the location of the range would conflict with a range already - // stored in the map. If enable_shrink_down is true and there is an overlap - // between the current range and some other range (already in the map), - // shrink down the range which ends at a higher address. - bool StoreRange(const AddressType &base, const AddressType &size, - const EntryType &entry); - - // Locates the range encompassing the supplied address. If there is no such - // range, returns false. entry_base, entry_delta, and entry_size, if - // non-NULL, are set to the base, delta, and size of the entry's range. - // A positive entry delta (> 0) indicates that there was an overlap and the - // entry was shrunk down (original start address was increased by delta). - bool RetrieveRange(const AddressType &address, EntryType *entry, - AddressType *entry_base, AddressType *entry_delta, - AddressType *entry_size) const; - - // Locates the range encompassing the supplied address, if one exists. - // If no range encompasses the supplied address, locates the nearest range - // to the supplied address that is lower than the address. Returns false - // if no range meets these criteria. entry_base, entry_delta, and entry_size, - // if non-NULL, are set to the base, delta, and size of the entry's range. - // A positive entry delta (> 0) indicates that there was an overlap and the - // entry was shrunk down (original start address was increased by delta). - bool RetrieveNearestRange(const AddressType &address, EntryType *entry, - AddressType *entry_base, AddressType *entry_delta, - AddressType *entry_size) const; - - // Treating all ranges as a list ordered by the address spaces that they - // occupy, locates the range at the index specified by index. Returns - // false if index is larger than the number of ranges stored. entry_base, - // entry_delta, and entry_size, if non-NULL, are set to the base, delta, and - // size of the entry's range. - // A positive entry delta (> 0) indicates that there was an overlap and the - // entry was shrunk down (original start address was increased by delta). - // - // RetrieveRangeAtIndex is not optimized for speedy operation. - bool RetrieveRangeAtIndex(int index, EntryType *entry, - AddressType *entry_base, AddressType *entry_delta, - AddressType *entry_size) const; - - // Returns the number of ranges stored in the RangeMap. - int GetCount() const; - - // Empties the range map, restoring it to the state it was when it was - // initially created. - void Clear(); - - private: - // Friend declarations. - friend class ModuleComparer; - friend class RangeMapSerializer; - - // Same a StoreRange() with the only exception that the |delta| can be - // passed in. - bool StoreRangeInternal(const AddressType &base, const AddressType &delta, - const AddressType &size, const EntryType &entry); - - class Range { - public: - Range(const AddressType &base, const AddressType &delta, - const EntryType &entry) - : base_(base), delta_(delta), entry_(entry) {} - - AddressType base() const { return base_; } - AddressType delta() const { return delta_; } - EntryType entry() const { return entry_; } - - private: - // The base address of the range. The high address does not need to - // be stored, because RangeMap uses it as the key to the map. - const AddressType base_; - - // The delta when the range is shrunk down. - const AddressType delta_; - - // The entry corresponding to a range. - const EntryType entry_; - }; - - // Convenience types. - typedef std::map AddressToRangeMap; - typedef typename AddressToRangeMap::const_iterator MapConstIterator; - typedef typename AddressToRangeMap::value_type MapValue; - - // Whether overlapping ranges can be shrunk down. - bool enable_shrink_down_; - - // Maps the high address of each range to a EntryType. - AddressToRangeMap map_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_RANGE_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/range_map_shrink_down_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/range_map_shrink_down_unittest.cc deleted file mode 100644 index 8dd0e709b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/range_map_shrink_down_unittest.cc +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (c) 2016, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - -// range_map_shrink_down_unittest.cc: Unit tests for RangeMap that specifically -// test shrink down when ranges overlap. -// -// Author: Ivan Penkov - -#include -#include - -#include "processor/range_map-inl.h" - -#include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" - -namespace { - -using google_breakpad::linked_ptr; -using google_breakpad::scoped_ptr; -using google_breakpad::RangeMap; - -// A CountedObject holds an int. A global (not thread safe!) count of -// allocated CountedObjects is maintained to help test memory management. -class CountedObject { - public: - explicit CountedObject(int id) : id_(id) { ++count_; } - ~CountedObject() { --count_; } - - static int count() { return count_; } - int id() const { return id_; } - - private: - static int count_; - int id_; -}; - -int CountedObject::count_; - -typedef int AddressType; -typedef RangeMap> TestMap; - -// Same range cannot be stored wice. -TEST(RangeMap, TestShinkDown_SameRange) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_1)); - - // Same range cannot be stored wice. - linked_ptr object_2(new CountedObject(2)); - EXPECT_FALSE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_2)); -} - -// If a range is completely contained by another range, then the larger range -// should be shrinked down. -TEST(RangeMap, TestShinkDown_CompletelyContained) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - // Larger range is added first. - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_1)); - // Smaller (contained) range is added second. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */, - object_2)); - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The first range contains the second, so the first range should have been - // shrunk to [90, 99]. Range [0, 9] should be free. - EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(90, retrieved_base); - EXPECT_EQ(90, retrieved_delta); - EXPECT_EQ(10, retrieved_size); - // Validate the properties of the smaller range (should be untouched). - EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(10, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(80, retrieved_size); -} - -// Same as the previous test, however the larger range is added second. -TEST(RangeMap, TestShinkDown_CompletelyContained_LargerAddedSecond) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - // Smaller (contained) range is added first. - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */, - object_1)); - // Larger range is added second. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_2)); - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The second range contains the first, so the second range should have been - // shrunk to [90, 99]. Range [0, 9] should be free. - EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(90, retrieved_base); - EXPECT_EQ(90, retrieved_delta); - EXPECT_EQ(10, retrieved_size); - // Validate the properties of the smaller range (should be untouched). - EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(10, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(80, retrieved_size); -} - -TEST(RangeMap, TestShinkDown_PartialOverlap_AtBeginning) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_1)); - - // Partial overlap at the beginning of the new range. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(90 /* base address */, 110 /* size */, - object_2)); - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The second range is supposed to be shrunk down so the following address - // should resize in the first range. - EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(0, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(100, retrieved_size); - // Validate the properties of the shrunk down range. - EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(100, retrieved_base); - EXPECT_EQ(10, retrieved_delta); - EXPECT_EQ(100, retrieved_size); -} - -TEST(RangeMap, TestShinkDown_PartialOverlap_AtEnd) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 50 /* size */, - object_1)); - - // Partial overlap at the end of the new range. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 70 /* size */, - object_2)); - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The first range is supposed to be shrunk down so the following address - // should resize in the first range. - EXPECT_TRUE(range_map.RetrieveRange(69, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(0, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(70, retrieved_size); - // Validate the properties of the shrunk down range. - EXPECT_TRUE(range_map.RetrieveRange(70, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(70, retrieved_base); - EXPECT_EQ(20, retrieved_delta); - EXPECT_EQ(30, retrieved_size); -} - -// A new range is overlapped at both ends. The new range and the range -// that overlaps at the end should be shrink. The range that overlaps at the -// beginning should be left untouched. -TEST(RangeMap, TestShinkDown_OverlapAtBothEnds) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - // This should overlap object_3 at the beginning. - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */, - object_1)); - - // This should overlap object_3 at the end. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */, - object_2)); - - // This should be overlapped on both ends by object_1 and object_2. - linked_ptr object_3(new CountedObject(3)); - EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 100 /* size */, - object_3)); - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The first range should be intact. - EXPECT_TRUE(range_map.RetrieveRange(0, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(0, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(100, retrieved_size); - // The second range should be shrunk down by 50. - EXPECT_TRUE(range_map.RetrieveRange(150, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(150, retrieved_base); - EXPECT_EQ(50, retrieved_delta); - EXPECT_EQ(50, retrieved_size); - // The third range (in the middle) should be shrunk down by 50. - EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(3, object->id()); - EXPECT_EQ(100, retrieved_base); - EXPECT_EQ(50, retrieved_delta); - EXPECT_EQ(50, retrieved_size); -} - -TEST(RangeMap, TestShinkDown_MultipleConflicts) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - // This should overlap with object_3. - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */, - object_1)); - - // This should also overlap with object_3 but after object_1. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */, - object_2)); - - // This should be overlapped on both object_1 and object_2. Since - // object_3 ends with the higher address it must be shrunk. - linked_ptr object_3(new CountedObject(3)); - EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 300 /* size */, - object_3)); - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The first range should be intact. - EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(10, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(90, retrieved_size); - // The second range should be intact. - EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(100, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(100, retrieved_size); - // The third range should be shrunk down by 200. - EXPECT_TRUE(range_map.RetrieveRange(299, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(3, object->id()); - EXPECT_EQ(200, retrieved_base); - EXPECT_EQ(200, retrieved_delta); - EXPECT_EQ(100, retrieved_size); -} - -// Adding two ranges without overlap should succeed and the ranges should -// be left intact. -TEST(RangeMap, TestShinkDown_NoConflicts) { - TestMap range_map; - range_map.SetEnableShrinkDown(true); - // Adding range 1. - linked_ptr object_1(new CountedObject(1)); - EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */, - object_1)); - - // Adding range 2 - no overlap with range 1. - linked_ptr object_2(new CountedObject(2)); - EXPECT_TRUE(range_map.StoreRange(110 /* base address */, 90 /* size */, - object_2)); - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_delta = AddressType(); - AddressType retrieved_size = AddressType(); - // The first range should be intact. - EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(1, object->id()); - EXPECT_EQ(10, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(90, retrieved_size); - // The second range should be intact. - EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base, - &retrieved_delta, &retrieved_size)); - EXPECT_EQ(2, object->id()); - EXPECT_EQ(110, retrieved_base); - EXPECT_EQ(0, retrieved_delta); - EXPECT_EQ(90, retrieved_size); -} - -} // namespace diff --git a/toolkit/crashreporter/google-breakpad/src/processor/range_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/range_map_unittest.cc deleted file mode 100644 index 31b89e5de..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/range_map_unittest.cc +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// range_map_unittest.cc: Unit tests for RangeMap -// -// Author: Mark Mentovai - - -#include -#include - -#include "processor/range_map-inl.h" - -#include "common/scoped_ptr.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" - -namespace { - - -using google_breakpad::linked_ptr; -using google_breakpad::scoped_ptr; -using google_breakpad::RangeMap; - - -// A CountedObject holds an int. A global (not thread safe!) count of -// allocated CountedObjects is maintained to help test memory management. -class CountedObject { - public: - explicit CountedObject(int id) : id_(id) { ++count_; } - ~CountedObject() { --count_; } - - static int count() { return count_; } - int id() const { return id_; } - - private: - static int count_; - int id_; -}; - -int CountedObject::count_; - - -typedef int AddressType; -typedef RangeMap< AddressType, linked_ptr > TestMap; - - -// RangeTest contains data to use for store and retrieve tests. See -// RunTests for descriptions of the tests. -struct RangeTest { - // Base address to use for test - AddressType address; - - // Size of range to use for test - AddressType size; - - // Unique ID of range - unstorable ranges must have unique IDs too - int id; - - // Whether this range is expected to be stored successfully or not - bool expect_storable; -}; - - -// A RangeTestSet encompasses multiple RangeTests, which are run in -// sequence on the same RangeMap. -struct RangeTestSet { - // An array of RangeTests - const RangeTest *range_tests; - - // The number of tests in the set - unsigned int range_test_count; -}; - - -// StoreTest uses the data in a RangeTest and calls StoreRange on the -// test RangeMap. It returns true if the expected result occurred, and -// false if something else happened. -static bool StoreTest(TestMap *range_map, const RangeTest *range_test) { - linked_ptr object(new CountedObject(range_test->id)); - bool stored = range_map->StoreRange(range_test->address, - range_test->size, - object); - - if (stored != range_test->expect_storable) { - fprintf(stderr, "FAILED: " - "StoreRange id %d, expected %s, observed %s\n", - range_test->id, - range_test->expect_storable ? "storable" : "not storable", - stored ? "stored" : "not stored"); - return false; - } - - return true; -} - - -// RetrieveTest uses the data in RangeTest and calls RetrieveRange on the -// test RangeMap. If it retrieves the expected value (which can be no -// map entry at the specified range,) it returns true, otherwise, it returns -// false. RetrieveTest will check the values around the base address and -// the high address of a range to guard against off-by-one errors. -static bool RetrieveTest(TestMap *range_map, const RangeTest *range_test) { - for (unsigned int side = 0; side <= 1; ++side) { - // When side == 0, check the low side (base address) of each range. - // When side == 1, check the high side (base + size) of each range. - - // Check one-less and one-greater than the target address in addition - // to the target address itself. - - // If the size of the range is only 1, don't check one greater than - // the base or one less than the high - for a successfully stored - // range, these tests would erroneously fail because the range is too - // small. - AddressType low_offset = -1; - AddressType high_offset = 1; - if (range_test->size == 1) { - if (!side) // When checking the low side, - high_offset = 0; // don't check one over the target. - else // When checking the high side, - low_offset = 0; // don't check one under the target. - } - - for (AddressType offset = low_offset; offset <= high_offset; ++offset) { - AddressType address = - offset + - (!side ? range_test->address : - range_test->address + range_test->size - 1); - - bool expected_result = false; // This is correct for tests not stored. - if (range_test->expect_storable) { - if (offset == 0) // When checking the target address, - expected_result = true; // test should always succeed. - else if (offset == -1) // When checking one below the target, - expected_result = side; // should fail low and succeed high. - else // When checking one above the target, - expected_result = !side; // should succeed low and fail high. - } - - linked_ptr object; - AddressType retrieved_base = AddressType(); - AddressType retrieved_size = AddressType(); - AddressType retrieved_delta = AddressType(); - bool retrieved = range_map->RetrieveRange(address, &object, - &retrieved_base, - &retrieved_delta, - &retrieved_size); - - bool observed_result = retrieved && object->id() == range_test->id; - - if (observed_result != expected_result) { - fprintf(stderr, "FAILED: " - "RetrieveRange id %d, side %d, offset %d, " - "expected %s, observed %s\n", - range_test->id, - side, - offset, - expected_result ? "true" : "false", - observed_result ? "true" : "false"); - return false; - } - - // If a range was successfully retrieved, check that the returned - // bounds match the range as stored. - if (observed_result == true && - (retrieved_base != range_test->address || - retrieved_size != range_test->size)) { - fprintf(stderr, "FAILED: " - "RetrieveRange id %d, side %d, offset %d, " - "expected base/size %d/%d, observed %d/%d\n", - range_test->id, - side, - offset, - range_test->address, range_test->size, - retrieved_base, retrieved_size); - return false; - } - - // Now, check RetrieveNearestRange. The nearest range is always - // expected to be different from the test range when checking one - // less than the low side. - bool expected_nearest = range_test->expect_storable; - if (!side && offset < 0) - expected_nearest = false; - - linked_ptr nearest_object; - AddressType nearest_base = AddressType(); - AddressType nearest_delta = AddressType(); - AddressType nearest_size = AddressType(); - bool retrieved_nearest = range_map->RetrieveNearestRange(address, - &nearest_object, - &nearest_base, - &nearest_delta, - &nearest_size); - - // When checking one greater than the high side, RetrieveNearestRange - // should usually return the test range. When a different range begins - // at that address, though, then RetrieveNearestRange should return the - // range at the address instead of the test range. - if (side && offset > 0 && nearest_base == address) { - expected_nearest = false; - } - - bool observed_nearest = retrieved_nearest && - nearest_object->id() == range_test->id; - - if (observed_nearest != expected_nearest) { - fprintf(stderr, "FAILED: " - "RetrieveNearestRange id %d, side %d, offset %d, " - "expected %s, observed %s\n", - range_test->id, - side, - offset, - expected_nearest ? "true" : "false", - observed_nearest ? "true" : "false"); - return false; - } - - // If a range was successfully retrieved, check that the returned - // bounds match the range as stored. - if (expected_nearest && - (nearest_base != range_test->address || - nearest_size != range_test->size)) { - fprintf(stderr, "FAILED: " - "RetrieveNearestRange id %d, side %d, offset %d, " - "expected base/size %d/%d, observed %d/%d\n", - range_test->id, - side, - offset, - range_test->address, range_test->size, - nearest_base, nearest_size); - return false; - } - } - } - - return true; -} - - -// Test RetrieveRangeAtIndex, which is supposed to return objects in order -// according to their addresses. This test is performed by looping through -// the map, calling RetrieveRangeAtIndex for all possible indices in sequence, -// and verifying that each call returns a different object than the previous -// call, and that ranges are returned with increasing base addresses. Returns -// false if the test fails. -static bool RetrieveIndexTest(TestMap *range_map, int set) { - linked_ptr object; - CountedObject *last_object = NULL; - AddressType last_base = 0; - - int object_count = range_map->GetCount(); - for (int object_index = 0; object_index < object_count; ++object_index) { - AddressType base; - if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, - NULL /* delta */, NULL /* size */)) { - fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " - "expected success, observed failure\n", - set, object_index); - return false; - } - - if (!object.get()) { - fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " - "expected object, observed NULL\n", - set, object_index); - return false; - } - - // It's impossible to do these comparisons unless there's a previous - // object to compare against. - if (last_object) { - // The object must be different from the last one. - if (object->id() == last_object->id()) { - fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " - "expected different objects, observed same objects (%d)\n", - set, object_index, object->id()); - return false; - } - - // Each object must have a base greater than the previous object's base. - if (base <= last_base) { - fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " - "expected different bases, observed same bases (%d)\n", - set, object_index, base); - return false; - } - } - - last_object = object.get(); - last_base = base; - } - - // Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that - // are too high. - if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL /* base */, - NULL /* delta */, NULL /* size */)) { - fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d (too large), " - "expected failure, observed success\n", - set, object_count); - return false; - } - - return true; -} - -// Additional RetriveAtIndex test to expose the bug in RetrieveRangeAtIndex(). -// Bug info: RetrieveRangeAtIndex() previously retrieves the high address of -// entry, however, it is supposed to retrieve the base address of entry as -// stated in the comment in range_map.h. -static bool RetriveAtIndexTest2() { - scoped_ptr range_map(new TestMap()); - - // Store ranges with base address = 2 * object_id: - const int range_size = 2; - for (int object_id = 0; object_id < 100; ++object_id) { - linked_ptr object(new CountedObject(object_id)); - int base_address = 2 * object_id; - range_map->StoreRange(base_address, range_size, object); - } - - linked_ptr object; - int object_count = range_map->GetCount(); - for (int object_index = 0; object_index < object_count; ++object_index) { - AddressType base; - if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, - NULL /* delta */, NULL /* size */)) { - fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, " - "expected success, observed failure\n", object_index); - return false; - } - - int expected_base = 2 * object->id(); - if (base != expected_base) { - fprintf(stderr, "FAILED: RetriveAtIndexTest2 index %d, " - "expected base %d, observed base %d", - object_index, expected_base, base); - return false; - } - } - - return true; -} - - -// RunTests runs a series of test sets. -static bool RunTests() { - // These tests will be run sequentially. The first set of tests exercises - // most functions of RangeTest, and verifies all of the bounds-checking. - const RangeTest range_tests_0[] = { - { INT_MIN, 16, 1, true }, // lowest possible range - { -2, 5, 2, true }, // a range through zero - { INT_MAX - 9, 11, 3, false }, // tests anti-overflow - { INT_MAX - 9, 10, 4, true }, // highest possible range - { 5, 0, 5, false }, // tests anti-zero-size - { 5, 1, 6, true }, // smallest possible range - { -20, 15, 7, true }, // entirely negative - - { 10, 10, 10, true }, // causes the following tests to fail - { 9, 10, 11, false }, // one-less base, one-less high - { 9, 11, 12, false }, // one-less base, identical high - { 9, 12, 13, false }, // completely contains existing - { 10, 9, 14, false }, // identical base, one-less high - { 10, 10, 15, false }, // exactly identical to existing range - { 10, 11, 16, false }, // identical base, one-greater high - { 11, 8, 17, false }, // contained completely within - { 11, 9, 18, false }, // one-greater base, identical high - { 11, 10, 19, false }, // one-greater base, one-greater high - { 9, 2, 20, false }, // overlaps bottom by one - { 10, 1, 21, false }, // overlaps bottom by one, contained - { 19, 1, 22, false }, // overlaps top by one, contained - { 19, 2, 23, false }, // overlaps top by one - - { 9, 1, 24, true }, // directly below without overlap - { 20, 1, 25, true }, // directly above without overlap - - { 6, 3, 26, true }, // exactly between two ranges, gapless - { 7, 3, 27, false }, // tries to span two ranges - { 7, 5, 28, false }, // tries to span three ranges - { 4, 20, 29, false }, // tries to contain several ranges - - { 30, 50, 30, true }, - { 90, 25, 31, true }, - { 35, 65, 32, false }, // tries to span two noncontiguous - { 120, 10000, 33, true }, // > 8-bit - { 20000, 20000, 34, true }, // > 8-bit - { 0x10001, 0x10001, 35, true }, // > 16-bit - - { 27, -1, 36, false } // tests high < base - }; - - // Attempt to fill the entire space. The entire space must be filled with - // three stores because AddressType is signed for these tests, so RangeMap - // treats the size as signed and rejects sizes that appear to be negative. - // Even if these tests were run as unsigned, two stores would be needed - // to fill the space because the entire size of the space could only be - // described by using one more bit than would be present in AddressType. - const RangeTest range_tests_1[] = { - { INT_MIN, INT_MAX, 50, true }, // From INT_MIN to -2, inclusive - { -1, 2, 51, true }, // From -1 to 0, inclusive - { 1, INT_MAX, 52, true }, // From 1 to INT_MAX, inclusive - { INT_MIN, INT_MAX, 53, false }, // Can't fill the space twice - { -1, 2, 54, false }, - { 1, INT_MAX, 55, false }, - { -3, 6, 56, false }, // -3 to 2, inclusive - spans 3 ranges - }; - - // A light round of testing to verify that RetrieveRange does the right - // the right thing at the extremities of the range when nothing is stored - // there. Checks are forced without storing anything at the extremities - // by setting size = 0. - const RangeTest range_tests_2[] = { - { INT_MIN, 0, 100, false }, // makes RetrieveRange check low end - { -1, 3, 101, true }, - { INT_MAX, 0, 102, false }, // makes RetrieveRange check high end - }; - - // Similar to the previous test set, but with a couple of ranges closer - // to the extremities. - const RangeTest range_tests_3[] = { - { INT_MIN + 1, 1, 110, true }, - { INT_MAX - 1, 1, 111, true }, - { INT_MIN, 0, 112, false }, // makes RetrieveRange check low end - { INT_MAX, 0, 113, false } // makes RetrieveRange check high end - }; - - // The range map is cleared between sets of tests listed here. - const RangeTestSet range_test_sets[] = { - { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) }, - { range_tests_1, sizeof(range_tests_1) / sizeof(RangeTest) }, - { range_tests_2, sizeof(range_tests_2) / sizeof(RangeTest) }, - { range_tests_3, sizeof(range_tests_3) / sizeof(RangeTest) }, - { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) } // Run again - }; - - // Maintain the range map in a pointer so that deletion can be meaningfully - // tested. - scoped_ptr range_map(new TestMap()); - - // Run all of the test sets in sequence. - unsigned int range_test_set_count = sizeof(range_test_sets) / - sizeof(RangeTestSet); - for (unsigned int range_test_set_index = 0; - range_test_set_index < range_test_set_count; - ++range_test_set_index) { - const RangeTest *range_tests = - range_test_sets[range_test_set_index].range_tests; - unsigned int range_test_count = - range_test_sets[range_test_set_index].range_test_count; - - // Run the StoreRange test, which validates StoreRange and initializes - // the RangeMap with data for the RetrieveRange test. - int stored_count = 0; // The number of ranges successfully stored - for (unsigned int range_test_index = 0; - range_test_index < range_test_count; - ++range_test_index) { - const RangeTest *range_test = &range_tests[range_test_index]; - if (!StoreTest(range_map.get(), range_test)) - return false; - - if (range_test->expect_storable) - ++stored_count; - } - - // There should be exactly one CountedObject for everything successfully - // stored in the RangeMap. - if (CountedObject::count() != stored_count) { - fprintf(stderr, "FAILED: " - "stored object counts don't match, expected %d, observed %d\n", - stored_count, - CountedObject::count()); - - return false; - } - - // The RangeMap's own count of objects should also match. - if (range_map->GetCount() != stored_count) { - fprintf(stderr, "FAILED: stored object count doesn't match GetCount, " - "expected %d, observed %d\n", - stored_count, range_map->GetCount()); - - return false; - } - - // Run the RetrieveRange test - for (unsigned int range_test_index = 0; - range_test_index < range_test_count; - ++range_test_index) { - const RangeTest *range_test = &range_tests[range_test_index]; - if (!RetrieveTest(range_map.get(), range_test)) - return false; - } - - if (!RetrieveIndexTest(range_map.get(), range_test_set_index)) - return false; - - // Clear the map between test sets. If this is the final test set, - // delete the map instead to test destruction. - if (range_test_set_index < range_test_set_count - 1) - range_map->Clear(); - else - range_map.reset(); - - // Test that all stored objects are freed when the RangeMap is cleared - // or deleted. - if (CountedObject::count() != 0) { - fprintf(stderr, "FAILED: " - "did not free all objects after %s, %d still allocated\n", - range_test_set_index < range_test_set_count - 1 ? "clear" - : "delete", - CountedObject::count()); - - return false; - } - } - - if (!RetriveAtIndexTest2()) { - fprintf(stderr, "FAILED: did not pass RetrieveAtIndexTest2()\n"); - return false; - } - - return true; -} - - -} // namespace - - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - return RunTests() ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer-inl.h deleted file mode 100644 index 606bb3cea..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer-inl.h +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// simple_serializer-inl.h: template specializations for following types: -// bool, const char *(C-string), string, -// Line, Function, PublicSymbol, WindowsFrameInfo and their linked pointers. -// -// See simple_serializer.h for moredocumentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_SIMPLE_SERIALIZER_INL_H__ -#define PROCESSOR_SIMPLE_SERIALIZER_INL_H__ - -#include - -#include "processor/simple_serializer.h" -#include "map_serializers-inl.h" - -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "processor/basic_source_line_resolver_types.h" -#include "processor/linked_ptr.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -// Specializations of SimpleSerializer: bool -template<> -class SimpleSerializer { - public: - static size_t SizeOf(bool boolean) { return 1; } - - static char *Write(bool boolean, char *dest) { - *dest = static_cast(boolean? 255 : 0); - return ++dest; - } - - static const char *Read(const char *source, bool *value) { - *value = ((*source) == 0 ? false : true); - return ++source; - } -}; - -// Specializations of SimpleSerializer: string -template<> -class SimpleSerializer { - public: - static size_t SizeOf(const string &str) { return str.size() + 1; } - - static char *Write(const string &str, char *dest) { - strcpy(dest, str.c_str()); - return dest + SizeOf(str); - } -}; - -// Specializations of SimpleSerializer: C-string -template<> -class SimpleSerializer { - public: - static size_t SizeOf(const char *cstring) { - return strlen(cstring) + 1; - } - - static char *Write(const char *cstring, char *dest) { - strcpy(dest, cstring); - return dest + SizeOf(cstring); - } -}; - -// Specializations of SimpleSerializer: Line -template<> -class SimpleSerializer { - typedef BasicSourceLineResolver::Line Line; - public: - static size_t SizeOf(const Line &line) { - return SimpleSerializer::SizeOf(line.address) - + SimpleSerializer::SizeOf(line.size) - + SimpleSerializer::SizeOf(line.source_file_id) - + SimpleSerializer::SizeOf(line.line); - } - static char *Write(const Line &line, char *dest) { - dest = SimpleSerializer::Write(line.address, dest); - dest = SimpleSerializer::Write(line.size, dest); - dest = SimpleSerializer::Write(line.source_file_id, dest); - dest = SimpleSerializer::Write(line.line, dest); - return dest; - } -}; - -// Specializations of SimpleSerializer: PublicSymbol -template<> -class SimpleSerializer { - typedef BasicSourceLineResolver::PublicSymbol PublicSymbol; - public: - static size_t SizeOf(const PublicSymbol &pubsymbol) { - return SimpleSerializer::SizeOf(pubsymbol.name) - + SimpleSerializer::SizeOf(pubsymbol.address) - + SimpleSerializer::SizeOf(pubsymbol.parameter_size); - } - static char *Write(const PublicSymbol &pubsymbol, char *dest) { - dest = SimpleSerializer::Write(pubsymbol.name, dest); - dest = SimpleSerializer::Write(pubsymbol.address, dest); - dest = SimpleSerializer::Write(pubsymbol.parameter_size, dest); - return dest; - } -}; - -// Specializations of SimpleSerializer: WindowsFrameInfo -template<> -class SimpleSerializer { - public: - static size_t SizeOf(const WindowsFrameInfo &wfi) { - unsigned int size = 0; - size += sizeof(int32_t); // wfi.type_ - size += SimpleSerializer::SizeOf(wfi.valid); - size += SimpleSerializer::SizeOf(wfi.prolog_size); - size += SimpleSerializer::SizeOf(wfi.epilog_size); - size += SimpleSerializer::SizeOf(wfi.parameter_size); - size += SimpleSerializer::SizeOf(wfi.saved_register_size); - size += SimpleSerializer::SizeOf(wfi.local_size); - size += SimpleSerializer::SizeOf(wfi.max_stack_size); - size += SimpleSerializer::SizeOf(wfi.allocates_base_pointer); - size += SimpleSerializer::SizeOf(wfi.program_string); - return size; - } - static char *Write(const WindowsFrameInfo &wfi, char *dest) { - dest = SimpleSerializer::Write( - static_cast(wfi.type_), dest); - dest = SimpleSerializer::Write(wfi.valid, dest); - dest = SimpleSerializer::Write(wfi.prolog_size, dest); - dest = SimpleSerializer::Write(wfi.epilog_size, dest); - dest = SimpleSerializer::Write(wfi.parameter_size, dest); - dest = SimpleSerializer::Write(wfi.saved_register_size, dest); - dest = SimpleSerializer::Write(wfi.local_size, dest); - dest = SimpleSerializer::Write(wfi.max_stack_size, dest); - dest = SimpleSerializer::Write(wfi.allocates_base_pointer, dest); - return SimpleSerializer::Write(wfi.program_string, dest); - } -}; - -// Specializations of SimpleSerializer: Linked_ptr version of -// Line, Function, PublicSymbol, WindowsFrameInfo. -template<> -class SimpleSerializer< linked_ptr > { - typedef BasicSourceLineResolver::Line Line; - public: - static size_t SizeOf(const linked_ptr &lineptr) { - if (lineptr.get() == NULL) return 0; - return SimpleSerializer::SizeOf(*(lineptr.get())); - } - static char *Write(const linked_ptr &lineptr, char *dest) { - if (lineptr.get()) - dest = SimpleSerializer::Write(*(lineptr.get()), dest); - return dest; - } -}; - -template<> -class SimpleSerializer { - // Convenient type names. - typedef BasicSourceLineResolver::Function Function; - typedef BasicSourceLineResolver::Line Line; - public: - static size_t SizeOf(const Function &func) { - unsigned int size = 0; - size += SimpleSerializer::SizeOf(func.name); - size += SimpleSerializer::SizeOf(func.address); - size += SimpleSerializer::SizeOf(func.size); - size += SimpleSerializer::SizeOf(func.parameter_size); - size += range_map_serializer_.SizeOf(func.lines); - return size; - } - - static char *Write(const Function &func, char *dest) { - dest = SimpleSerializer::Write(func.name, dest); - dest = SimpleSerializer::Write(func.address, dest); - dest = SimpleSerializer::Write(func.size, dest); - dest = SimpleSerializer::Write(func.parameter_size, dest); - dest = range_map_serializer_.Write(func.lines, dest); - return dest; - } - private: - // This static member is defined in module_serializer.cc. - static RangeMapSerializer< MemAddr, linked_ptr > range_map_serializer_; -}; - -template<> -class SimpleSerializer< linked_ptr > { - typedef BasicSourceLineResolver::Function Function; - public: - static size_t SizeOf(const linked_ptr &func) { - if (!func.get()) return 0; - return SimpleSerializer::SizeOf(*(func.get())); - } - - static char *Write(const linked_ptr &func, char *dest) { - if (func.get()) - dest = SimpleSerializer::Write(*(func.get()), dest); - return dest; - } -}; - -template<> -class SimpleSerializer< linked_ptr > { - typedef BasicSourceLineResolver::PublicSymbol PublicSymbol; - public: - static size_t SizeOf(const linked_ptr &pubsymbol) { - if (pubsymbol.get() == NULL) return 0; - return SimpleSerializer::SizeOf(*(pubsymbol.get())); - } - static char *Write(const linked_ptr &pubsymbol, char *dest) { - if (pubsymbol.get()) - dest = SimpleSerializer::Write(*(pubsymbol.get()), dest); - return dest; - } -}; - -template<> -class SimpleSerializer< linked_ptr > { - public: - static size_t SizeOf(const linked_ptr &wfi) { - if (wfi.get() == NULL) return 0; - return SimpleSerializer::SizeOf(*(wfi.get())); - } - static char *Write(const linked_ptr &wfi, char *dest) { - if (wfi.get()) - dest = SimpleSerializer::Write(*(wfi.get()), dest); - return dest; - } -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_SIMPLE_SERIALIZER_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer.h b/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer.h deleted file mode 100644 index 275f51ce3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/simple_serializer.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// simple_serializer.h: SimpleSerializer is a template for calculating size and -// writing to specific memory location for objects of primitive types, C-style -// string, string, breakpad types/structs etc. -// All specializations of SimpleSerializer template are defined in the -// "simple_serializer-inl.h" file. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_SIMPLE_SERIALIZER_H__ -#define PROCESSOR_SIMPLE_SERIALIZER_H__ - -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -typedef uint64_t MemAddr; - -// Default implementation of SimpleSerializer template. -// Specializations are defined in "simple_serializer-inl.h". -template class SimpleSerializer { - public: - // Calculate and return the size of the 'item'. - static size_t SizeOf(const Type &item) { return sizeof(item); } - // Write 'item' to memory location 'dest', and return to the "end" address of - // data written, i.e., the address after the final byte written. - static char *Write(const Type &item, char *dest) { - new (dest) Type(item); - return dest + SizeOf(item); - } -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_SIMPLE_SERIALIZER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.cc b/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.cc deleted file mode 100644 index bc5ebb687..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// simple_symbol_supplier.cc: A simple SymbolSupplier implementation -// -// See simple_symbol_supplier.h for documentation. -// -// Author: Mark Mentovai - -#include "processor/simple_symbol_supplier.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/logging.h" -#include "processor/pathname_stripper.h" - -namespace google_breakpad { - -static bool file_exists(const string &file_name) { - struct stat sb; - return stat(file_name.c_str(), &sb) == 0; -} - -SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetSymbolFile( - const CodeModule *module, const SystemInfo *system_info, - string *symbol_file) { - BPLOG_IF(ERROR, !symbol_file) << "SimpleSymbolSupplier::GetSymbolFile " - "requires |symbol_file|"; - assert(symbol_file); - symbol_file->clear(); - - for (unsigned int path_index = 0; path_index < paths_.size(); ++path_index) { - SymbolResult result; - if ((result = GetSymbolFileAtPathFromRoot(module, system_info, - paths_[path_index], - symbol_file)) != NOT_FOUND) { - return result; - } - } - return NOT_FOUND; -} - -SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetSymbolFile( - const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data) { - assert(symbol_data); - symbol_data->clear(); - - SymbolSupplier::SymbolResult s = GetSymbolFile(module, system_info, - symbol_file); - if (s == FOUND) { - std::ifstream in(symbol_file->c_str()); - std::getline(in, *symbol_data, string::traits_type::to_char_type( - string::traits_type::eof())); - in.close(); - } - return s; -} - -SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetCStringSymbolData( - const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size) { - assert(symbol_data); - assert(symbol_data_size); - - string symbol_data_string; - SymbolSupplier::SymbolResult s = - GetSymbolFile(module, system_info, symbol_file, &symbol_data_string); - - if (s == FOUND) { - *symbol_data_size = symbol_data_string.size() + 1; - *symbol_data = new char[*symbol_data_size]; - if (*symbol_data == NULL) { - BPLOG(ERROR) << "Memory allocation for size " << *symbol_data_size - << " failed"; - return INTERRUPT; - } - memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size()); - (*symbol_data)[symbol_data_string.size()] = '\0'; - memory_buffers_.insert(make_pair(module->code_file(), *symbol_data)); - } - return s; -} - -void SimpleSymbolSupplier::FreeSymbolData(const CodeModule *module) { - if (!module) { - BPLOG(INFO) << "Cannot free symbol data buffer for NULL module"; - return; - } - - map::iterator it = memory_buffers_.find(module->code_file()); - if (it == memory_buffers_.end()) { - BPLOG(INFO) << "Cannot find symbol data buffer for module " - << module->code_file(); - return; - } - delete [] it->second; - memory_buffers_.erase(it); -} - -SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetSymbolFileAtPathFromRoot( - const CodeModule *module, const SystemInfo *system_info, - const string &root_path, string *symbol_file) { - BPLOG_IF(ERROR, !symbol_file) << "SimpleSymbolSupplier::GetSymbolFileAtPath " - "requires |symbol_file|"; - assert(symbol_file); - symbol_file->clear(); - - if (!module) - return NOT_FOUND; - - // Start with the base path. - string path = root_path; - - // Append the debug (pdb) file name as a directory name. - path.append("/"); - string debug_file_name = PathnameStripper::File(module->debug_file()); - if (debug_file_name.empty()) { - BPLOG(ERROR) << "Can't construct symbol file path without debug_file " - "(code_file = " << - PathnameStripper::File(module->code_file()) << ")"; - return NOT_FOUND; - } - path.append(debug_file_name); - - // Append the identifier as a directory name. - path.append("/"); - string identifier = module->debug_identifier(); - if (identifier.empty()) { - BPLOG(ERROR) << "Can't construct symbol file path without debug_identifier " - "(code_file = " << - PathnameStripper::File(module->code_file()) << - ", debug_file = " << debug_file_name << ")"; - return NOT_FOUND; - } - path.append(identifier); - - // Transform the debug file name into one ending in .sym. If the existing - // name ends in .pdb, strip the .pdb. Otherwise, add .sym to the non-.pdb - // name. - path.append("/"); - string debug_file_extension; - if (debug_file_name.size() > 4) - debug_file_extension = debug_file_name.substr(debug_file_name.size() - 4); - std::transform(debug_file_extension.begin(), debug_file_extension.end(), - debug_file_extension.begin(), tolower); - if (debug_file_extension == ".pdb") { - path.append(debug_file_name.substr(0, debug_file_name.size() - 4)); - } else { - path.append(debug_file_name); - } - path.append(".sym"); - - if (!file_exists(path)) { - BPLOG(INFO) << "No symbol file at " << path; - return NOT_FOUND; - } - - *symbol_file = path; - return FOUND; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h b/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h deleted file mode 100644 index 0cde85cdc..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// simple_symbol_supplier.h: A simple SymbolSupplier implementation -// -// SimpleSymbolSupplier is a straightforward implementation of SymbolSupplier -// that stores symbol files in a filesystem tree. A SimpleSymbolSupplier is -// created with one or more base directories, which are the root paths for all -// symbol files. Each symbol file contained therein has a directory entry in -// the base directory with a name identical to the corresponding debugging -// file (pdb). Within each of these directories, there are subdirectories -// named for the debugging file's identifier. For recent pdb files, this is -// a concatenation of the pdb's uuid and age, presented in hexadecimal form, -// without any dashes or separators. The uuid is in uppercase hexadecimal -// and the age is in lowercase hexadecimal. Within that subdirectory, -// SimpleSymbolSupplier expects to find the symbol file, which is named -// identically to the debug file, but with a .sym extension. If the original -// debug file had a name ending in .pdb, the .pdb extension will be replaced -// with .sym. This sample hierarchy is rooted at the "symbols" base -// directory: -// -// symbols -// symbols/test_app.pdb -// symbols/test_app.pdb/63FE4780728D49379B9D7BB6460CB42A1 -// symbols/test_app.pdb/63FE4780728D49379B9D7BB6460CB42A1/test_app.sym -// symbols/kernel32.pdb -// symbols/kernel32.pdb/BCE8785C57B44245A669896B6A19B9542 -// symbols/kernel32.pdb/BCE8785C57B44245A669896B6A19B9542/kernel32.sym -// -// In this case, the uuid of test_app.pdb is -// 63fe4780-728d-4937-9b9d-7bb6460cb42a and its age is 1. -// -// This scheme was chosen to be roughly analogous to the way that -// symbol files may be accessed from Microsoft Symbol Server. A hierarchy -// used for Microsoft Symbol Server storage is usable as a hierarchy for -// SimpleSymbolServer, provided that the pdb files are transformed to dumped -// format using a tool such as dump_syms, and given a .sym extension. -// -// SimpleSymbolSupplier will iterate over all root paths searching for -// a symbol file existing in that path. -// -// SimpleSymbolSupplier supports any debugging file which can be identified -// by a CodeModule object's debug_file and debug_identifier accessors. The -// expected ultimate source of these CodeModule objects are MinidumpModule -// objects; it is this class that is responsible for assigning appropriate -// values for debug_file and debug_identifier. -// -// Author: Mark Mentovai - -#ifndef PROCESSOR_SIMPLE_SYMBOL_SUPPLIER_H__ -#define PROCESSOR_SIMPLE_SYMBOL_SUPPLIER_H__ - -#include -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/processor/symbol_supplier.h" - -namespace google_breakpad { - -using std::map; -using std::vector; - -class CodeModule; - -class SimpleSymbolSupplier : public SymbolSupplier { - public: - // Creates a new SimpleSymbolSupplier, using path as the root path where - // symbols are stored. - explicit SimpleSymbolSupplier(const string &path) : paths_(1, path) {} - - // Creates a new SimpleSymbolSupplier, using paths as a list of root - // paths where symbols may be stored. - explicit SimpleSymbolSupplier(const vector &paths) : paths_(paths) {} - - virtual ~SimpleSymbolSupplier() {} - - // Returns the path to the symbol file for the given module. See the - // description above. - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file); - - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data); - - // Allocates data buffer on heap and writes symbol data into buffer. - // Symbol supplier ALWAYS takes ownership of the data buffer. - virtual SymbolResult GetCStringSymbolData(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size); - - // Free the data buffer allocated in the above GetCStringSymbolData(); - virtual void FreeSymbolData(const CodeModule *module); - - protected: - SymbolResult GetSymbolFileAtPathFromRoot(const CodeModule *module, - const SystemInfo *system_info, - const string &root_path, - string *symbol_file); - - private: - map memory_buffers_; - vector paths_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_SIMPLE_SYMBOL_SUPPLIER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc b/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc deleted file mode 100644 index 6eff1f991..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// source_line_resolver_base.cc: Implementation of SourceLineResolverBase. -// -// See source_line_resolver_base.h and source_line_resolver_base_types.h for -// more documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include -#include -#include - -#include -#include - -#include "google_breakpad/processor/source_line_resolver_base.h" -#include "processor/source_line_resolver_base_types.h" -#include "processor/module_factory.h" - -using std::map; -using std::make_pair; - -namespace google_breakpad { - -SourceLineResolverBase::SourceLineResolverBase( - ModuleFactory *module_factory) - : modules_(new ModuleMap), - corrupt_modules_(new ModuleSet), - memory_buffers_(new MemoryMap), - module_factory_(module_factory) { -} - -SourceLineResolverBase::~SourceLineResolverBase() { - ModuleMap::iterator it; - // Iterate through ModuleMap and delete all loaded modules. - for (it = modules_->begin(); it != modules_->end(); ++it) { - // Delete individual module. - delete it->second; - } - // Delete the map of modules. - delete modules_; - modules_ = NULL; - - // Delete the set of corrupt modules. - delete corrupt_modules_; - corrupt_modules_ = NULL; - - MemoryMap::iterator iter = memory_buffers_->begin(); - for (; iter != memory_buffers_->end(); ++iter) { - delete [] iter->second; - } - // Delete the map of memory buffers. - delete memory_buffers_; - memory_buffers_ = NULL; - - delete module_factory_; - module_factory_ = NULL; -} - -bool SourceLineResolverBase::ReadSymbolFile(const string &map_file, - char **symbol_data, - size_t *symbol_data_size) { - if (symbol_data == NULL || symbol_data_size == NULL) { - BPLOG(ERROR) << "Could not Read file into Null memory pointer"; - return false; - } - - struct stat buf; - int error_code = stat(map_file.c_str(), &buf); - if (error_code == -1) { - string error_string; - error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "Could not open " << map_file << - ", error " << error_code << ": " << error_string; - return false; - } - - off_t file_size = buf.st_size; - - // Allocate memory for file contents, plus a null terminator - // since we may use strtok() on the contents. - *symbol_data_size = file_size + 1; - *symbol_data = new char[file_size + 1]; - - if (*symbol_data == NULL) { - BPLOG(ERROR) << "Could not allocate memory for " << map_file; - return false; - } - - BPLOG(INFO) << "Opening " << map_file; - - FILE *f = fopen(map_file.c_str(), "rt"); - if (!f) { - string error_string; - error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "Could not open " << map_file << - ", error " << error_code << ": " << error_string; - delete [] (*symbol_data); - *symbol_data = NULL; - return false; - } - - AutoFileCloser closer(f); - - int items_read = 0; - - items_read = fread(*symbol_data, 1, file_size, f); - - if (items_read != file_size) { - string error_string; - error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "Could not slurp " << map_file << - ", error " << error_code << ": " << error_string; - delete [] (*symbol_data); - *symbol_data = NULL; - return false; - } - - (*symbol_data)[file_size] = '\0'; - return true; -} - -bool SourceLineResolverBase::LoadModule(const CodeModule *module, - const string &map_file) { - if (module == NULL) - return false; - - // Make sure we don't already have a module with the given name. - if (modules_->find(module->code_file()) != modules_->end()) { - BPLOG(INFO) << "Symbols for module " << module->code_file() - << " already loaded"; - return false; - } - - BPLOG(INFO) << "Loading symbols for module " << module->code_file() - << " from " << map_file; - - char *memory_buffer; - size_t memory_buffer_size; - if (!ReadSymbolFile(map_file, &memory_buffer, &memory_buffer_size)) - return false; - - BPLOG(INFO) << "Read symbol file " << map_file << " succeeded"; - - bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, - memory_buffer_size); - - if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { - // memory_buffer has to stay alive as long as the module. - memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); - } else { - delete [] memory_buffer; - } - - return load_result; -} - -bool SourceLineResolverBase::LoadModuleUsingMapBuffer( - const CodeModule *module, const string &map_buffer) { - if (module == NULL) - return false; - - // Make sure we don't already have a module with the given name. - if (modules_->find(module->code_file()) != modules_->end()) { - BPLOG(INFO) << "Symbols for module " << module->code_file() - << " already loaded"; - return false; - } - - size_t memory_buffer_size = map_buffer.size() + 1; - char *memory_buffer = new char[memory_buffer_size]; - if (memory_buffer == NULL) { - BPLOG(ERROR) << "Could not allocate memory for " << module->code_file(); - return false; - } - - // Can't use strcpy, as the data may contain '\0's before the end. - memcpy(memory_buffer, map_buffer.c_str(), map_buffer.size()); - memory_buffer[map_buffer.size()] = '\0'; - - bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, - memory_buffer_size); - - if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { - // memory_buffer has to stay alive as long as the module. - memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); - } else { - delete [] memory_buffer; - } - - return load_result; -} - -bool SourceLineResolverBase::LoadModuleUsingMemoryBuffer( - const CodeModule *module, - char *memory_buffer, - size_t memory_buffer_size) { - if (!module) - return false; - - // Make sure we don't already have a module with the given name. - if (modules_->find(module->code_file()) != modules_->end()) { - BPLOG(INFO) << "Symbols for module " << module->code_file() - << " already loaded"; - return false; - } - - BPLOG(INFO) << "Loading symbols for module " << module->code_file() - << " from memory buffer"; - - Module *basic_module = module_factory_->CreateModule(module->code_file()); - - // Ownership of memory is NOT transfered to Module::LoadMapFromMemory(). - if (!basic_module->LoadMapFromMemory(memory_buffer, memory_buffer_size)) { - BPLOG(ERROR) << "Too many error while parsing symbol data for module " - << module->code_file(); - // Returning false from here would be an indication that the symbols for - // this module are missing which would be wrong. Intentionally fall through - // and add the module to both the modules_ and the corrupt_modules_ lists. - assert(basic_module->IsCorrupt()); - } - - modules_->insert(make_pair(module->code_file(), basic_module)); - if (basic_module->IsCorrupt()) { - corrupt_modules_->insert(module->code_file()); - } - return true; -} - -bool SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule() { - return true; -} - -void SourceLineResolverBase::UnloadModule(const CodeModule *code_module) { - if (!code_module) - return; - - ModuleMap::iterator mod_iter = modules_->find(code_module->code_file()); - if (mod_iter != modules_->end()) { - Module *symbol_module = mod_iter->second; - delete symbol_module; - corrupt_modules_->erase(mod_iter->first); - modules_->erase(mod_iter); - } - - if (ShouldDeleteMemoryBufferAfterLoadModule()) { - // No-op. Because we never store any memory buffers. - } else { - // There may be a buffer stored locally, we need to find and delete it. - MemoryMap::iterator iter = memory_buffers_->find(code_module->code_file()); - if (iter != memory_buffers_->end()) { - delete [] iter->second; - memory_buffers_->erase(iter); - } - } -} - -bool SourceLineResolverBase::HasModule(const CodeModule *module) { - if (!module) - return false; - return modules_->find(module->code_file()) != modules_->end(); -} - -bool SourceLineResolverBase::IsModuleCorrupt(const CodeModule *module) { - if (!module) - return false; - return corrupt_modules_->find(module->code_file()) != corrupt_modules_->end(); -} - -void SourceLineResolverBase::FillSourceLineInfo(StackFrame *frame) { - if (frame->module) { - ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); - if (it != modules_->end()) { - it->second->LookupAddress(frame); - } - } -} - -WindowsFrameInfo *SourceLineResolverBase::FindWindowsFrameInfo( - const StackFrame *frame) { - if (frame->module) { - ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); - if (it != modules_->end()) { - return it->second->FindWindowsFrameInfo(frame); - } - } - return NULL; -} - -CFIFrameInfo *SourceLineResolverBase::FindCFIFrameInfo( - const StackFrame *frame) { - if (frame->module) { - ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); - if (it != modules_->end()) { - return it->second->FindCFIFrameInfo(frame); - } - } - return NULL; -} - -bool SourceLineResolverBase::CompareString::operator()( - const string &s1, const string &s2) const { - return strcmp(s1.c_str(), s2.c_str()) < 0; -} - -bool SourceLineResolverBase::Module::ParseCFIRuleSet( - const string &rule_set, CFIFrameInfo *frame_info) const { - CFIFrameInfoParseHandler handler(frame_info); - CFIRuleParser parser(&handler); - return parser.Parse(rule_set); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base_types.h b/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base_types.h deleted file mode 100644 index 4a9dfb3ce..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base_types.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// source_line_resolver_base_types.h: definition of nested classes/structs in -// SourceLineResolverBase. It moves the definitions out of -// source_line_resolver_base.cc, so that other classes may have access -// to these private nested types without including source_line_resolver_base.cc -// In addition, Module is defined as a pure abstract class to be implemented by -// each concrete source line resolver class. -// -// See source_line_resolver_base.h for more documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include - -#include -#include - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/source_line_resolver_base.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/cfi_frame_info.h" -#include "processor/windows_frame_info.h" - -#ifndef PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ -#define PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ - -namespace google_breakpad { - -class SourceLineResolverBase::AutoFileCloser { - public: - explicit AutoFileCloser(FILE *file) : file_(file) {} - ~AutoFileCloser() { - if (file_) - fclose(file_); - } - - private: - FILE *file_; -}; - -struct SourceLineResolverBase::Line { - Line() { } - Line(MemAddr addr, MemAddr code_size, int file_id, int source_line) - : address(addr) - , size(code_size) - , source_file_id(file_id) - , line(source_line) { } - - MemAddr address; - MemAddr size; - int32_t source_file_id; - int32_t line; -}; - -struct SourceLineResolverBase::Function { - Function() { } - Function(const string &function_name, - MemAddr function_address, - MemAddr code_size, - int set_parameter_size) - : name(function_name), address(function_address), size(code_size), - parameter_size(set_parameter_size) { } - - string name; - MemAddr address; - MemAddr size; - - // The size of parameters passed to this function on the stack. - int32_t parameter_size; -}; - -struct SourceLineResolverBase::PublicSymbol { - PublicSymbol() { } - PublicSymbol(const string& set_name, - MemAddr set_address, - int set_parameter_size) - : name(set_name), - address(set_address), - parameter_size(set_parameter_size) {} - - string name; - MemAddr address; - - // If the public symbol is used as a function entry point, parameter_size - // is set to the size of the parameters passed to the funciton on the - // stack, if known. - int32_t parameter_size; -}; - -class SourceLineResolverBase::Module { - public: - virtual ~Module() { }; - // Loads a map from the given buffer in char* type. - // Does NOT take ownership of memory_buffer (the caller, source line resolver, - // is the owner of memory_buffer). - // The passed in |memory buffer| is of size |memory_buffer_size|. If it is - // not null terminated, LoadMapFromMemory will null terminate it by modifying - // the passed in buffer. - virtual bool LoadMapFromMemory(char *memory_buffer, - size_t memory_buffer_size) = 0; - - // Tells whether the loaded symbol data is corrupt. Return value is - // undefined, if the symbol data hasn't been loaded yet. - virtual bool IsCorrupt() const = 0; - - // Looks up the given relative address, and fills the StackFrame struct - // with the result. - virtual void LookupAddress(StackFrame *frame) const = 0; - - // If Windows stack walking information is available covering ADDRESS, - // return a WindowsFrameInfo structure describing it. If the information - // is not available, returns NULL. A NULL return value does not indicate - // an error. The caller takes ownership of any returned WindowsFrameInfo - // object. - virtual WindowsFrameInfo * - FindWindowsFrameInfo(const StackFrame *frame) const = 0; - - // If CFI stack walking information is available covering ADDRESS, - // return a CFIFrameInfo structure describing it. If the information - // is not available, return NULL. The caller takes ownership of any - // returned CFIFrameInfo object. - virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) const = 0; - protected: - virtual bool ParseCFIRuleSet(const string &rule_set, - CFIFrameInfo *frame_info) const; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_cpu.cc b/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_cpu.cc deleted file mode 100644 index 6175dc7f2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_cpu.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stack_frame_cpu.h: CPU-specific StackFrame extensions. -// -// See google_breakpad/processor/stack_frame_cpu.h for documentation. -// -// Author: Colin Blundell - -#include "google_breakpad/processor/stack_frame_cpu.h" - -namespace google_breakpad { - -const uint64_t StackFrameARM64::CONTEXT_VALID_X0; -const uint64_t StackFrameARM64::CONTEXT_VALID_X1; -const uint64_t StackFrameARM64::CONTEXT_VALID_X2; -const uint64_t StackFrameARM64::CONTEXT_VALID_X3; -const uint64_t StackFrameARM64::CONTEXT_VALID_X4; -const uint64_t StackFrameARM64::CONTEXT_VALID_X5; -const uint64_t StackFrameARM64::CONTEXT_VALID_X6; -const uint64_t StackFrameARM64::CONTEXT_VALID_X7; -const uint64_t StackFrameARM64::CONTEXT_VALID_X8; -const uint64_t StackFrameARM64::CONTEXT_VALID_X9; -const uint64_t StackFrameARM64::CONTEXT_VALID_X10; -const uint64_t StackFrameARM64::CONTEXT_VALID_X11; -const uint64_t StackFrameARM64::CONTEXT_VALID_X12; -const uint64_t StackFrameARM64::CONTEXT_VALID_X13; -const uint64_t StackFrameARM64::CONTEXT_VALID_X14; -const uint64_t StackFrameARM64::CONTEXT_VALID_X15; -const uint64_t StackFrameARM64::CONTEXT_VALID_X16; -const uint64_t StackFrameARM64::CONTEXT_VALID_X17; -const uint64_t StackFrameARM64::CONTEXT_VALID_X18; -const uint64_t StackFrameARM64::CONTEXT_VALID_X19; -const uint64_t StackFrameARM64::CONTEXT_VALID_X20; -const uint64_t StackFrameARM64::CONTEXT_VALID_X21; -const uint64_t StackFrameARM64::CONTEXT_VALID_X22; -const uint64_t StackFrameARM64::CONTEXT_VALID_X23; -const uint64_t StackFrameARM64::CONTEXT_VALID_X24; -const uint64_t StackFrameARM64::CONTEXT_VALID_X25; -const uint64_t StackFrameARM64::CONTEXT_VALID_X26; -const uint64_t StackFrameARM64::CONTEXT_VALID_X27; -const uint64_t StackFrameARM64::CONTEXT_VALID_X28; -const uint64_t StackFrameARM64::CONTEXT_VALID_X29; -const uint64_t StackFrameARM64::CONTEXT_VALID_X30; -const uint64_t StackFrameARM64::CONTEXT_VALID_X31; -const uint64_t StackFrameARM64::CONTEXT_VALID_X32; -const uint64_t StackFrameARM64::CONTEXT_VALID_FP; -const uint64_t StackFrameARM64::CONTEXT_VALID_LR; -const uint64_t StackFrameARM64::CONTEXT_VALID_SP; -const uint64_t StackFrameARM64::CONTEXT_VALID_PC; -const uint64_t StackFrameARM64::CONTEXT_VALID_ALL; - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_symbolizer.cc b/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_symbolizer.cc deleted file mode 100644 index 5c8dbe5e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stack_frame_symbolizer.cc +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2012 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Implementation of StackFrameSymbolizer, which encapsulates the logic of how -// SourceLineResolverInterface interacts with SymbolSupplier to fill source -// line information in a stack frame, and also looks up WindowsFrameInfo or -// CFIFrameInfo for a stack frame. - -#include "google_breakpad/processor/stack_frame_symbolizer.h" - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/symbol_supplier.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" - -namespace google_breakpad { - -StackFrameSymbolizer::StackFrameSymbolizer( - SymbolSupplier* supplier, - SourceLineResolverInterface* resolver) : supplier_(supplier), - resolver_(resolver) { } - -StackFrameSymbolizer::SymbolizerResult StackFrameSymbolizer::FillSourceLineInfo( - const CodeModules* modules, - const SystemInfo* system_info, - StackFrame* frame) { - assert(frame); - - if (!modules) return kError; - const CodeModule* module = modules->GetModuleForAddress(frame->instruction); - if (!module) return kError; - frame->module = module; - - if (!resolver_) return kError; // no resolver. - // If module is known to have missing symbol file, return. - if (no_symbol_modules_.find(module->code_file()) != - no_symbol_modules_.end()) { - return kError; - } - - // If module is already loaded, go ahead to fill source line info and return. - if (resolver_->HasModule(frame->module)) { - resolver_->FillSourceLineInfo(frame); - return resolver_->IsModuleCorrupt(frame->module) ? - kWarningCorruptSymbols : kNoError; - } - - // Module needs to fetch symbol file. First check to see if supplier exists. - if (!supplier_) { - return kError; - } - - // Start fetching symbol from supplier. - string symbol_file; - char* symbol_data = NULL; - size_t symbol_data_size; - SymbolSupplier::SymbolResult symbol_result = supplier_->GetCStringSymbolData( - module, system_info, &symbol_file, &symbol_data, &symbol_data_size); - - switch (symbol_result) { - case SymbolSupplier::FOUND: { - bool load_success = resolver_->LoadModuleUsingMemoryBuffer( - frame->module, - symbol_data, - symbol_data_size); - if (resolver_->ShouldDeleteMemoryBufferAfterLoadModule()) { - supplier_->FreeSymbolData(module); - } - - if (load_success) { - resolver_->FillSourceLineInfo(frame); - return resolver_->IsModuleCorrupt(frame->module) ? - kWarningCorruptSymbols : kNoError; - } else { - BPLOG(ERROR) << "Failed to load symbol file in resolver."; - no_symbol_modules_.insert(module->code_file()); - return kError; - } - } - - case SymbolSupplier::NOT_FOUND: - no_symbol_modules_.insert(module->code_file()); - return kError; - - case SymbolSupplier::INTERRUPT: - return kInterrupt; - - default: - BPLOG(ERROR) << "Unknown SymbolResult enum: " << symbol_result; - return kError; - } - return kError; -} - -WindowsFrameInfo* StackFrameSymbolizer::FindWindowsFrameInfo( - const StackFrame* frame) { - return resolver_ ? resolver_->FindWindowsFrameInfo(frame) : NULL; -} - -CFIFrameInfo* StackFrameSymbolizer::FindCFIFrameInfo( - const StackFrame* frame) { - return resolver_ ? resolver_->FindCFIFrameInfo(frame) : NULL; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.cc deleted file mode 100644 index 704039f34..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.cc +++ /dev/null @@ -1,950 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalk_common.cc: Module shared by the {micro,mini}dump_stackwalck -// executables to print the content of dumps (w/ stack traces) on the console. -// -// Author: Mark Mentovai - -#include "processor/stackwalk_common.h" - -#include -#include -#include - -#include -#include - -#include "common/stdio_wrapper.h" -#include "common/using_std_string.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/logging.h" -#include "processor/pathname_stripper.h" - -namespace google_breakpad { - -namespace { - -using std::vector; - -// Separator character for machine readable output. -static const char kOutputSeparator = '|'; - -// PrintRegister prints a register's name and value to stdout. It will -// print four registers on a line. For the first register in a set, -// pass 0 for |start_col|. For registers in a set, pass the most recent -// return value of PrintRegister. -// The caller is responsible for printing the final newline after a set -// of registers is completely printed, regardless of the number of calls -// to PrintRegister. -static const int kMaxWidth = 80; // optimize for an 80-column terminal -static int PrintRegister(const char *name, uint32_t value, int start_col) { - char buffer[64]; - snprintf(buffer, sizeof(buffer), " %5s = 0x%08x", name, value); - - if (start_col + static_cast(strlen(buffer)) > kMaxWidth) { - start_col = 0; - printf("\n "); - } - fputs(buffer, stdout); - - return start_col + strlen(buffer); -} - -// PrintRegister64 does the same thing, but for 64-bit registers. -static int PrintRegister64(const char *name, uint64_t value, int start_col) { - char buffer[64]; - snprintf(buffer, sizeof(buffer), " %5s = 0x%016" PRIx64 , name, value); - - if (start_col + static_cast(strlen(buffer)) > kMaxWidth) { - start_col = 0; - printf("\n "); - } - fputs(buffer, stdout); - - return start_col + strlen(buffer); -} - -// StripSeparator takes a string |original| and returns a copy -// of the string with all occurences of |kOutputSeparator| removed. -static string StripSeparator(const string &original) { - string result = original; - string::size_type position = 0; - while ((position = result.find(kOutputSeparator, position)) != string::npos) { - result.erase(position, 1); - } - position = 0; - while ((position = result.find('\n', position)) != string::npos) { - result.erase(position, 1); - } - return result; -} - -// PrintStackContents prints the stack contents of the current frame to stdout. -static void PrintStackContents(const string &indent, - const StackFrame *frame, - const StackFrame *prev_frame, - const string &cpu, - const MemoryRegion *memory, - const CodeModules* modules, - SourceLineResolverInterface *resolver) { - // Find stack range. - int word_length = 0; - uint64_t stack_begin = 0, stack_end = 0; - if (cpu == "x86") { - word_length = 4; - const StackFrameX86 *frame_x86 = static_cast(frame); - const StackFrameX86 *prev_frame_x86 = - static_cast(prev_frame); - if ((frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP) && - (prev_frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP)) { - stack_begin = frame_x86->context.esp; - stack_end = prev_frame_x86->context.esp; - } - } else if (cpu == "amd64") { - word_length = 8; - const StackFrameAMD64 *frame_amd64 = - static_cast(frame); - const StackFrameAMD64 *prev_frame_amd64 = - static_cast(prev_frame); - if ((frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSP) && - (prev_frame_amd64->context_validity & - StackFrameAMD64::CONTEXT_VALID_RSP)) { - stack_begin = frame_amd64->context.rsp; - stack_end = prev_frame_amd64->context.rsp; - } - } else if (cpu == "arm") { - word_length = 4; - const StackFrameARM *frame_arm = static_cast(frame); - const StackFrameARM *prev_frame_arm = - static_cast(prev_frame); - if ((frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_SP) && - (prev_frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { - stack_begin = frame_arm->context.iregs[13]; - stack_end = prev_frame_arm->context.iregs[13]; - } - } else if (cpu == "arm64") { - word_length = 8; - const StackFrameARM64 *frame_arm64 = - static_cast(frame); - const StackFrameARM64 *prev_frame_arm64 = - static_cast(prev_frame); - if ((frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_SP) && - (prev_frame_arm64->context_validity & - StackFrameARM64::CONTEXT_VALID_SP)) { - stack_begin = frame_arm64->context.iregs[31]; - stack_end = prev_frame_arm64->context.iregs[31]; - } - } - if (!word_length || !stack_begin || !stack_end) - return; - - // Print stack contents. - printf("\n%sStack contents:", indent.c_str()); - for(uint64_t address = stack_begin; address < stack_end; ) { - // Print the start address of this row. - if (word_length == 4) - printf("\n%s %08x", indent.c_str(), static_cast(address)); - else - printf("\n%s %016" PRIx64, indent.c_str(), address); - - // Print data in hex. - const int kBytesPerRow = 16; - string data_as_string; - for (int i = 0; i < kBytesPerRow; ++i, ++address) { - uint8_t value = 0; - if (address < stack_end && - memory->GetMemoryAtAddress(address, &value)) { - printf(" %02x", value); - data_as_string.push_back(isprint(value) ? value : '.'); - } else { - printf(" "); - data_as_string.push_back(' '); - } - } - // Print data as string. - printf(" %s", data_as_string.c_str()); - } - - // Try to find instruction pointers from stack. - printf("\n%sPossible instruction pointers:\n", indent.c_str()); - for (uint64_t address = stack_begin; address < stack_end; - address += word_length) { - StackFrame pointee_frame; - - // Read a word (possible instruction pointer) from stack. - if (word_length == 4) { - uint32_t data32 = 0; - memory->GetMemoryAtAddress(address, &data32); - pointee_frame.instruction = data32; - } else { - uint64_t data64 = 0; - memory->GetMemoryAtAddress(address, &data64); - pointee_frame.instruction = data64; - } - pointee_frame.module = - modules->GetModuleForAddress(pointee_frame.instruction); - - // Try to look up the function name. - if (pointee_frame.module) - resolver->FillSourceLineInfo(&pointee_frame); - - // Print function name. - if (!pointee_frame.function_name.empty()) { - if (word_length == 4) { - printf("%s *(0x%08x) = 0x%08x", indent.c_str(), - static_cast(address), - static_cast(pointee_frame.instruction)); - } else { - printf("%s *(0x%016" PRIx64 ") = 0x%016" PRIx64, - indent.c_str(), address, pointee_frame.instruction); - } - printf(" <%s> [%s : %d + 0x%" PRIx64 "]\n", - pointee_frame.function_name.c_str(), - PathnameStripper::File(pointee_frame.source_file_name).c_str(), - pointee_frame.source_line, - pointee_frame.instruction - pointee_frame.source_line_base); - } - } - printf("\n"); -} - -// PrintStack prints the call stack in |stack| to stdout, in a reasonably -// useful form. Module, function, and source file names are displayed if -// they are available. The code offset to the base code address of the -// source line, function, or module is printed, preferring them in that -// order. If no source line, function, or module information is available, -// an absolute code offset is printed. -// -// If |cpu| is a recognized CPU name, relevant register state for each stack -// frame printed is also output, if available. -static void PrintStack(const CallStack *stack, - const string &cpu, - bool output_stack_contents, - const MemoryRegion* memory, - const CodeModules* modules, - SourceLineResolverInterface* resolver) { - int frame_count = stack->frames()->size(); - if (frame_count == 0) { - printf(" \n"); - } - for (int frame_index = 0; frame_index < frame_count; ++frame_index) { - const StackFrame *frame = stack->frames()->at(frame_index); - printf("%2d ", frame_index); - - uint64_t instruction_address = frame->ReturnAddress(); - - if (frame->module) { - printf("%s", PathnameStripper::File(frame->module->code_file()).c_str()); - if (!frame->function_name.empty()) { - printf("!%s", frame->function_name.c_str()); - if (!frame->source_file_name.empty()) { - string source_file = PathnameStripper::File(frame->source_file_name); - printf(" [%s : %d + 0x%" PRIx64 "]", - source_file.c_str(), - frame->source_line, - instruction_address - frame->source_line_base); - } else { - printf(" + 0x%" PRIx64, instruction_address - frame->function_base); - } - } else { - printf(" + 0x%" PRIx64, - instruction_address - frame->module->base_address()); - } - } else { - printf("0x%" PRIx64, instruction_address); - } - printf("\n "); - - int sequence = 0; - if (cpu == "x86") { - const StackFrameX86 *frame_x86 = - reinterpret_cast(frame); - - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EIP) - sequence = PrintRegister("eip", frame_x86->context.eip, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP) - sequence = PrintRegister("esp", frame_x86->context.esp, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBP) - sequence = PrintRegister("ebp", frame_x86->context.ebp, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBX) - sequence = PrintRegister("ebx", frame_x86->context.ebx, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESI) - sequence = PrintRegister("esi", frame_x86->context.esi, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EDI) - sequence = PrintRegister("edi", frame_x86->context.edi, sequence); - if (frame_x86->context_validity == StackFrameX86::CONTEXT_VALID_ALL) { - sequence = PrintRegister("eax", frame_x86->context.eax, sequence); - sequence = PrintRegister("ecx", frame_x86->context.ecx, sequence); - sequence = PrintRegister("edx", frame_x86->context.edx, sequence); - sequence = PrintRegister("efl", frame_x86->context.eflags, sequence); - } - } else if (cpu == "ppc") { - const StackFramePPC *frame_ppc = - reinterpret_cast(frame); - - if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_SRR0) - sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence); - if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_GPR1) - sequence = PrintRegister("r1", frame_ppc->context.gpr[1], sequence); - } else if (cpu == "amd64") { - const StackFrameAMD64 *frame_amd64 = - reinterpret_cast(frame); - - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RAX) - sequence = PrintRegister64("rax", frame_amd64->context.rax, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RDX) - sequence = PrintRegister64("rdx", frame_amd64->context.rdx, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RCX) - sequence = PrintRegister64("rcx", frame_amd64->context.rcx, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RBX) - sequence = PrintRegister64("rbx", frame_amd64->context.rbx, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSI) - sequence = PrintRegister64("rsi", frame_amd64->context.rsi, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RDI) - sequence = PrintRegister64("rdi", frame_amd64->context.rdi, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RBP) - sequence = PrintRegister64("rbp", frame_amd64->context.rbp, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSP) - sequence = PrintRegister64("rsp", frame_amd64->context.rsp, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R8) - sequence = PrintRegister64("r8", frame_amd64->context.r8, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R9) - sequence = PrintRegister64("r9", frame_amd64->context.r9, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R10) - sequence = PrintRegister64("r10", frame_amd64->context.r10, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R11) - sequence = PrintRegister64("r11", frame_amd64->context.r11, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R12) - sequence = PrintRegister64("r12", frame_amd64->context.r12, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R13) - sequence = PrintRegister64("r13", frame_amd64->context.r13, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R14) - sequence = PrintRegister64("r14", frame_amd64->context.r14, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R15) - sequence = PrintRegister64("r15", frame_amd64->context.r15, sequence); - if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RIP) - sequence = PrintRegister64("rip", frame_amd64->context.rip, sequence); - } else if (cpu == "sparc") { - const StackFrameSPARC *frame_sparc = - reinterpret_cast(frame); - - if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_SP) - sequence = PrintRegister("sp", frame_sparc->context.g_r[14], sequence); - if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_FP) - sequence = PrintRegister("fp", frame_sparc->context.g_r[30], sequence); - if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_PC) - sequence = PrintRegister("pc", frame_sparc->context.pc, sequence); - } else if (cpu == "arm") { - const StackFrameARM *frame_arm = - reinterpret_cast(frame); - - // Argument registers (caller-saves), which will likely only be valid - // for the youngest frame. - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R0) - sequence = PrintRegister("r0", frame_arm->context.iregs[0], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R1) - sequence = PrintRegister("r1", frame_arm->context.iregs[1], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R2) - sequence = PrintRegister("r2", frame_arm->context.iregs[2], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R3) - sequence = PrintRegister("r3", frame_arm->context.iregs[3], sequence); - - // General-purpose callee-saves registers. - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R4) - sequence = PrintRegister("r4", frame_arm->context.iregs[4], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R5) - sequence = PrintRegister("r5", frame_arm->context.iregs[5], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R6) - sequence = PrintRegister("r6", frame_arm->context.iregs[6], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R7) - sequence = PrintRegister("r7", frame_arm->context.iregs[7], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R8) - sequence = PrintRegister("r8", frame_arm->context.iregs[8], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R9) - sequence = PrintRegister("r9", frame_arm->context.iregs[9], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R10) - sequence = PrintRegister("r10", frame_arm->context.iregs[10], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R12) - sequence = PrintRegister("r12", frame_arm->context.iregs[12], sequence); - - // Registers with a dedicated or conventional purpose. - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_FP) - sequence = PrintRegister("fp", frame_arm->context.iregs[11], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_SP) - sequence = PrintRegister("sp", frame_arm->context.iregs[13], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_LR) - sequence = PrintRegister("lr", frame_arm->context.iregs[14], sequence); - if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_PC) - sequence = PrintRegister("pc", frame_arm->context.iregs[15], sequence); - } else if (cpu == "arm64") { - const StackFrameARM64 *frame_arm64 = - reinterpret_cast(frame); - - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X0) { - sequence = - PrintRegister64("x0", frame_arm64->context.iregs[0], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X1) { - sequence = - PrintRegister64("x1", frame_arm64->context.iregs[1], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X2) { - sequence = - PrintRegister64("x2", frame_arm64->context.iregs[2], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X3) { - sequence = - PrintRegister64("x3", frame_arm64->context.iregs[3], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X4) { - sequence = - PrintRegister64("x4", frame_arm64->context.iregs[4], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X5) { - sequence = - PrintRegister64("x5", frame_arm64->context.iregs[5], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X6) { - sequence = - PrintRegister64("x6", frame_arm64->context.iregs[6], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X7) { - sequence = - PrintRegister64("x7", frame_arm64->context.iregs[7], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X8) { - sequence = - PrintRegister64("x8", frame_arm64->context.iregs[8], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X9) { - sequence = - PrintRegister64("x9", frame_arm64->context.iregs[9], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X10) { - sequence = - PrintRegister64("x10", frame_arm64->context.iregs[10], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X11) { - sequence = - PrintRegister64("x11", frame_arm64->context.iregs[11], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X12) { - sequence = - PrintRegister64("x12", frame_arm64->context.iregs[12], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X13) { - sequence = - PrintRegister64("x13", frame_arm64->context.iregs[13], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X14) { - sequence = - PrintRegister64("x14", frame_arm64->context.iregs[14], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X15) { - sequence = - PrintRegister64("x15", frame_arm64->context.iregs[15], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X16) { - sequence = - PrintRegister64("x16", frame_arm64->context.iregs[16], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X17) { - sequence = - PrintRegister64("x17", frame_arm64->context.iregs[17], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X18) { - sequence = - PrintRegister64("x18", frame_arm64->context.iregs[18], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X19) { - sequence = - PrintRegister64("x19", frame_arm64->context.iregs[19], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X20) { - sequence = - PrintRegister64("x20", frame_arm64->context.iregs[20], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X21) { - sequence = - PrintRegister64("x21", frame_arm64->context.iregs[21], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X22) { - sequence = - PrintRegister64("x22", frame_arm64->context.iregs[22], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X23) { - sequence = - PrintRegister64("x23", frame_arm64->context.iregs[23], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X24) { - sequence = - PrintRegister64("x24", frame_arm64->context.iregs[24], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X25) { - sequence = - PrintRegister64("x25", frame_arm64->context.iregs[25], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X26) { - sequence = - PrintRegister64("x26", frame_arm64->context.iregs[26], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X27) { - sequence = - PrintRegister64("x27", frame_arm64->context.iregs[27], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X28) { - sequence = - PrintRegister64("x28", frame_arm64->context.iregs[28], sequence); - } - - // Registers with a dedicated or conventional purpose. - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_FP) { - sequence = - PrintRegister64("fp", frame_arm64->context.iregs[29], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_LR) { - sequence = - PrintRegister64("lr", frame_arm64->context.iregs[30], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_SP) { - sequence = - PrintRegister64("sp", frame_arm64->context.iregs[31], sequence); - } - if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_PC) { - sequence = - PrintRegister64("pc", frame_arm64->context.iregs[32], sequence); - } - } else if ((cpu == "mips") || (cpu == "mips64")) { - const StackFrameMIPS* frame_mips = - reinterpret_cast(frame); - - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_GP) - sequence = PrintRegister64("gp", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_GP], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_SP) - sequence = PrintRegister64("sp", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_SP], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_FP) - sequence = PrintRegister64("fp", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_FP], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_RA) - sequence = PrintRegister64("ra", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_RA], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_PC) - sequence = PrintRegister64("pc", frame_mips->context.epc, sequence); - - // Save registers s0-s7 - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S0) - sequence = PrintRegister64("s0", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S0], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S1) - sequence = PrintRegister64("s1", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S1], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S2) - sequence = PrintRegister64("s2", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S2], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S3) - sequence = PrintRegister64("s3", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S3], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S4) - sequence = PrintRegister64("s4", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S4], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S5) - sequence = PrintRegister64("s5", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S5], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S6) - sequence = PrintRegister64("s6", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S6], - sequence); - if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S7) - sequence = PrintRegister64("s7", - frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S7], - sequence); - } - printf("\n Found by: %s\n", frame->trust_description().c_str()); - - // Print stack contents. - if (output_stack_contents && frame_index + 1 < frame_count) { - const string indent(" "); - PrintStackContents(indent, frame, stack->frames()->at(frame_index + 1), - cpu, memory, modules, resolver); - } - } -} - -// PrintStackMachineReadable prints the call stack in |stack| to stdout, -// in the following machine readable pipe-delimited text format: -// thread number|frame number|module|function|source file|line|offset -// -// Module, function, source file, and source line may all be empty -// depending on availability. The code offset follows the same rules as -// PrintStack above. -static void PrintStackMachineReadable(int thread_num, const CallStack *stack) { - int frame_count = stack->frames()->size(); - for (int frame_index = 0; frame_index < frame_count; ++frame_index) { - const StackFrame *frame = stack->frames()->at(frame_index); - printf("%d%c%d%c", thread_num, kOutputSeparator, frame_index, - kOutputSeparator); - - uint64_t instruction_address = frame->ReturnAddress(); - - if (frame->module) { - assert(!frame->module->code_file().empty()); - printf("%s", StripSeparator(PathnameStripper::File( - frame->module->code_file())).c_str()); - if (!frame->function_name.empty()) { - printf("%c%s", kOutputSeparator, - StripSeparator(frame->function_name).c_str()); - if (!frame->source_file_name.empty()) { - printf("%c%s%c%d%c0x%" PRIx64, - kOutputSeparator, - StripSeparator(frame->source_file_name).c_str(), - kOutputSeparator, - frame->source_line, - kOutputSeparator, - instruction_address - frame->source_line_base); - } else { - printf("%c%c%c0x%" PRIx64, - kOutputSeparator, // empty source file - kOutputSeparator, // empty source line - kOutputSeparator, - instruction_address - frame->function_base); - } - } else { - printf("%c%c%c%c0x%" PRIx64, - kOutputSeparator, // empty function name - kOutputSeparator, // empty source file - kOutputSeparator, // empty source line - kOutputSeparator, - instruction_address - frame->module->base_address()); - } - } else { - // the printf before this prints a trailing separator for module name - printf("%c%c%c%c0x%" PRIx64, - kOutputSeparator, // empty function name - kOutputSeparator, // empty source file - kOutputSeparator, // empty source line - kOutputSeparator, - instruction_address); - } - printf("\n"); - } -} - -// ContainsModule checks whether a given |module| is in the vector -// |modules_without_symbols|. -static bool ContainsModule( - const vector *modules, - const CodeModule *module) { - assert(modules); - assert(module); - vector::const_iterator iter; - for (iter = modules->begin(); iter != modules->end(); ++iter) { - if (module->debug_file().compare((*iter)->debug_file()) == 0 && - module->debug_identifier().compare((*iter)->debug_identifier()) == 0) { - return true; - } - } - return false; -} - -// PrintModule prints a single |module| to stdout. -// |modules_without_symbols| should contain the list of modules that were -// confirmed to be missing their symbols during the stack walk. -static void PrintModule( - const CodeModule *module, - const vector *modules_without_symbols, - const vector *modules_with_corrupt_symbols, - uint64_t main_address) { - string symbol_issues; - if (ContainsModule(modules_without_symbols, module)) { - symbol_issues = " (WARNING: No symbols, " + - PathnameStripper::File(module->debug_file()) + ", " + - module->debug_identifier() + ")"; - } else if (ContainsModule(modules_with_corrupt_symbols, module)) { - symbol_issues = " (WARNING: Corrupt symbols, " + - PathnameStripper::File(module->debug_file()) + ", " + - module->debug_identifier() + ")"; - } - uint64_t base_address = module->base_address(); - printf("0x%08" PRIx64 " - 0x%08" PRIx64 " %s %s%s%s\n", - base_address, base_address + module->size() - 1, - PathnameStripper::File(module->code_file()).c_str(), - module->version().empty() ? "???" : module->version().c_str(), - main_address != 0 && base_address == main_address ? " (main)" : "", - symbol_issues.c_str()); -} - -// PrintModules prints the list of all loaded |modules| to stdout. -// |modules_without_symbols| should contain the list of modules that were -// confirmed to be missing their symbols during the stack walk. -static void PrintModules( - const CodeModules *modules, - const vector *modules_without_symbols, - const vector *modules_with_corrupt_symbols) { - if (!modules) - return; - - printf("\n"); - printf("Loaded modules:\n"); - - uint64_t main_address = 0; - const CodeModule *main_module = modules->GetMainModule(); - if (main_module) { - main_address = main_module->base_address(); - } - - unsigned int module_count = modules->module_count(); - for (unsigned int module_sequence = 0; - module_sequence < module_count; - ++module_sequence) { - const CodeModule *module = modules->GetModuleAtSequence(module_sequence); - PrintModule(module, modules_without_symbols, modules_with_corrupt_symbols, - main_address); - } -} - -// PrintModulesMachineReadable outputs a list of loaded modules, -// one per line, in the following machine-readable pipe-delimited -// text format: -// Module|{Module Filename}|{Version}|{Debug Filename}|{Debug Identifier}| -// {Base Address}|{Max Address}|{Main} -static void PrintModulesMachineReadable(const CodeModules *modules) { - if (!modules) - return; - - uint64_t main_address = 0; - const CodeModule *main_module = modules->GetMainModule(); - if (main_module) { - main_address = main_module->base_address(); - } - - unsigned int module_count = modules->module_count(); - for (unsigned int module_sequence = 0; - module_sequence < module_count; - ++module_sequence) { - const CodeModule *module = modules->GetModuleAtSequence(module_sequence); - uint64_t base_address = module->base_address(); - printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d\n", - kOutputSeparator, - StripSeparator(PathnameStripper::File(module->code_file())).c_str(), - kOutputSeparator, StripSeparator(module->version()).c_str(), - kOutputSeparator, - StripSeparator(PathnameStripper::File(module->debug_file())).c_str(), - kOutputSeparator, - StripSeparator(module->debug_identifier()).c_str(), - kOutputSeparator, base_address, - kOutputSeparator, base_address + module->size() - 1, - kOutputSeparator, - main_module != NULL && base_address == main_address ? 1 : 0); - } -} - -} // namespace - -void PrintProcessState(const ProcessState& process_state, - bool output_stack_contents, - SourceLineResolverInterface* resolver) { - // Print OS and CPU information. - string cpu = process_state.system_info()->cpu; - string cpu_info = process_state.system_info()->cpu_info; - printf("Operating system: %s\n", process_state.system_info()->os.c_str()); - printf(" %s\n", - process_state.system_info()->os_version.c_str()); - printf("CPU: %s\n", cpu.c_str()); - if (!cpu_info.empty()) { - // This field is optional. - printf(" %s\n", cpu_info.c_str()); - } - printf(" %d CPU%s\n", - process_state.system_info()->cpu_count, - process_state.system_info()->cpu_count != 1 ? "s" : ""); - printf("\n"); - - // Print GPU information - string gl_version = process_state.system_info()->gl_version; - string gl_vendor = process_state.system_info()->gl_vendor; - string gl_renderer = process_state.system_info()->gl_renderer; - printf("GPU:"); - if (!gl_version.empty() || !gl_vendor.empty() || !gl_renderer.empty()) { - printf(" %s\n", gl_version.c_str()); - printf(" %s\n", gl_vendor.c_str()); - printf(" %s\n", gl_renderer.c_str()); - } else { - printf(" UNKNOWN\n"); - } - printf("\n"); - - // Print crash information. - if (process_state.crashed()) { - printf("Crash reason: %s\n", process_state.crash_reason().c_str()); - printf("Crash address: 0x%" PRIx64 "\n", process_state.crash_address()); - } else { - printf("No crash\n"); - } - - string assertion = process_state.assertion(); - if (!assertion.empty()) { - printf("Assertion: %s\n", assertion.c_str()); - } - - // Compute process uptime if the process creation and crash times are - // available in the dump. - if (process_state.time_date_stamp() != 0 && - process_state.process_create_time() != 0 && - process_state.time_date_stamp() >= process_state.process_create_time()) { - printf("Process uptime: %d seconds\n", - process_state.time_date_stamp() - - process_state.process_create_time()); - } else { - printf("Process uptime: not available\n"); - } - - // If the thread that requested the dump is known, print it first. - int requesting_thread = process_state.requesting_thread(); - if (requesting_thread != -1) { - printf("\n"); - printf("Thread %d (%s)\n", - requesting_thread, - process_state.crashed() ? "crashed" : - "requested dump, did not crash"); - PrintStack(process_state.threads()->at(requesting_thread), cpu, - output_stack_contents, - process_state.thread_memory_regions()->at(requesting_thread), - process_state.modules(), resolver); - } - - // Print all of the threads in the dump. - int thread_count = process_state.threads()->size(); - for (int thread_index = 0; thread_index < thread_count; ++thread_index) { - if (thread_index != requesting_thread) { - // Don't print the crash thread again, it was already printed. - printf("\n"); - printf("Thread %d\n", thread_index); - PrintStack(process_state.threads()->at(thread_index), cpu, - output_stack_contents, - process_state.thread_memory_regions()->at(thread_index), - process_state.modules(), resolver); - } - } - - PrintModules(process_state.modules(), - process_state.modules_without_symbols(), - process_state.modules_with_corrupt_symbols()); -} - -void PrintProcessStateMachineReadable(const ProcessState& process_state) { - // Print OS and CPU information. - // OS|{OS Name}|{OS Version} - // CPU|{CPU Name}|{CPU Info}|{Number of CPUs} - // GPU|{GPU version}|{GPU vendor}|{GPU renderer} - printf("OS%c%s%c%s\n", kOutputSeparator, - StripSeparator(process_state.system_info()->os).c_str(), - kOutputSeparator, - StripSeparator(process_state.system_info()->os_version).c_str()); - printf("CPU%c%s%c%s%c%d\n", kOutputSeparator, - StripSeparator(process_state.system_info()->cpu).c_str(), - kOutputSeparator, - // this may be empty - StripSeparator(process_state.system_info()->cpu_info).c_str(), - kOutputSeparator, - process_state.system_info()->cpu_count); - printf("GPU%c%s%c%s%c%s\n", kOutputSeparator, - StripSeparator(process_state.system_info()->gl_version).c_str(), - kOutputSeparator, - StripSeparator(process_state.system_info()->gl_vendor).c_str(), - kOutputSeparator, - StripSeparator(process_state.system_info()->gl_renderer).c_str()); - - int requesting_thread = process_state.requesting_thread(); - - // Print crash information. - // Crash|{Crash Reason}|{Crash Address}|{Crashed Thread} - printf("Crash%c", kOutputSeparator); - if (process_state.crashed()) { - printf("%s%c0x%" PRIx64 "%c", - StripSeparator(process_state.crash_reason()).c_str(), - kOutputSeparator, process_state.crash_address(), kOutputSeparator); - } else { - // print assertion info, if available, in place of crash reason, - // instead of the unhelpful "No crash" - string assertion = process_state.assertion(); - if (!assertion.empty()) { - printf("%s%c%c", StripSeparator(assertion).c_str(), - kOutputSeparator, kOutputSeparator); - } else { - printf("No crash%c%c", kOutputSeparator, kOutputSeparator); - } - } - - if (requesting_thread != -1) { - printf("%d\n", requesting_thread); - } else { - printf("\n"); - } - - PrintModulesMachineReadable(process_state.modules()); - - // blank line to indicate start of threads - printf("\n"); - - // If the thread that requested the dump is known, print it first. - if (requesting_thread != -1) { - PrintStackMachineReadable(requesting_thread, - process_state.threads()->at(requesting_thread)); - } - - // Print all of the threads in the dump. - int thread_count = process_state.threads()->size(); - for (int thread_index = 0; thread_index < thread_count; ++thread_index) { - if (thread_index != requesting_thread) { - // Don't print the crash thread again, it was already printed. - PrintStackMachineReadable(thread_index, - process_state.threads()->at(thread_index)); - } - } -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.h deleted file mode 100644 index a74f7b6da..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalk_common.cc: Module shared by the {micro,mini}dump_stackwalck -// executables to print the content of dumps (w/ stack traces) on the console. - - -#ifndef PROCESSOR_STACKWALK_COMMON_H__ -#define PROCESSOR_STACKWALK_COMMON_H__ - -namespace google_breakpad { - -class ProcessState; -class SourceLineResolverInterface; - -void PrintProcessStateMachineReadable(const ProcessState& process_state); -void PrintProcessState(const ProcessState& process_state, - bool output_stack_contents, - SourceLineResolverInterface* resolver); - -} // namespace google_breakpad - -#endif // PROCESSOR_STACKWALK_COMMON_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker.cc deleted file mode 100644 index 98cb0b5be..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker.cc +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker.cc: Generic stackwalker. -// -// See stackwalker.h for documentation. -// -// Author: Mark Mentovai - -#include "google_breakpad/processor/stackwalker.h" - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/dump_context.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/linked_ptr.h" -#include "processor/logging.h" -#include "processor/stackwalker_ppc.h" -#include "processor/stackwalker_ppc64.h" -#include "processor/stackwalker_sparc.h" -#include "processor/stackwalker_x86.h" -#include "processor/stackwalker_amd64.h" -#include "processor/stackwalker_arm.h" -#include "processor/stackwalker_arm64.h" -#include "processor/stackwalker_mips.h" - -namespace google_breakpad { - -const int Stackwalker::kRASearchWords = 40; - -uint32_t Stackwalker::max_frames_ = 1024; -bool Stackwalker::max_frames_set_ = false; - -uint32_t Stackwalker::max_frames_scanned_ = 1024; - -Stackwalker::Stackwalker(const SystemInfo* system_info, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer) - : system_info_(system_info), - memory_(memory), - modules_(modules), - frame_symbolizer_(frame_symbolizer) { - assert(frame_symbolizer_); -} - -void InsertSpecialAttentionModule( - StackFrameSymbolizer::SymbolizerResult symbolizer_result, - const CodeModule* module, - vector* modules) { - if (!module) { - return; - } - assert(symbolizer_result == StackFrameSymbolizer::kError || - symbolizer_result == StackFrameSymbolizer::kWarningCorruptSymbols); - bool found = false; - vector::iterator iter; - for (iter = modules->begin(); iter != modules->end(); ++iter) { - if (*iter == module) { - found = true; - break; - } - } - if (!found) { - BPLOG(INFO) << ((symbolizer_result == StackFrameSymbolizer::kError) ? - "Couldn't load symbols for: " : - "Detected corrupt symbols for: ") - << module->debug_file() << "|" << module->debug_identifier(); - modules->push_back(module); - } -} - -bool Stackwalker::Walk( - CallStack* stack, - vector* modules_without_symbols, - vector* modules_with_corrupt_symbols) { - BPLOG_IF(ERROR, !stack) << "Stackwalker::Walk requires |stack|"; - assert(stack); - stack->Clear(); - - BPLOG_IF(ERROR, !modules_without_symbols) << "Stackwalker::Walk requires " - << "|modules_without_symbols|"; - BPLOG_IF(ERROR, !modules_without_symbols) << "Stackwalker::Walk requires " - << "|modules_with_corrupt_symbols|"; - assert(modules_without_symbols); - assert(modules_with_corrupt_symbols); - - // Begin with the context frame, and keep getting callers until there are - // no more. - - // Keep track of the number of scanned or otherwise dubious frames seen - // so far, as the caller may have set a limit. - uint32_t scanned_frames = 0; - - // Take ownership of the pointer returned by GetContextFrame. - scoped_ptr frame(GetContextFrame()); - - while (frame.get()) { - // frame already contains a good frame with properly set instruction and - // frame_pointer fields. The frame structure comes from either the - // context frame (above) or a caller frame (below). - - // Resolve the module information, if a module map was provided. - StackFrameSymbolizer::SymbolizerResult symbolizer_result = - frame_symbolizer_->FillSourceLineInfo(modules_, system_info_, - frame.get()); - switch (symbolizer_result) { - case StackFrameSymbolizer::kInterrupt: - BPLOG(INFO) << "Stack walk is interrupted."; - return false; - break; - case StackFrameSymbolizer::kError: - InsertSpecialAttentionModule(symbolizer_result, frame->module, - modules_without_symbols); - break; - case StackFrameSymbolizer::kWarningCorruptSymbols: - InsertSpecialAttentionModule(symbolizer_result, frame->module, - modules_with_corrupt_symbols); - break; - case StackFrameSymbolizer::kNoError: - break; - default: - assert(false); - break; - } - - // Keep track of the number of dubious frames so far. - switch (frame.get()->trust) { - case StackFrame::FRAME_TRUST_NONE: - case StackFrame::FRAME_TRUST_SCAN: - case StackFrame::FRAME_TRUST_CFI_SCAN: - scanned_frames++; - break; - default: - break; - } - - // Add the frame to the call stack. Relinquish the ownership claim - // over the frame, because the stack now owns it. - stack->frames_.push_back(frame.release()); - if (stack->frames_.size() > max_frames_) { - // Only emit an error message in the case where the limit - // reached is the default limit, not set by the user. - if (!max_frames_set_) - BPLOG(ERROR) << "The stack is over " << max_frames_ << " frames."; - break; - } - - // Get the next frame and take ownership. - bool stack_scan_allowed = scanned_frames < max_frames_scanned_; - frame.reset(GetCallerFrame(stack, stack_scan_allowed)); - } - - return true; -} - - -// static -Stackwalker* Stackwalker::StackwalkerForCPU( - const SystemInfo* system_info, - DumpContext* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer) { - if (!context) { - BPLOG(ERROR) << "Can't choose a stackwalker implementation without context"; - return NULL; - } - - Stackwalker* cpu_stackwalker = NULL; - - uint32_t cpu = context->GetContextCPU(); - switch (cpu) { - case MD_CONTEXT_X86: - cpu_stackwalker = new StackwalkerX86(system_info, - context->GetContextX86(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_PPC: - cpu_stackwalker = new StackwalkerPPC(system_info, - context->GetContextPPC(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_PPC64: - cpu_stackwalker = new StackwalkerPPC64(system_info, - context->GetContextPPC64(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_AMD64: - cpu_stackwalker = new StackwalkerAMD64(system_info, - context->GetContextAMD64(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_SPARC: - cpu_stackwalker = new StackwalkerSPARC(system_info, - context->GetContextSPARC(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_MIPS: - case MD_CONTEXT_MIPS64: - cpu_stackwalker = new StackwalkerMIPS(system_info, - context->GetContextMIPS(), - memory, modules, frame_symbolizer); - break; - - case MD_CONTEXT_ARM: - { - int fp_register = -1; - if (system_info->os_short == "ios") - fp_register = MD_CONTEXT_ARM_REG_IOS_FP; - cpu_stackwalker = new StackwalkerARM(system_info, - context->GetContextARM(), - fp_register, memory, modules, - frame_symbolizer); - break; - } - - case MD_CONTEXT_ARM64: - cpu_stackwalker = new StackwalkerARM64(system_info, - context->GetContextARM64(), - memory, modules, - frame_symbolizer); - break; - } - - BPLOG_IF(ERROR, !cpu_stackwalker) << "Unknown CPU type " << HexString(cpu) << - ", can't choose a stackwalker " - "implementation"; - return cpu_stackwalker; -} - -bool Stackwalker::InstructionAddressSeemsValid(uint64_t address) { - StackFrame frame; - frame.instruction = address; - StackFrameSymbolizer::SymbolizerResult symbolizer_result = - frame_symbolizer_->FillSourceLineInfo(modules_, system_info_, &frame); - - if (!frame.module) { - // not inside any loaded module - return false; - } - - if (!frame_symbolizer_->HasImplementation()) { - // No valid implementation to symbolize stack frame, but the address is - // within a known module. - return true; - } - - if (symbolizer_result != StackFrameSymbolizer::kNoError && - symbolizer_result != StackFrameSymbolizer::kWarningCorruptSymbols) { - // Some error occurred during symbolization, but the address is within a - // known module - return true; - } - - return !frame.function_name.empty(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.cc deleted file mode 100644 index e81fec282..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_address_list.cc: a pseudo stack walker. -// -// See stackwalker_address_list.h for documentation. -// -// Author: Chris Hamilton - -#include - -#include - -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/logging.h" -#include "processor/stackwalker_address_list.h" - -namespace google_breakpad { - -StackwalkerAddressList::StackwalkerAddressList( - const uint64_t* frames, - size_t frame_count, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer) - : Stackwalker(NULL, NULL, modules, frame_symbolizer), - frames_(frames), - frame_count_(frame_count) { - assert(frames); - assert(frame_symbolizer); -} - -StackFrame* StackwalkerAddressList::GetContextFrame() { - if (frame_count_ == 0) - return NULL; - - StackFrame* frame = new StackFrame(); - frame->instruction = frames_[0]; - frame->trust = StackFrame::FRAME_TRUST_PREWALKED; - return frame; -} - -StackFrame* StackwalkerAddressList::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!stack) { - BPLOG(ERROR) << "Can't get caller frame without stack"; - return NULL; - } - - size_t frame_index = stack->frames()->size(); - - // There are no more frames to fetch. - if (frame_index >= frame_count_) - return NULL; - - // All frames have the highest level of trust because they were - // explicitly provided. - StackFrame* frame = new StackFrame(); - frame->instruction = frames_[frame_index]; - frame->trust = StackFrame::FRAME_TRUST_PREWALKED; - return frame; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.h deleted file mode 100644 index 0f8c989ef..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_address_list.h: a pseudo stackwalker. -// -// Doesn't actually walk a stack, rather initializes a CallStack given an -// explicit list of already walked return addresses. -// -// Author: Chris Hamilton - -#ifndef PROCESSOR_STACKWALKER_ADDRESS_LIST_H_ -#define PROCESSOR_STACKWALKER_ADDRESS_LIST_H_ - -#include "common/basictypes.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerAddressList : public Stackwalker { - public: - // Initializes this stack walker with an explicit set of frame addresses. - // |modules| and |frame_symbolizer| are passed directly through to the base - // Stackwalker constructor. - StackwalkerAddressList(const uint64_t* frames, - size_t frame_count, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // Implementation of Stackwalker. - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - const uint64_t* frames_; - size_t frame_count_; - - DISALLOW_COPY_AND_ASSIGN(StackwalkerAddressList); -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STACKWALKER_ADDRESS_LIST_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list_unittest.cc deleted file mode 100644 index ab4e9c088..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list_unittest.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_address_list_unittest.cc: Unit tests for the -// StackwalkerAddressList class. -// -// Author: Chris Hamilton - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_address_list.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerAddressList; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; - -#define arraysize(f) (sizeof(f) / sizeof(*f)) - -// Addresses and sizes of a couple dummy modules. -uint64_t kModule1Base = 0x40000000; -uint64_t kModule1Size = 0x10000; -uint64_t kModule2Base = 0x50000000; -uint64_t kModule2Size = 0x10000; - -// A handful of addresses that lie within the modules above. -const uint64_t kDummyFrames[] = { - 0x50003000, 0x50002000, 0x50001000, 0x40002000, 0x40001000 }; - -class StackwalkerAddressListTest : public testing::Test { - public: - StackwalkerAddressListTest() - : // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(kModule1Base, kModule1Size, "module1", "version1"), - module2(kModule2Base, kModule2Size, "module2", "version2") { - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule *module, const string &info) { - size_t buffer_size; - char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, NULL, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - void CheckCallStack(const CallStack& call_stack) { - const std::vector* frames = call_stack.frames(); - ASSERT_EQ(arraysize(kDummyFrames), frames->size()); - for (size_t i = 0; i < arraysize(kDummyFrames); ++i) { - ASSERT_EQ(kDummyFrames[i], frames->at(i)->instruction); - ASSERT_EQ(StackFrame::FRAME_TRUST_PREWALKED, frames->at(i)->trust); - } - ASSERT_EQ(static_cast(&module2), frames->at(0)->module); - ASSERT_EQ(static_cast(&module2), frames->at(1)->module); - ASSERT_EQ(static_cast(&module2), frames->at(2)->module); - ASSERT_EQ(static_cast(&module1), frames->at(3)->module); - ASSERT_EQ(static_cast(&module1), frames->at(4)->module); - } - - MockCodeModule module1; - MockCodeModule module2; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; -}; - -TEST_F(StackwalkerAddressListTest, ScanWithoutSymbols) { - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAddressList walker(kDummyFrames, arraysize(kDummyFrames), - &modules, &frame_symbolizer); - - CallStack call_stack; - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - - // The stack starts in module2, so we expect that to be the first module - // found without symbols. - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module2", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module1", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0u, modules_with_corrupt_symbols.size()); - - ASSERT_NO_FATAL_FAILURE(CheckCallStack(call_stack)); -} - -TEST_F(StackwalkerAddressListTest, ScanWithSymbols) { - // File : FILE number(dex) name - // Function: FUNC address(hex) size(hex) parameter_size(hex) name - // Line : address(hex) size(hex) line(dec) filenum(dec) - SetModuleSymbols(&module2, - "FILE 1 module2.cc\n" - "FUNC 3000 100 10 mod2func3\n" - "3000 10 1 1\n" - "FUNC 2000 200 10 mod2func2\n" - "FUNC 1000 300 10 mod2func1\n"); - SetModuleSymbols(&module1, - "FUNC 2000 200 10 mod1func2\n" - "FUNC 1000 300 10 mod1func1\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAddressList walker(kDummyFrames, arraysize(kDummyFrames), - &modules, &frame_symbolizer); - - CallStack call_stack; - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - - ASSERT_EQ(0u, modules_without_symbols.size()); - ASSERT_EQ(0u, modules_with_corrupt_symbols.size()); - - ASSERT_NO_FATAL_FAILURE(CheckCallStack(call_stack)); - - const std::vector* frames = call_stack.frames(); - - // We have full file/line information for the first function call. - ASSERT_EQ("mod2func3", frames->at(0)->function_name); - ASSERT_EQ(0x50003000u, frames->at(0)->function_base); - ASSERT_EQ("module2.cc", frames->at(0)->source_file_name); - ASSERT_EQ(1, frames->at(0)->source_line); - ASSERT_EQ(0x50003000u, frames->at(0)->source_line_base); - - ASSERT_EQ("mod2func2", frames->at(1)->function_name); - ASSERT_EQ(0x50002000u, frames->at(1)->function_base); - - ASSERT_EQ("mod2func1", frames->at(2)->function_name); - ASSERT_EQ(0x50001000u, frames->at(2)->function_base); - - ASSERT_EQ("mod1func2", frames->at(3)->function_name); - ASSERT_EQ(0x40002000u, frames->at(3)->function_base); - - ASSERT_EQ("mod1func1", frames->at(4)->function_name); - ASSERT_EQ(0x40001000u, frames->at(4)->function_base); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.cc deleted file mode 100644 index 440724a1e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.cc +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_amd64.cc: amd64-specific stackwalker. -// -// See stackwalker_amd64.h for documentation. -// -// Author: Mark Mentovai, Ted Mielczarek - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/cfi_frame_info.h" -#include "processor/logging.h" -#include "processor/stackwalker_amd64.h" - -namespace google_breakpad { - - -const StackwalkerAMD64::CFIWalker::RegisterSet -StackwalkerAMD64::cfi_register_map_[] = { - // It may seem like $rip and $rsp are callee-saves, because the callee is - // responsible for having them restored upon return. But the callee_saves - // flags here really means that the walker should assume they're - // unchanged if the CFI doesn't mention them --- clearly wrong for $rip - // and $rsp. - { "$rax", NULL, false, - StackFrameAMD64::CONTEXT_VALID_RAX, &MDRawContextAMD64::rax }, - { "$rdx", NULL, false, - StackFrameAMD64::CONTEXT_VALID_RDX, &MDRawContextAMD64::rdx }, - { "$rcx", NULL, false, - StackFrameAMD64::CONTEXT_VALID_RCX, &MDRawContextAMD64::rcx }, - { "$rbx", NULL, true, - StackFrameAMD64::CONTEXT_VALID_RBX, &MDRawContextAMD64::rbx }, - { "$rsi", NULL, false, - StackFrameAMD64::CONTEXT_VALID_RSI, &MDRawContextAMD64::rsi }, - { "$rdi", NULL, false, - StackFrameAMD64::CONTEXT_VALID_RDI, &MDRawContextAMD64::rdi }, - { "$rbp", NULL, true, - StackFrameAMD64::CONTEXT_VALID_RBP, &MDRawContextAMD64::rbp }, - { "$rsp", ".cfa", false, - StackFrameAMD64::CONTEXT_VALID_RSP, &MDRawContextAMD64::rsp }, - { "$r8", NULL, false, - StackFrameAMD64::CONTEXT_VALID_R8, &MDRawContextAMD64::r8 }, - { "$r9", NULL, false, - StackFrameAMD64::CONTEXT_VALID_R9, &MDRawContextAMD64::r9 }, - { "$r10", NULL, false, - StackFrameAMD64::CONTEXT_VALID_R10, &MDRawContextAMD64::r10 }, - { "$r11", NULL, false, - StackFrameAMD64::CONTEXT_VALID_R11, &MDRawContextAMD64::r11 }, - { "$r12", NULL, true, - StackFrameAMD64::CONTEXT_VALID_R12, &MDRawContextAMD64::r12 }, - { "$r13", NULL, true, - StackFrameAMD64::CONTEXT_VALID_R13, &MDRawContextAMD64::r13 }, - { "$r14", NULL, true, - StackFrameAMD64::CONTEXT_VALID_R14, &MDRawContextAMD64::r14 }, - { "$r15", NULL, true, - StackFrameAMD64::CONTEXT_VALID_R15, &MDRawContextAMD64::r15 }, - { "$rip", ".ra", false, - StackFrameAMD64::CONTEXT_VALID_RIP, &MDRawContextAMD64::rip }, -}; - -StackwalkerAMD64::StackwalkerAMD64(const SystemInfo* system_info, - const MDRawContextAMD64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context), - cfi_walker_(cfi_register_map_, - (sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) { -} - -uint64_t StackFrameAMD64::ReturnAddress() const { - assert(context_validity & StackFrameAMD64::CONTEXT_VALID_RIP); - return context.rip; -} - -StackFrame* StackwalkerAMD64::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFrameAMD64* frame = new StackFrameAMD64(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFrameAMD64::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.rip; - - return frame; -} - -StackFrameAMD64* StackwalkerAMD64::GetCallerByCFIFrameInfo( - const vector &frames, - CFIFrameInfo* cfi_frame_info) { - StackFrameAMD64* last_frame = static_cast(frames.back()); - - scoped_ptr frame(new StackFrameAMD64()); - if (!cfi_walker_ - .FindCallerRegisters(*memory_, *cfi_frame_info, - last_frame->context, last_frame->context_validity, - &frame->context, &frame->context_validity)) - return NULL; - - // Make sure we recovered all the essentials. - static const int essentials = (StackFrameAMD64::CONTEXT_VALID_RIP - | StackFrameAMD64::CONTEXT_VALID_RSP); - if ((frame->context_validity & essentials) != essentials) - return NULL; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - return frame.release(); -} - -bool StackwalkerAMD64::IsEndOfStack(uint64_t caller_rip, uint64_t caller_rsp, - uint64_t callee_rsp) { - // Treat an instruction address of 0 as end-of-stack. - if (caller_rip == 0) { - return true; - } - - // If the new stack pointer is at a lower address than the old, then - // that's clearly incorrect. Treat this as end-of-stack to enforce - // progress and avoid infinite loops. - if (caller_rsp < callee_rsp) { - return true; - } - - return false; -} - -// Returns true if `ptr` is not in x86-64 canonical form. -// https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details -static bool is_non_canonical(uint64_t ptr) { - return ptr > 0x7FFFFFFFFFFF && ptr < 0xFFFF800000000000; -} - -StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery( - const vector& frames) { - StackFrameAMD64* last_frame = static_cast(frames.back()); - uint64_t last_rsp = last_frame->context.rsp; - uint64_t last_rbp = last_frame->context.rbp; - - // Assume the presence of a frame pointer. This is not mandated by the - // AMD64 ABI, c.f. section 3.2.2 footnote 7, though it is typical for - // compilers to still preserve the frame pointer and not treat %rbp as a - // general purpose register. - // - // With this assumption, the CALL instruction pushes the return address - // onto the stack and sets %rip to the procedure to enter. The procedure - // then establishes the stack frame with a prologue that PUSHes the current - // %rbp onto the stack, MOVes the current %rsp to %rbp, and then allocates - // space for any local variables. Using this procedure linking information, - // it is possible to locate frame information for the callee: - // - // %caller_rsp = *(%callee_rbp + 16) - // %caller_rip = *(%callee_rbp + 8) - // %caller_rbp = *(%callee_rbp) - - // If rbp is not 8-byte aligned it can't be a frame pointer. - if (last_rbp % 8 != 0) { - return NULL; - } - - uint64_t caller_rip, caller_rbp; - if (memory_->GetMemoryAtAddress(last_rbp + 8, &caller_rip) && - memory_->GetMemoryAtAddress(last_rbp, &caller_rbp)) { - uint64_t caller_rsp = last_rbp + 16; - - // If the recovered rip is not a canonical address it can't be - // the return address, so rbp must not have been a frame pointer. - if (is_non_canonical(caller_rip)) { - return NULL; - } - - // Simple sanity check that the stack is growing downwards as expected. - if (IsEndOfStack(caller_rip, caller_rsp, last_rsp) || - caller_rbp < last_rbp) { - // Reached end-of-stack or stack is not growing downwards. - return NULL; - } - - StackFrameAMD64* frame = new StackFrameAMD64(); - frame->trust = StackFrame::FRAME_TRUST_FP; - frame->context = last_frame->context; - frame->context.rip = caller_rip; - frame->context.rsp = caller_rsp; - frame->context.rbp = caller_rbp; - frame->context_validity = StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP; - return frame; - } - - return NULL; -} - -StackFrameAMD64* StackwalkerAMD64::GetCallerByStackScan( - const vector &frames) { - StackFrameAMD64* last_frame = static_cast(frames.back()); - uint64_t last_rsp = last_frame->context.rsp; - uint64_t caller_rip_address, caller_rip; - - if (!ScanForReturnAddress(last_rsp, &caller_rip_address, &caller_rip, - frames.size() == 1 /* is_context_frame */)) { - // No plausible return address was found. - return NULL; - } - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameAMD64* frame = new StackFrameAMD64(); - - frame->trust = StackFrame::FRAME_TRUST_SCAN; - frame->context = last_frame->context; - frame->context.rip = caller_rip; - // The caller's %rsp is directly underneath the return address pushed by - // the call. - frame->context.rsp = caller_rip_address + 8; - frame->context_validity = StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP; - - // Other unwinders give up if they don't have an %rbp value, so see if we - // can pass some plausible value on. - if (last_frame->context_validity & StackFrameAMD64::CONTEXT_VALID_RBP) { - // Functions typically push their caller's %rbp immediately upon entry, - // and then set %rbp to point to that. So if the callee's %rbp is - // pointing to the first word below the alleged return address, presume - // that the caller's %rbp is saved there. - if (caller_rip_address - 8 == last_frame->context.rbp) { - uint64_t caller_rbp = 0; - if (memory_->GetMemoryAtAddress(last_frame->context.rbp, &caller_rbp) && - caller_rbp > caller_rip_address) { - frame->context.rbp = caller_rbp; - frame->context_validity |= StackFrameAMD64::CONTEXT_VALID_RBP; - } - } else if (last_frame->context.rbp >= caller_rip_address + 8) { - // If the callee's %rbp is plausible as a value for the caller's - // %rbp, presume that the callee left it unchanged. - frame->context.rbp = last_frame->context.rbp; - frame->context_validity |= StackFrameAMD64::CONTEXT_VALID_RBP; - } - } - - return frame; -} - -StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - const vector &frames = *stack->frames(); - StackFrameAMD64* last_frame = static_cast(frames.back()); - scoped_ptr new_frame; - - // If we have DWARF CFI information, use it. - scoped_ptr cfi_frame_info( - frame_symbolizer_->FindCFIFrameInfo(last_frame)); - if (cfi_frame_info.get()) - new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); - - // If CFI was not available or failed, try using frame pointer recovery. - if (!new_frame.get()) { - new_frame.reset(GetCallerByFramePointerRecovery(frames)); - } - - // If all else fails, fall back to stack scanning. - if (stack_scan_allowed && !new_frame.get()) { - new_frame.reset(GetCallerByStackScan(frames)); - } - - // If nothing worked, tell the caller. - if (!new_frame.get()) - return NULL; - - if (system_info_->os_short == "nacl") { - // Apply constraints from Native Client's x86-64 sandbox. These - // registers have the 4GB-aligned sandbox base address (from r15) - // added to them, and only the bottom 32 bits are relevant for - // stack walking. - new_frame->context.rip = static_cast(new_frame->context.rip); - new_frame->context.rsp = static_cast(new_frame->context.rsp); - new_frame->context.rbp = static_cast(new_frame->context.rbp); - } - - if (IsEndOfStack(new_frame->context.rip, new_frame->context.rsp, - last_frame->context.rsp)) { - // Reached end-of-stack. - return NULL; - } - - // new_frame->context.rip is the return address, which is the instruction - // after the CALL that caused us to arrive at the callee. Set - // new_frame->instruction to one less than that, so it points within the - // CALL instruction. See StackFrame::instruction for details, and - // StackFrameAMD64::ReturnAddress. - new_frame->instruction = new_frame->context.rip - 1; - - return new_frame.release(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h deleted file mode 100644 index 67c455104..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_amd64.h: amd64-specific stackwalker. -// -// Provides stack frames given amd64 register context and a memory region -// corresponding to a amd64 stack. -// -// Author: Mark Mentovai, Ted Mielczarek - - -#ifndef PROCESSOR_STACKWALKER_AMD64_H__ -#define PROCESSOR_STACKWALKER_AMD64_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerAMD64 : public Stackwalker { - public: - // context is a amd64 context object that gives access to amd64-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerAMD64(const SystemInfo* system_info, - const MDRawContextAMD64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // A STACK CFI-driven frame walker for the AMD64 - typedef SimpleCFIWalker CFIWalker; - - // Implementation of Stackwalker, using amd64 context (stack pointer in %rsp, - // stack base in %rbp) and stack conventions (saved stack pointer at 0(%rbp)) - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Use cfi_frame_info (derived from STACK CFI records) to construct - // the frame that called frames.back(). The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameAMD64* GetCallerByCFIFrameInfo(const vector &frames, - CFIFrameInfo* cfi_frame_info); - - // Checks whether end-of-stack is reached. An instruction address of 0 is an - // end-of-stack marker. If the stack pointer of the caller is at a lower - // address than the stack pointer of the callee, then that's clearly incorrect - // and it is treated as end-of-stack to enforce progress and avoid infinite - // loops. - bool IsEndOfStack(uint64_t caller_rip, uint64_t caller_rsp, - uint64_t callee_rsp); - - // Assumes a traditional frame layout where the frame pointer has not been - // omitted. The expectation is that caller's %rbp is pushed to the stack - // after the return address of the callee, and that the callee's %rsp can - // be used to find the pushed %rbp. - // Caller owns the returned frame object. Returns NULL on failure. - StackFrameAMD64* GetCallerByFramePointerRecovery( - const vector& frames); - - // Scan the stack for plausible return addresses. The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameAMD64* GetCallerByStackScan(const vector &frames); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextAMD64* context_; - - // Our register map, for cfi_walker_. - static const CFIWalker::RegisterSet cfi_register_map_[]; - - // Our CFI frame walker. - const CFIWalker cfi_walker_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_AMD64_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64_unittest.cc deleted file mode 100644 index 935bef866..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64_unittest.cc +++ /dev/null @@ -1,932 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stackwalker_amd64_unittest.cc: Unit tests for StackwalkerAMD64 class. - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_amd64.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::StackFrameAMD64; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerAMD64; -using google_breakpad::SystemInfo; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class StackwalkerAMD64Fixture { - public: - StackwalkerAMD64Fixture() - : stack_section(kLittleEndian), - // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(0x00007400c0000000ULL, 0x10000, "module1", "version1"), - module2(0x00007500b0000000ULL, 0x10000, "module2", "version2") { - // Identify the system as a Linux system. - system_info.os = "Linux"; - system_info.os_short = "linux"; - system_info.os_version = "Horrendous Hippo"; - system_info.cpu = "x86"; - system_info.cpu_info = ""; - - // Put distinctive values in the raw CPU context. - BrandContext(&raw_context); - - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - - // Reset max_frames_scanned since it's static. - Stackwalker::set_max_frames_scanned(1024); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule *module, const string &info) { - size_t buffer_size; - char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - // Populate stack_region with the contents of stack_section. Use - // stack_section.start() as the region's starting address. - void RegionFromSection() { - string contents; - ASSERT_TRUE(stack_section.GetContents(&contents)); - stack_region.Init(stack_section.start().Value(), contents); - } - - // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. - void BrandContext(MDRawContextAMD64 *raw_context) { - uint8_t x = 173; - for (size_t i = 0; i < sizeof(*raw_context); i++) - reinterpret_cast(raw_context)[i] = (x += 17); - } - - SystemInfo system_info; - MDRawContextAMD64 raw_context; - Section stack_section; - MockMemoryRegion stack_region; - MockCodeModule module1; - MockCodeModule module2; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - CallStack call_stack; - const vector *frames; -}; - -class GetContextFrame: public StackwalkerAMD64Fixture, public Test { }; - -class SanityCheck: public StackwalkerAMD64Fixture, public Test { }; - -TEST_F(SanityCheck, NoResolver) { - // There should be no references to the stack in this walk: we don't - // provide any call frame information, so trying to reconstruct the - // context frame's caller should fail. So there's no need for us to - // provide stack contents. - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = 0x8000000080000000ULL; - - StackFrameSymbolizer frame_symbolizer(NULL, NULL); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - // This should succeed even without a resolver or supplier. - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_GE(1U, frames->size()); - StackFrameAMD64 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -TEST_F(GetContextFrame, Simple) { - // There should be no references to the stack in this walk: we don't - // provide any call frame information, so trying to reconstruct the - // context frame's caller should fail. So there's no need for us to - // provide stack contents. - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = 0x8000000080000000ULL; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_GE(1U, frames->size()); - StackFrameAMD64 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -// The stackwalker should be able to produce the context frame even -// without stack memory present. -TEST_F(GetContextFrame, NoStackMemory) { - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = 0x8000000080000000ULL; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_GE(1U, frames->size()); - StackFrameAMD64 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetCallerFrame: public StackwalkerAMD64Fixture, public Test { }; - -TEST_F(GetCallerFrame, ScanWithoutSymbols) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - // Force scanning through three frames to ensure that the - // stack pointer is set properly in scan-recovered frames. - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address1 = 0x00007500b0000100ULL; - uint64_t return_address2 = 0x00007500b0000900ULL; - Label frame1_sp, frame2_sp, frame1_rbp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // junk that's not - .D64(0x00007500d0000000ULL) // a return address - - .D64(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // more junk - .D64(0x00007500d0000000ULL) - - .Mark(&frame1_rbp) - .D64(stack_section.start()) // This is in the right place to be - // a saved rbp, but it's bogus, so - // we shouldn't report it. - - .D64(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame1_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.rip); - EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); - EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); - - StackFrameAMD64 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.rip); - EXPECT_EQ(frame2_sp.Value(), frame2->context.rsp); -} - -TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { - // During stack scanning, if a potential return address - // is located within a loaded module that has symbols, - // it is only considered a valid return address if it - // lies within a function's bounds. - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address = 0x00007500b0000110ULL; - Label frame1_sp, frame1_rbp; - - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // junk that's not - .D64(0x00007500b0000000ULL) // a return address - - .D64(0x00007400c0001000ULL) // a couple of plausible addresses - .D64(0x00007500b000aaaaULL) // that are not within functions - - .D64(return_address) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0) // end of stack - .Mark(&frame1_rbp); - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame1_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 100 400 10 platypus\n"); - SetModuleSymbols(&module2, - // The calling frame's function. - "FUNC 100 400 10 echidna\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ("platypus", frame0->function_name); - EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP), - frame1->context_validity); - EXPECT_EQ(return_address, frame1->context.rip); - EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); - EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); - EXPECT_EQ("echidna", frame1->function_name); - EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base); -} - -// StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an -// instruction pointer of 0 because IP of 0 is an end of stack marker and the -// stack walk may be terminated prematurely. Instead it should return NULL -// so that the stack walking code can proceed to stack scanning. -TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) { - MockCodeModule user32_dll(0x00007ff9cb8a0000ULL, 0x14E000, "user32.dll", - "version1"); - SetModuleSymbols(&user32_dll, // user32.dll - "PUBLIC fa60 0 DispatchMessageWorker\n" - "PUBLIC fee0 0 UserCallWinProcCheckWow\n" - "PUBLIC 1cdb0 0 _fnHkINLPMSG\n" - "STACK CFI INIT fa60 340 .cfa: $rsp .ra: .cfa 8 - ^\n" - "STACK CFI fa60 .cfa: $rsp 128 +\n" - "STACK CFI INIT fee0 49f .cfa: $rsp .ra: .cfa 8 - ^\n" - "STACK CFI fee0 .cfa: $rsp 240 +\n" - "STACK CFI INIT 1cdb0 9f .cfa: $rsp .ra: .cfa 8 - ^\n" - "STACK CFI 1cdb0 .cfa: $rsp 80 +\n"); - - // Create some modules with some stock debugging information. - MockCodeModules local_modules; - local_modules.Add(&user32_dll); - - Label frame0_rsp; - Label frame0_rbp; - Label frame1_rsp; - Label frame2_rsp; - - stack_section.start() = 0x00000099abf0f238ULL; - stack_section - .Mark(&frame0_rsp) - .D64(0x00007ff9cb8b00dcULL) - .Mark(&frame1_rsp) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000001ULL) - .D64(0x00000099abf0f308ULL) - .D64(0x00007ff9cb8bce3aULL) // Stack residue from execution of - // user32!_fnHkINLPMSG+0x8a - .D64(0x000000000000c2e0ULL) - .D64(0x00000099abf0f328ULL) - .D64(0x0000000100000001ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x00007ff9ccad53e4ULL) - .D64(0x0000000000000048ULL) - .D64(0x0000000000000001ULL) - .D64(0x00000099abf0f5e0ULL) - .D64(0x00000099b61f7388ULL) - .D64(0x0000000000000030ULL) - .D64(0xffffff66540f0a1fULL) - .D64(0xffffff6649e08c77ULL) - .D64(0x00007ff9cb8affb4ULL) // Return address in - // user32!UserCallWinProcCheckWow+0xd4 - .D64(0x0000000000000000ULL) - .D64(0x00000099abf0f368ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x0000000000000000ULL) - .D64(0x00000099a8150fd8ULL) - .D64(0x00000099abf0f3e8ULL) - .D64(0x00007ff9cb8afc07ULL) // Return address in - // user32!DispatchMessageWorker+0x1a7 - .Mark(&frame2_rsp) - .Append(256, 0) - .Mark(&frame0_rbp) // The following are expected by - // GetCallerByFramePointerRecovery. - .D64(0xfffffffffffffffeULL) // %caller_rbp = *(%callee_rbp) - .D64(0x0000000000000000ULL) // %caller_rip = *(%callee_rbp + 8) - .D64(0x00000099a3e31040ULL) // %caller_rsp = *(%callee_rbp + 16) - .Append(256, 0); - - RegionFromSection(); - raw_context.rip = 0x00000099a8150fd8ULL; // IP in context frame is guarbage - raw_context.rsp = frame0_rsp.Value(); - raw_context.rbp = frame0_rbp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, - &local_modules, &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - - ASSERT_EQ(3U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameAMD64 *frame = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame->context_validity); - EXPECT_EQ("", frame->function_name); - EXPECT_EQ(0x00000099a8150fd8ULL, frame->instruction); - EXPECT_EQ(0x00000099a8150fd8ULL, frame->context.rip); - EXPECT_EQ(frame0_rsp.Value(), frame->context.rsp); - EXPECT_EQ(frame0_rbp.Value(), frame->context.rbp); - } - - { // To avoid reusing locals by mistake - StackFrameAMD64 *frame = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP), - frame->context_validity); - EXPECT_EQ("UserCallWinProcCheckWow", frame->function_name); - EXPECT_EQ(140710838468828ULL, frame->instruction + 1); - EXPECT_EQ(140710838468828ULL, frame->context.rip); - EXPECT_EQ(frame1_rsp.Value(), frame->context.rsp); - EXPECT_EQ(&user32_dll, frame->module); - } - - { // To avoid reusing locals by mistake - StackFrameAMD64 *frame = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP), - frame->context_validity); - EXPECT_EQ("DispatchMessageWorker", frame->function_name); - EXPECT_EQ(140710838467591ULL, frame->instruction + 1); - EXPECT_EQ(140710838467591ULL, frame->context.rip); - EXPECT_EQ(frame2_rsp.Value(), frame->context.rsp); - EXPECT_EQ(&user32_dll, frame->module); - } -} - -// Don't use frame pointer recovery if %rbp is not 8-byte aligned, which -// indicates that it's not being used as a frame pointer. -TEST_F(GetCallerFrame, FramePointerNotAligned) { - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address1 = 0x00007500b0000100ULL; - Label frame0_rbp, not_frame1_rbp, frame1_sp; - stack_section - // frame 0 - .Align(8, 0) - .Append(2, 0) // mis-align the frame pointer - .Mark(&frame0_rbp) - .D64(not_frame1_rbp) // not the previous frame pointer - .D64(0x00007500b0000a00ULL) // plausible but wrong return address - .Align(8, 0) - .D64(return_address1) // return address - // frame 1 - .Mark(&frame1_sp) - .Mark(¬_frame1_rbp) - .Append(32, 0); // end of stack - - - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame0_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.rip); - EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); -} - -// Don't use frame pointer recovery if the recovered %rip is not -// a canonical x86-64 address. -TEST_F(GetCallerFrame, NonCanonicalInstructionPointerFromFramePointer) { - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address1 = 0x00007500b0000100ULL; - Label frame0_rbp, frame1_sp, not_frame1_bp; - stack_section - // frame 0 - .Align(8, 0) - .Mark(&frame0_rbp) - .D64(not_frame1_bp) // some junk on the stack - .D64(0xDADADADADADADADA) // not the return address - .D64(return_address1) // return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) - .Mark(¬_frame1_bp) - .Append(32, 0); // end of stack - - - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame0_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.rip); - EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); -} - -// Test that set_max_frames_scanned prevents using stack scanning -// to find caller frames. -TEST_F(GetCallerFrame, ScanningNotAllowed) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address1 = 0x00007500b0000100ULL; - uint64_t return_address2 = 0x00007500b0000900ULL; - Label frame1_sp, frame2_sp, frame1_rbp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // junk that's not - .D64(0x00007500d0000000ULL) // a return address - - .D64(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // more junk - .D64(0x00007500d0000000ULL) - - .Mark(&frame1_rbp) - .D64(stack_section.start()) // This is in the right place to be - // a saved rbp, but it's bogus, so - // we shouldn't report it. - - .D64(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame1_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - Stackwalker::set_max_frames_scanned(0); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); -} - -TEST_F(GetCallerFrame, CallerPushedRBP) { - // Functions typically push their %rbp upon entry and set %rbp pointing - // there. If stackwalking finds a plausible address for the next frame's - // %rbp directly below the return address, assume that it is indeed the - // next frame's %rbp. - stack_section.start() = 0x8000000080000000ULL; - uint64_t return_address = 0x00007500b0000110ULL; - Label frame0_rbp, frame1_sp, frame1_rbp; - - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x00007400b0000000ULL) // junk that's not - .D64(0x00007500b0000000ULL) // a return address - - .D64(0x00007400c0001000ULL) // a couple of plausible addresses - .D64(0x00007500b000aaaaULL) // that are not within functions - - .Mark(&frame0_rbp) - .D64(frame1_rbp) // caller-pushed %rbp - .D64(return_address) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0) // body of frame1 - .Mark(&frame1_rbp); // end of stack - RegionFromSection(); - - raw_context.rip = 0x00007400c0000200ULL; - raw_context.rbp = frame0_rbp.Value(); - raw_context.rsp = stack_section.start().Value(); - - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 100 400 10 sasquatch\n"); - SetModuleSymbols(&module2, - // The calling frame's function. - "FUNC 100 400 10 yeti\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(frame0_rbp.Value(), frame0->context.rbp); - EXPECT_EQ("sasquatch", frame0->function_name); - EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP), - frame1->context_validity); - EXPECT_EQ(return_address, frame1->context.rip); - EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); - EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); - EXPECT_EQ("yeti", frame1->function_name); - EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base); -} - -struct CFIFixture: public StackwalkerAMD64Fixture { - CFIFixture() { - // Provide a bunch of STACK CFI records; we'll walk to the caller - // from every point in this series, expecting to find the same set - // of register values. - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 4000 1000 10 enchiridion\n" - // Initially, just a return address. - "STACK CFI INIT 4000 100 .cfa: $rsp 8 + .ra: .cfa 8 - ^\n" - // Push %rbx. - "STACK CFI 4001 .cfa: $rsp 16 + $rbx: .cfa 16 - ^\n" - // Save %r12 in %rbx. Weird, but permitted. - "STACK CFI 4002 $r12: $rbx\n" - // Allocate frame space, and save %r13. - "STACK CFI 4003 .cfa: $rsp 40 + $r13: .cfa 32 - ^\n" - // Put the return address in %r13. - "STACK CFI 4005 .ra: $r13\n" - // Save %rbp, and use it as a frame pointer. - "STACK CFI 4006 .cfa: $rbp 16 + $rbp: .cfa 24 - ^\n" - - // The calling function. - "FUNC 5000 1000 10 epictetus\n" - // Mark it as end of stack. - "STACK CFI INIT 5000 1000 .cfa: $rsp .ra 0\n"); - - // Provide some distinctive values for the caller's registers. - expected.rsp = 0x8000000080000000ULL; - expected.rip = 0x00007400c0005510ULL; - expected.rbp = 0x68995b1de4700266ULL; - expected.rbx = 0x5a5beeb38de23be8ULL; - expected.r12 = 0xed1b02e8cc0fc79cULL; - expected.r13 = 0x1d20ad8acacbe930ULL; - expected.r14 = 0xe94cffc2f7adaa28ULL; - expected.r15 = 0xb638d17d8da413b5ULL; - - // By default, registers are unchanged. - raw_context = expected; - } - - // Walk the stack, using stack_section as the contents of the stack - // and raw_context as the current register values. (Set - // raw_context.rsp to the stack's starting address.) Expect two - // stack frames; in the older frame, expect the callee-saves - // registers to have values matching those in 'expected'. - void CheckWalk() { - RegionFromSection(); - raw_context.rsp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameAMD64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ("enchiridion", frame0->function_name); - EXPECT_EQ(0x00007400c0004000ULL, frame0->function_base); - - StackFrameAMD64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | - StackFrameAMD64::CONTEXT_VALID_RSP | - StackFrameAMD64::CONTEXT_VALID_RBP | - StackFrameAMD64::CONTEXT_VALID_RBX | - StackFrameAMD64::CONTEXT_VALID_R12 | - StackFrameAMD64::CONTEXT_VALID_R13 | - StackFrameAMD64::CONTEXT_VALID_R14 | - StackFrameAMD64::CONTEXT_VALID_R15), - frame1->context_validity); - EXPECT_EQ(expected.rip, frame1->context.rip); - EXPECT_EQ(expected.rsp, frame1->context.rsp); - EXPECT_EQ(expected.rbp, frame1->context.rbp); - EXPECT_EQ(expected.rbx, frame1->context.rbx); - EXPECT_EQ(expected.r12, frame1->context.r12); - EXPECT_EQ(expected.r13, frame1->context.r13); - EXPECT_EQ(expected.r14, frame1->context.r14); - EXPECT_EQ(expected.r15, frame1->context.r15); - EXPECT_EQ("epictetus", frame1->function_name); - } - - // The values we expect to find for the caller's registers. - MDRawContextAMD64 expected; -}; - -class CFI: public CFIFixture, public Test { }; - -TEST_F(CFI, At4000) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x00007400c0005510ULL) // return address - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004000ULL; - CheckWalk(); -} - -TEST_F(CFI, At4001) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0x00007400c0005510ULL) // return address - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004001ULL; - raw_context.rbx = 0xbe0487d2f9eafe29ULL; // callee's (distinct) %rbx value - CheckWalk(); -} - -TEST_F(CFI, At4002) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0x00007400c0005510ULL) // return address - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004002ULL; - raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 - raw_context.r12 = 0xb0118de918a4bceaULL; // callee's (distinct) %r12 value - CheckWalk(); -} - -TEST_F(CFI, At4003) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x0e023828dffd4d81ULL) // garbage - .D64(0x1d20ad8acacbe930ULL) // saved %r13 - .D64(0x319e68b49e3ace0fULL) // garbage - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0x00007400c0005510ULL) // return address - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004003ULL; - raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 - raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12 - raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13 - CheckWalk(); -} - -// The results here should be the same as those at module offset 0x4003. -TEST_F(CFI, At4004) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x0e023828dffd4d81ULL) // garbage - .D64(0x1d20ad8acacbe930ULL) // saved %r13 - .D64(0x319e68b49e3ace0fULL) // garbage - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0x00007400c0005510ULL) // return address - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004004ULL; - raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 - raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12 - raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13 - CheckWalk(); -} - -TEST_F(CFI, At4005) { - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x4b516dd035745953ULL) // garbage - .D64(0x1d20ad8acacbe930ULL) // saved %r13 - .D64(0xa6d445e16ae3d872ULL) // garbage - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0xaa95fa054aedfbaeULL) // garbage - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004005ULL; - raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 - raw_context.r12 = 0x46b1b8868891b34aULL; // callee's %r12 - raw_context.r13 = 0x00007400c0005510ULL; // return address - CheckWalk(); -} - -TEST_F(CFI, At4006) { - Label frame0_rbp; - Label frame1_rsp = expected.rsp; - stack_section - .D64(0x043c6dfceb91aa34ULL) // garbage - .D64(0x1d20ad8acacbe930ULL) // saved %r13 - .D64(0x68995b1de4700266ULL) // saved %rbp - .Mark(&frame0_rbp) // frame pointer points here - .D64(0x5a5beeb38de23be8ULL) // saved %rbx - .D64(0xf015ee516ad89eabULL) // garbage - .Mark(&frame1_rsp); // This effectively sets stack_section.start(). - raw_context.rip = 0x00007400c0004006ULL; - raw_context.rbp = frame0_rbp.Value(); - raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 - raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12 - raw_context.r13 = 0x00007400c0005510ULL; // return address - CheckWalk(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.cc deleted file mode 100644 index e4fc58697..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.cc +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_arm.cc: arm-specific stackwalker. -// -// See stackwalker_arm.h for documentation. -// -// Author: Mark Mentovai, Ted Mielczarek, Jim Blandy - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" -#include "processor/logging.h" -#include "processor/stackwalker_arm.h" - -namespace google_breakpad { - - -StackwalkerARM::StackwalkerARM(const SystemInfo* system_info, - const MDRawContextARM* context, - int fp_register, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context), fp_register_(fp_register), - context_frame_validity_(StackFrameARM::CONTEXT_VALID_ALL) { } - - -StackFrame* StackwalkerARM::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFrameARM* frame = new StackFrameARM(); - - // The instruction pointer is stored directly in a register (r15), so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = context_frame_validity_; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.iregs[MD_CONTEXT_ARM_REG_PC]; - - return frame; -} - -StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( - const vector &frames, - CFIFrameInfo* cfi_frame_info) { - StackFrameARM* last_frame = static_cast(frames.back()); - - static const char* register_names[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "fps", "cpsr", - NULL - }; - - // Populate a dictionary with the valid register values in last_frame. - CFIFrameInfo::RegisterValueMap callee_registers; - for (int i = 0; register_names[i]; i++) - if (last_frame->context_validity & StackFrameARM::RegisterValidFlag(i)) - callee_registers[register_names[i]] = last_frame->context.iregs[i]; - - // Use the STACK CFI data to recover the caller's register values. - CFIFrameInfo::RegisterValueMap caller_registers; - if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, - &caller_registers)) - return NULL; - - // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameARM()); - for (int i = 0; register_names[i]; i++) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(register_names[i]); - if (entry != caller_registers.end()) { - // We recovered the value of this register; fill the context with the - // value from caller_registers. - frame->context_validity |= StackFrameARM::RegisterValidFlag(i); - frame->context.iregs[i] = entry->second; - } else if (4 <= i && i <= 11 && (last_frame->context_validity & - StackFrameARM::RegisterValidFlag(i))) { - // If the STACK CFI data doesn't mention some callee-saves register, and - // it is valid in the callee, assume the callee has not yet changed it. - // Registers r4 through r11 are callee-saves, according to the Procedure - // Call Standard for the ARM Architecture, which the Linux ABI follows. - frame->context_validity |= StackFrameARM::RegisterValidFlag(i); - frame->context.iregs[i] = last_frame->context.iregs[i]; - } - } - // If the CFI doesn't recover the PC explicitly, then use .ra. - if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(".ra"); - if (entry != caller_registers.end()) { - if (fp_register_ == -1) { - frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; - frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = entry->second; - } else { - // The CFI updated the link register and not the program counter. - // Handle getting the program counter from the link register. - frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; - frame->context_validity |= StackFrameARM::CONTEXT_VALID_LR; - frame->context.iregs[MD_CONTEXT_ARM_REG_LR] = entry->second; - frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = - last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR]; - } - } - } - // If the CFI doesn't recover the SP explicitly, then use .cfa. - if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(".cfa"); - if (entry != caller_registers.end()) { - frame->context_validity |= StackFrameARM::CONTEXT_VALID_SP; - frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = entry->second; - } - } - - // If we didn't recover the PC and the SP, then the frame isn't very useful. - static const int essentials = (StackFrameARM::CONTEXT_VALID_SP - | StackFrameARM::CONTEXT_VALID_PC); - if ((frame->context_validity & essentials) != essentials) - return NULL; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - return frame.release(); -} - -StackFrameARM* StackwalkerARM::GetCallerByStackScan( - const vector &frames) { - StackFrameARM* last_frame = static_cast(frames.back()); - uint32_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; - uint32_t caller_sp, caller_pc; - - if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, - frames.size() == 1 /* is_context_frame */)) { - // No plausible return address was found. - return NULL; - } - - // ScanForReturnAddress found a reasonable return address. Advance - // %sp to the location above the one where the return address was - // found. - caller_sp += 4; - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameARM* frame = new StackFrameARM(); - - frame->trust = StackFrame::FRAME_TRUST_SCAN; - frame->context = last_frame->context; - frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = caller_pc; - frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = caller_sp; - frame->context_validity = StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP; - - return frame; -} - -StackFrameARM* StackwalkerARM::GetCallerByFramePointer( - const vector &frames) { - StackFrameARM* last_frame = static_cast(frames.back()); - - if (!(last_frame->context_validity & - StackFrameARM::RegisterValidFlag(fp_register_))) { - return NULL; - } - - uint32_t last_fp = last_frame->context.iregs[fp_register_]; - - uint32_t caller_fp = 0; - if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { - BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" - << std::hex << last_fp; - return NULL; - } - - uint32_t caller_lr = 0; - if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_lr)) { - BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 4: 0x" - << std::hex << (last_fp + 4); - return NULL; - } - - uint32_t caller_sp = last_fp ? last_fp + 8 : - last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]; - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameARM* frame = new StackFrameARM(); - - frame->trust = StackFrame::FRAME_TRUST_FP; - frame->context = last_frame->context; - frame->context.iregs[fp_register_] = caller_fp; - frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = caller_sp; - frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = - last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR]; - frame->context.iregs[MD_CONTEXT_ARM_REG_LR] = caller_lr; - frame->context_validity = StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_LR | - StackFrameARM::RegisterValidFlag(fp_register_) | - StackFrameARM::CONTEXT_VALID_SP; - return frame; -} - -StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - const vector &frames = *stack->frames(); - StackFrameARM* last_frame = static_cast(frames.back()); - scoped_ptr frame; - - // See if there is DWARF call frame information covering this address. - scoped_ptr cfi_frame_info( - frame_symbolizer_->FindCFIFrameInfo(last_frame)); - if (cfi_frame_info.get()) - frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); - - // If CFI failed, or there wasn't CFI available, fall back - // to frame pointer, if this is configured. - if (fp_register_ >= 0 && !frame.get()) - frame.reset(GetCallerByFramePointer(frames)); - - // If everuthing failed, fall back to stack scanning. - if (stack_scan_allowed && !frame.get()) - frame.reset(GetCallerByStackScan(frames)); - - // If nothing worked, tell the caller. - if (!frame.get()) - return NULL; - - - // An instruction address of zero marks the end of the stack. - if (frame->context.iregs[MD_CONTEXT_ARM_REG_PC] == 0) - return NULL; - - // If the new stack pointer is at a lower address than the old, then - // that's clearly incorrect. Treat this as end-of-stack to enforce - // progress and avoid infinite loops. - if (frame->context.iregs[MD_CONTEXT_ARM_REG_SP] - < last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP]) - return NULL; - - // The new frame's context's PC is the return address, which is one - // instruction past the instruction that caused us to arrive at the - // callee. Set new_frame->instruction to one less than the PC. This won't - // reference the beginning of the call instruction, but it's at least - // within it, which is sufficient to get the source line information to - // match up with the line that contains the function call. Callers that - // require the exact return address value may access - // frame->context.iregs[MD_CONTEXT_ARM_REG_PC]. - frame->instruction = frame->context.iregs[MD_CONTEXT_ARM_REG_PC] - 2; - - return frame.release(); -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h deleted file mode 100644 index 9081a40cd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h +++ /dev/null @@ -1,107 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_arm.h: arm-specific stackwalker. -// -// Provides stack frames given arm register context and a memory region -// corresponding to an arm stack. -// -// Author: Mark Mentovai, Ted Mielczarek - - -#ifndef PROCESSOR_STACKWALKER_ARM_H__ -#define PROCESSOR_STACKWALKER_ARM_H__ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerARM : public Stackwalker { - public: - // context is an arm context object that gives access to arm-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerARM(const SystemInfo* system_info, - const MDRawContextARM* context, - int fp_register, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - // Change the context validity mask of the frame returned by - // GetContextFrame to VALID. This is only for use by unit tests; the - // default behavior is correct for all application code. - void SetContextFrameValidity(int valid) { context_frame_validity_ = valid; } - - private: - // Implementation of Stackwalker, using arm context and stack conventions. - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Use cfi_frame_info (derived from STACK CFI records) to construct - // the frame that called frames.back(). The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameARM* GetCallerByCFIFrameInfo(const vector &frames, - CFIFrameInfo* cfi_frame_info); - - // Use the frame pointer. The caller takes ownership of the returned frame. - // Return NULL on failure. - StackFrameARM* GetCallerByFramePointer(const vector &frames); - - // Scan the stack for plausible return addresses. The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameARM* GetCallerByStackScan(const vector &frames); - - // Stores the CPU context corresponding to the youngest stack frame, to - // be returned by GetContextFrame. - const MDRawContextARM* context_; - - // The register to use a as frame pointer. The value is -1 if frame pointer - // cannot be used. - int fp_register_; - - // Validity mask for youngest stack frame. This is always - // CONTEXT_VALID_ALL in real use; it is only changeable for the sake of - // unit tests. - int context_frame_validity_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_ARM_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.cc deleted file mode 100644 index 31119a97e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.cc +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_arm64.cc: arm64-specific stackwalker. -// -// See stackwalker_arm64.h for documentation. -// -// Author: Mark Mentovai, Ted Mielczarek, Jim Blandy, Colin Blundell - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" -#include "processor/logging.h" -#include "processor/stackwalker_arm64.h" - -namespace google_breakpad { - - -StackwalkerARM64::StackwalkerARM64(const SystemInfo* system_info, - const MDRawContextARM64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context), - context_frame_validity_(StackFrameARM64::CONTEXT_VALID_ALL) { } - - -StackFrame* StackwalkerARM64::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFrameARM64* frame = new StackFrameARM64(); - - // The instruction pointer is stored directly in a register (x32), so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = context_frame_validity_; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.iregs[MD_CONTEXT_ARM64_REG_PC]; - - return frame; -} - -StackFrameARM64* StackwalkerARM64::GetCallerByCFIFrameInfo( - const vector &frames, - CFIFrameInfo* cfi_frame_info) { - StackFrameARM64* last_frame = static_cast(frames.back()); - - static const char* register_names[] = { - "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", - "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", - "pc", NULL - }; - - // Populate a dictionary with the valid register values in last_frame. - CFIFrameInfo::RegisterValueMap callee_registers; - for (int i = 0; register_names[i]; i++) { - if (last_frame->context_validity & StackFrameARM64::RegisterValidFlag(i)) - callee_registers[register_names[i]] = last_frame->context.iregs[i]; - } - - // Use the STACK CFI data to recover the caller's register values. - CFIFrameInfo::RegisterValueMap caller_registers; - if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, - &caller_registers)) { - return NULL; - } - // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameARM64()); - for (int i = 0; register_names[i]; i++) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(register_names[i]); - if (entry != caller_registers.end()) { - // We recovered the value of this register; fill the context with the - // value from caller_registers. - frame->context_validity |= StackFrameARM64::RegisterValidFlag(i); - frame->context.iregs[i] = entry->second; - } else if (19 <= i && i <= 29 && (last_frame->context_validity & - StackFrameARM64::RegisterValidFlag(i))) { - // If the STACK CFI data doesn't mention some callee-saves register, and - // it is valid in the callee, assume the callee has not yet changed it. - // Registers r19 through r29 are callee-saves, according to the Procedure - // Call Standard for the ARM AARCH64 Architecture, which the Linux ABI - // follows. - frame->context_validity |= StackFrameARM64::RegisterValidFlag(i); - frame->context.iregs[i] = last_frame->context.iregs[i]; - } - } - // If the CFI doesn't recover the PC explicitly, then use .ra. - if (!(frame->context_validity & StackFrameARM64::CONTEXT_VALID_PC)) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(".ra"); - if (entry != caller_registers.end()) { - frame->context_validity |= StackFrameARM64::CONTEXT_VALID_PC; - frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = entry->second; - } - } - // If the CFI doesn't recover the SP explicitly, then use .cfa. - if (!(frame->context_validity & StackFrameARM64::CONTEXT_VALID_SP)) { - CFIFrameInfo::RegisterValueMap::iterator entry = - caller_registers.find(".cfa"); - if (entry != caller_registers.end()) { - frame->context_validity |= StackFrameARM64::CONTEXT_VALID_SP; - frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] = entry->second; - } - } - - // If we didn't recover the PC and the SP, then the frame isn't very useful. - static const uint64_t essentials = (StackFrameARM64::CONTEXT_VALID_SP - | StackFrameARM64::CONTEXT_VALID_PC); - if ((frame->context_validity & essentials) != essentials) - return NULL; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - return frame.release(); -} - -StackFrameARM64* StackwalkerARM64::GetCallerByStackScan( - const vector &frames) { - StackFrameARM64* last_frame = static_cast(frames.back()); - uint64_t last_sp = last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]; - uint64_t caller_sp, caller_pc; - - if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, - frames.size() == 1 /* is_context_frame */)) { - // No plausible return address was found. - return NULL; - } - - // ScanForReturnAddress found a reasonable return address. Advance - // %sp to the location above the one where the return address was - // found. - caller_sp += 8; - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameARM64* frame = new StackFrameARM64(); - - frame->trust = StackFrame::FRAME_TRUST_SCAN; - frame->context = last_frame->context; - frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = caller_pc; - frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] = caller_sp; - frame->context_validity = StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP; - - return frame; -} - -StackFrameARM64* StackwalkerARM64::GetCallerByFramePointer( - const vector &frames) { - StackFrameARM64* last_frame = static_cast(frames.back()); - - uint64_t last_fp = last_frame->context.iregs[MD_CONTEXT_ARM64_REG_FP]; - - uint64_t caller_fp = 0; - if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { - BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" - << std::hex << last_fp; - return NULL; - } - - uint64_t caller_lr = 0; - if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_lr)) { - BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 8: 0x" - << std::hex << (last_fp + 8); - return NULL; - } - - uint64_t caller_sp = last_fp ? last_fp + 16 : - last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]; - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameARM64* frame = new StackFrameARM64(); - - frame->trust = StackFrame::FRAME_TRUST_FP; - frame->context = last_frame->context; - frame->context.iregs[MD_CONTEXT_ARM64_REG_FP] = caller_fp; - frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] = caller_sp; - frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = - last_frame->context.iregs[MD_CONTEXT_ARM64_REG_LR]; - frame->context.iregs[MD_CONTEXT_ARM64_REG_LR] = caller_lr; - frame->context_validity = StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_LR | - StackFrameARM64::CONTEXT_VALID_FP | - StackFrameARM64::CONTEXT_VALID_SP; - return frame; -} - -StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - const vector &frames = *stack->frames(); - StackFrameARM64* last_frame = static_cast(frames.back()); - scoped_ptr frame; - - // See if there is DWARF call frame information covering this address. - scoped_ptr cfi_frame_info( - frame_symbolizer_->FindCFIFrameInfo(last_frame)); - if (cfi_frame_info.get()) - frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); - - // If CFI failed, or there wasn't CFI available, fall back to frame pointer. - if (!frame.get()) - frame.reset(GetCallerByFramePointer(frames)); - - // If everything failed, fall back to stack scanning. - if (stack_scan_allowed && !frame.get()) - frame.reset(GetCallerByStackScan(frames)); - - // If nothing worked, tell the caller. - if (!frame.get()) - return NULL; - - // An instruction address of zero marks the end of the stack. - if (frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] == 0) - return NULL; - - // If the new stack pointer is at a lower address than the old, then - // that's clearly incorrect. Treat this as end-of-stack to enforce - // progress and avoid infinite loops. - if (frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] - < last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]) - return NULL; - - // The new frame's context's PC is the return address, which is one - // instruction past the instruction that caused us to arrive at the callee. - // ARM64 instructions have a uniform 4-byte encoding, so subtracting 4 off - // the return address gets back to the beginning of the call instruction. - // Callers that require the exact return address value may access - // frame->context.iregs[MD_CONTEXT_ARM64_REG_PC]. - frame->instruction = frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] - 4; - - return frame.release(); -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.h deleted file mode 100644 index 121e82467..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.h +++ /dev/null @@ -1,104 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_arm64.h: arm64-specific stackwalker. -// -// Provides stack frames given arm64 register context and a memory region -// corresponding to an arm64 stack. -// -// Author: Mark Mentovai, Ted Mielczarek, Colin Blundell - - -#ifndef PROCESSOR_STACKWALKER_ARM64_H__ -#define PROCESSOR_STACKWALKER_ARM64_H__ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerARM64 : public Stackwalker { - public: - // context is an arm64 context object that gives access to arm64-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerARM64(const SystemInfo* system_info, - const MDRawContextARM64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - // Change the context validity mask of the frame returned by - // GetContextFrame to VALID. This is only for use by unit tests; the - // default behavior is correct for all application code. - void SetContextFrameValidity(uint64_t valid) { - context_frame_validity_ = valid; - } - - private: - // Implementation of Stackwalker, using arm64 context and stack conventions. - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Use cfi_frame_info (derived from STACK CFI records) to construct - // the frame that called frames.back(). The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameARM64* GetCallerByCFIFrameInfo(const vector &frames, - CFIFrameInfo* cfi_frame_info); - - // Use the frame pointer. The caller takes ownership of the returned frame. - // Return NULL on failure. - StackFrameARM64* GetCallerByFramePointer(const vector &frames); - - // Scan the stack for plausible return addresses. The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameARM64* GetCallerByStackScan(const vector &frames); - - // Stores the CPU context corresponding to the youngest stack frame, to - // be returned by GetContextFrame. - const MDRawContextARM64* context_; - - // Validity mask for youngest stack frame. This is always - // CONTEXT_VALID_ALL in real use; it is only changeable for the sake of - // unit tests. - uint64_t context_frame_validity_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_ARM64_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64_unittest.cc deleted file mode 100644 index f9d18cea0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64_unittest.cc +++ /dev/null @@ -1,880 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stackwalker_arm64_unittest.cc: Unit tests for StackwalkerARM64 class. - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_arm64.h" -#include "processor/windows_frame_info.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::StackFrameARM64; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerARM64; -using google_breakpad::SystemInfo; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class StackwalkerARM64Fixture { - public: - StackwalkerARM64Fixture() - : stack_section(kLittleEndian), - // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(0x40000000, 0x10000, "module1", "version1"), - module2(0x50000000, 0x10000, "module2", "version2") { - // Identify the system as an iOS system. - system_info.os = "iOS"; - system_info.os_short = "ios"; - system_info.cpu = "arm64"; - system_info.cpu_info = ""; - - // Put distinctive values in the raw CPU context. - BrandContext(&raw_context); - - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - - // Reset max_frames_scanned since it's static. - Stackwalker::set_max_frames_scanned(1024); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule *module, const string &info) { - size_t buffer_size; - char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - // Populate stack_region with the contents of stack_section. Use - // stack_section.start() as the region's starting address. - void RegionFromSection() { - string contents; - ASSERT_TRUE(stack_section.GetContents(&contents)); - stack_region.Init(stack_section.start().Value(), contents); - } - - // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. - void BrandContext(MDRawContextARM64 *raw_context) { - uint8_t x = 173; - for (size_t i = 0; i < sizeof(*raw_context); i++) - reinterpret_cast(raw_context)[i] = (x += 17); - } - - SystemInfo system_info; - MDRawContextARM64 raw_context; - Section stack_section; - MockMemoryRegion stack_region; - MockCodeModule module1; - MockCodeModule module2; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - CallStack call_stack; - const vector *frames; -}; - -class SanityCheck: public StackwalkerARM64Fixture, public Test { }; - -TEST_F(SanityCheck, NoResolver) { - // Since the context's frame pointer is garbage, the stack walk will end after - // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - // This should succeed even without a resolver or supplier. - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameARM64 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetContextFrame: public StackwalkerARM64Fixture, public Test { }; - -// The stackwalker should be able to produce the context frame even -// without stack memory present. -TEST_F(GetContextFrame, NoStackMemory) { - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, NULL, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameARM64 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetCallerFrame: public StackwalkerARM64Fixture, public Test { }; - -TEST_F(GetCallerFrame, ScanWithoutSymbols) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - // Force scanning through three frames to ensure that the - // stack pointer is set properly in scan-recovered frames. - stack_section.start() = 0x80000000; - uint64_t return_address1 = 0x50000100; - uint64_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x40090000) // junk that's not - .D64(0x60000000) // a return address - - .D64(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D64(0xF0000000) // more junk - .D64(0x0000000D) - - .D64(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(64, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, - frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); - - StackFrameARM64 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM64_REG_SP]); -} - -TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { - // During stack scanning, if a potential return address - // is located within a loaded module that has symbols, - // it is only considered a valid return address if it - // lies within a function's bounds. - stack_section.start() = 0x80000000; - uint64_t return_address = 0x50000200; - Label frame1_sp; - - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x40090000) // junk that's not - .D64(0x60000000) // a return address - - .D64(0x40001000) // a couple of plausible addresses - .D64(0x5000F000) // that are not within functions - - .D64(return_address) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(64, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40000200; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 100 400 10 monotreme\n"); - SetModuleSymbols(&module2, - // The calling frame's function. - "FUNC 100 400 10 marsupial\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, - frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - EXPECT_EQ("monotreme", frame0->function_name); - EXPECT_EQ(0x40000100ULL, frame0->function_base); - - StackFrameARM64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); - EXPECT_EQ("marsupial", frame1->function_name); - EXPECT_EQ(0x50000100ULL, frame1->function_base); -} - -TEST_F(GetCallerFrame, ScanFirstFrame) { - // If the stackwalker resorts to stack scanning, it will scan much - // farther to find the caller of the context frame. - stack_section.start() = 0x80000000; - uint64_t return_address1 = 0x50000100; - uint64_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(32, 0) // space - - .D64(0x40090000) // junk that's not - .D64(0x60000000) // a return address - - .Append(96, 0) // more space - - .D64(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0) // space - - .D64(0xF0000000) // more junk - .D64(0x0000000D) - - .Append(336, 0) // more space - - .D64(return_address2) // actual return address - // (won't be found) - // frame 2 - .Mark(&frame2_sp) - .Append(64, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, - frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); -} - -// Test that set_max_frames_scanned prevents using stack scanning -// to find caller frames. -TEST_F(GetCallerFrame, ScanningNotAllowed) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - stack_section.start() = 0x80000000; - uint64_t return_address1 = 0x50000100; - uint64_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D64(0x40090000) // junk that's not - .D64(0x60000000) // a return address - - .D64(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D64(0xF0000000) // more junk - .D64(0x0000000D) - - .D64(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(64, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - Stackwalker::set_max_frames_scanned(0); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, - frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); -} - -class GetFramesByFramePointer: public StackwalkerARM64Fixture, public Test { }; - -TEST_F(GetFramesByFramePointer, OnlyFramePointer) { - stack_section.start() = 0x80000000; - uint64_t return_address1 = 0x50000100; - uint64_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - Label frame1_fp, frame2_fp; - stack_section - // frame 0 - .Append(64, 0) // Whatever values on the stack. - .D64(0x0000000D) // junk that's not - .D64(0xF0000000) // a return address. - - .Mark(&frame1_fp) // Next fp will point to the next value. - .D64(frame2_fp) // Save current frame pointer. - .D64(return_address2) // Save current link register. - .Mark(&frame1_sp) - - // frame 1 - .Append(64, 0) // Whatever values on the stack. - .D64(0x0000000D) // junk that's not - .D64(0xF0000000) // a return address. - - .Mark(&frame2_fp) - .D64(0) - .D64(0) - .Mark(&frame2_sp) - - // frame 2 - .Append(64, 0) // Whatever values on the stack. - .D64(0x0000000D) // junk that's not - .D64(0xF0000000); // a return address. - RegionFromSection(); - - - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = return_address1; - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = frame1_fp.Value(); - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, - &stack_region, &modules, &frame_symbolizer); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, - frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_LR | - StackFrameARM64::CONTEXT_VALID_FP | - StackFrameARM64::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM64_REG_LR]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); - EXPECT_EQ(frame2_fp.Value(), - frame1->context.iregs[MD_CONTEXT_ARM64_REG_FP]); - - StackFrameARM64 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust); - ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_LR | - StackFrameARM64::CONTEXT_VALID_FP | - StackFrameARM64::CONTEXT_VALID_SP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM64_REG_LR]); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM64_REG_SP]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM64_REG_FP]); -} - -struct CFIFixture: public StackwalkerARM64Fixture { - CFIFixture() { - // Provide a bunch of STACK CFI records; we'll walk to the caller - // from every point in this series, expecting to find the same set - // of register values. - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 4000 1000 10 enchiridion\n" - // Initially, nothing has been pushed on the stack, - // and the return address is still in the link - // register (x30). - "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: x30\n" - // Push x19, x20, the frame pointer and the link register. - "STACK CFI 4001 .cfa: sp 32 + .ra: .cfa -8 + ^" - " x19: .cfa -32 + ^ x20: .cfa -24 + ^ " - " x29: .cfa -16 + ^\n" - // Save x19..x22 in x0..x3: verify that we populate - // the youngest frame with all the values we have. - "STACK CFI 4002 x19: x0 x20: x1 x21: x2 x22: x3\n" - // Restore x19..x22. Save the non-callee-saves register x1. - "STACK CFI 4003 .cfa: sp 40 + x1: .cfa 40 - ^" - " x19: x19 x20: x20 x21: x21 x22: x22\n" - // Move the .cfa back eight bytes, to point at the return - // address, and restore the sp explicitly. - "STACK CFI 4005 .cfa: sp 32 + x1: .cfa 32 - ^" - " x29: .cfa 8 - ^ .ra: .cfa ^ sp: .cfa 8 +\n" - // Recover the PC explicitly from a new stack slot; - // provide garbage for the .ra. - "STACK CFI 4006 .cfa: sp 40 + pc: .cfa 40 - ^\n" - - // The calling function. - "FUNC 5000 1000 10 epictetus\n" - // Mark it as end of stack. - "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n" - - // A function whose CFI makes the stack pointer - // go backwards. - "FUNC 6000 1000 20 palinal\n" - "STACK CFI INIT 6000 1000 .cfa: sp 8 - .ra: x30\n" - - // A function with CFI expressions that can't be - // evaluated. - "FUNC 7000 1000 20 rhetorical\n" - "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n"); - - // Provide some distinctive values for the caller's registers. - expected.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040005510L; - expected.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; - expected.iregs[19] = 0x5e68b5d5b5d55e68L; - expected.iregs[20] = 0x34f3ebd1ebd134f3L; - expected.iregs[21] = 0x74bca31ea31e74bcL; - expected.iregs[22] = 0x16b32dcb2dcb16b3L; - expected.iregs[23] = 0x21372ada2ada2137L; - expected.iregs[24] = 0x557dbbbbbbbb557dL; - expected.iregs[25] = 0x8ca748bf48bf8ca7L; - expected.iregs[26] = 0x21f0ab46ab4621f0L; - expected.iregs[27] = 0x146732b732b71467L; - expected.iregs[28] = 0xa673645fa673645fL; - expected.iregs[MD_CONTEXT_ARM64_REG_FP] = 0xe11081128112e110L; - - // Expect CFI to recover all callee-saves registers. Since CFI is the - // only stack frame construction technique we have, aside from the - // context frame itself, there's no way for us to have a set of valid - // registers smaller than this. - expected_validity = (StackFrameARM64::CONTEXT_VALID_PC | - StackFrameARM64::CONTEXT_VALID_SP | - StackFrameARM64::CONTEXT_VALID_X19 | - StackFrameARM64::CONTEXT_VALID_X20 | - StackFrameARM64::CONTEXT_VALID_X21 | - StackFrameARM64::CONTEXT_VALID_X22 | - StackFrameARM64::CONTEXT_VALID_X23 | - StackFrameARM64::CONTEXT_VALID_X24 | - StackFrameARM64::CONTEXT_VALID_X25 | - StackFrameARM64::CONTEXT_VALID_X26 | - StackFrameARM64::CONTEXT_VALID_X27 | - StackFrameARM64::CONTEXT_VALID_X28 | - StackFrameARM64::CONTEXT_VALID_FP); - - // By default, context frames provide all registers, as normal. - context_frame_validity = StackFrameARM64::CONTEXT_VALID_ALL; - - // By default, registers are unchanged. - raw_context = expected; - } - - // Walk the stack, using stack_section as the contents of the stack - // and raw_context as the current register values. (Set the stack - // pointer to the stack's starting address.) Expect two stack - // frames; in the older frame, expect the callee-saves registers to - // have values matching those in 'expected'. - void CheckWalk() { - RegionFromSection(); - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, - &modules, &frame_symbolizer); - walker.SetContextFrameValidity(context_frame_validity); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM64 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(context_frame_validity, frame0->context_validity); - EXPECT_EQ("enchiridion", frame0->function_name); - EXPECT_EQ(0x0000000040004000UL, frame0->function_base); - - StackFrameARM64 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ(expected_validity, frame1->context_validity); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X1) - EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X19) - EXPECT_EQ(expected.iregs[19], frame1->context.iregs[19]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X20) - EXPECT_EQ(expected.iregs[20], frame1->context.iregs[20]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X21) - EXPECT_EQ(expected.iregs[21], frame1->context.iregs[21]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X22) - EXPECT_EQ(expected.iregs[22], frame1->context.iregs[22]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X23) - EXPECT_EQ(expected.iregs[23], frame1->context.iregs[23]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X24) - EXPECT_EQ(expected.iregs[24], frame1->context.iregs[24]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X25) - EXPECT_EQ(expected.iregs[25], frame1->context.iregs[25]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X26) - EXPECT_EQ(expected.iregs[26], frame1->context.iregs[26]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X27) - EXPECT_EQ(expected.iregs[27], frame1->context.iregs[27]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_X28) - EXPECT_EQ(expected.iregs[28], frame1->context.iregs[28]); - if (expected_validity & StackFrameARM64::CONTEXT_VALID_FP) - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_FP], - frame1->context.iregs[MD_CONTEXT_ARM64_REG_FP]); - - // We would never have gotten a frame in the first place if the SP - // and PC weren't valid or ->instruction weren't set. - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_SP], - frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_PC], - frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_PC], - frame1->instruction + 4); - EXPECT_EQ("epictetus", frame1->function_name); - } - - // The values we expect to find for the caller's registers. - MDRawContextARM64 expected; - - // The validity mask for expected. - uint64_t expected_validity; - - // The validity mask to impose on the context frame. - uint64_t context_frame_validity; -}; - -class CFI: public CFIFixture, public Test { }; - -TEST_F(CFI, At4000) { - stack_section.start() = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004000L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = 0x0000000040005510L; - CheckWalk(); -} - -TEST_F(CFI, At4001) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0x5e68b5d5b5d55e68L) // saved x19 - .D64(0x34f3ebd1ebd134f3L) // saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004001L; - // distinct callee x19, x20 and fp - raw_context.iregs[19] = 0xadc9f635a635adc9L; - raw_context.iregs[20] = 0x623135ac35ac6231L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; - CheckWalk(); -} - -// As above, but unwind from a context that has only the PC and SP. -TEST_F(CFI, At4001LimitedValidity) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0x5e68b5d5b5d55e68L) // saved x19 - .D64(0x34f3ebd1ebd134f3L) // saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - context_frame_validity = - StackFrameARM64::CONTEXT_VALID_PC | StackFrameARM64::CONTEXT_VALID_SP; - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004001L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; - - expected_validity = (StackFrameARM64::CONTEXT_VALID_PC - | StackFrameARM64::CONTEXT_VALID_SP - | StackFrameARM64::CONTEXT_VALID_FP - | StackFrameARM64::CONTEXT_VALID_X19 - | StackFrameARM64::CONTEXT_VALID_X20); - CheckWalk(); -} - -TEST_F(CFI, At4002) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 - .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004002L; - raw_context.iregs[0] = 0x5e68b5d5b5d55e68L; // saved x19 - raw_context.iregs[1] = 0x34f3ebd1ebd134f3L; // saved x20 - raw_context.iregs[2] = 0x74bca31ea31e74bcL; // saved x21 - raw_context.iregs[3] = 0x16b32dcb2dcb16b3L; // saved x22 - raw_context.iregs[19] = 0xadc9f635a635adc9L; // distinct callee x19 - raw_context.iregs[20] = 0x623135ac35ac6231L; // distinct callee x20 - raw_context.iregs[21] = 0xac4543564356ac45L; // distinct callee x21 - raw_context.iregs[22] = 0x2561562f562f2561L; // distinct callee x22 - // distinct callee fp - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; - CheckWalk(); -} - -TEST_F(CFI, At4003) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) - .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 - .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004003L; - // distinct callee x1 and fp - raw_context.iregs[1] = 0xfb756319fb756319L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; - // caller's x1 - expected.iregs[1] = 0xdd5a48c848c8dd5aL; - expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; - CheckWalk(); -} - -// We have no new rule at module offset 0x4004, so the results here should -// be the same as those at module offset 0x4003. -TEST_F(CFI, At4004) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) - .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 - .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004004L; - // distinct callee x1 and fp - raw_context.iregs[1] = 0xfb756319fb756319L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; - // caller's x1 - expected.iregs[1] = 0xdd5a48c848c8dd5aL; - expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; - CheckWalk(); -} - -// Here we move the .cfa, but provide an explicit rule to recover the SP, -// so again there should be no change in the registers recovered. -TEST_F(CFI, At4005) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) - .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 - .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0x0000000040005510L) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004005L; - raw_context.iregs[1] = 0xfb756319fb756319L; // distinct callee x1 - expected.iregs[1] = 0xdd5a48c848c8dd5aL; // caller's x1 - expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; - CheckWalk(); -} - -// Here we provide an explicit rule for the PC, and have the saved .ra be -// bogus. -TEST_F(CFI, At4006) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; - stack_section - .D64(0x0000000040005510L) // saved pc - .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) - .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 - .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 - .D64(0xe11081128112e110L) // saved fp - .D64(0xf8d157835783f8d1L) // .ra rule recovers this, which is garbage - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004006L; - raw_context.iregs[1] = 0xfb756319fb756319L; // distinct callee x1 - expected.iregs[1] = 0xdd5a48c848c8dd5aL; // caller's x1 - expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; - CheckWalk(); -} - -// Check that we reject rules that would cause the stack pointer to -// move in the wrong direction. -TEST_F(CFI, RejectBackwards) { - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040006000L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = 0x0000000040005510L; - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} - -// Check that we reject rules whose expressions' evaluation fails. -TEST_F(CFI, RejectBadExpressions) { - raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040007000L; - raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc deleted file mode 100644 index 8a0fd5e95..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc +++ /dev/null @@ -1,974 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class. - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_arm.h" -#include "processor/windows_frame_info.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::StackFrameARM; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerARM; -using google_breakpad::SystemInfo; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class StackwalkerARMFixture { - public: - StackwalkerARMFixture() - : stack_section(kLittleEndian), - // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(0x40000000, 0x10000, "module1", "version1"), - module2(0x50000000, 0x10000, "module2", "version2") { - // Identify the system as a Linux system. - system_info.os = "Linux"; - system_info.os_short = "linux"; - system_info.os_version = "Lugubrious Labrador"; - system_info.cpu = "arm"; - system_info.cpu_info = ""; - - // Put distinctive values in the raw CPU context. - BrandContext(&raw_context); - - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - - // Reset max_frames_scanned since it's static. - Stackwalker::set_max_frames_scanned(1024); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule *module, const string &info) { - size_t buffer_size; - char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - // Populate stack_region with the contents of stack_section. Use - // stack_section.start() as the region's starting address. - void RegionFromSection() { - string contents; - ASSERT_TRUE(stack_section.GetContents(&contents)); - stack_region.Init(stack_section.start().Value(), contents); - } - - // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. - void BrandContext(MDRawContextARM *raw_context) { - uint8_t x = 173; - for (size_t i = 0; i < sizeof(*raw_context); i++) - reinterpret_cast(raw_context)[i] = (x += 17); - } - - SystemInfo system_info; - MDRawContextARM raw_context; - Section stack_section; - MockMemoryRegion stack_region; - MockCodeModule module1; - MockCodeModule module2; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - CallStack call_stack; - const vector *frames; -}; - -class SanityCheck: public StackwalkerARMFixture, public Test { }; - -TEST_F(SanityCheck, NoResolver) { - // Since we have no call frame information, and all unwinding - // requires call frame information, the stack walk will end after - // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - // This should succeed even without a resolver or supplier. - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameARM *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetContextFrame: public StackwalkerARMFixture, public Test { }; - -TEST_F(GetContextFrame, Simple) { - // Since we have no call frame information, and all unwinding - // requires call frame information, the stack walk will end after - // the first frame. - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameARM *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -// The stackwalker should be able to produce the context frame even -// without stack memory present. -TEST_F(GetContextFrame, NoStackMemory) { - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameARM *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetCallerFrame: public StackwalkerARMFixture, public Test { }; - -TEST_F(GetCallerFrame, ScanWithoutSymbols) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - // Force scanning through three frames to ensure that the - // stack pointer is set properly in scan-recovered frames. - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x50000100; - uint32_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D32(0x40090000) // junk that's not - .D32(0x60000000) // a return address - - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D32(0xF0000000) // more junk - .D32(0x0000000D) - - .D32(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); - - StackFrameARM *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); -} - -TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { - // During stack scanning, if a potential return address - // is located within a loaded module that has symbols, - // it is only considered a valid return address if it - // lies within a function's bounds. - stack_section.start() = 0x80000000; - uint32_t return_address = 0x50000200; - Label frame1_sp; - - stack_section - // frame 0 - .Append(16, 0) // space - - .D32(0x40090000) // junk that's not - .D32(0x60000000) // a return address - - .D32(0x40001000) // a couple of plausible addresses - .D32(0x5000F000) // that are not within functions - - .D32(return_address) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40000200; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 100 400 10 monotreme\n"); - SetModuleSymbols(&module2, - // The calling frame's function. - "FUNC 100 400 10 marsupial\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - EXPECT_EQ("monotreme", frame0->function_name); - EXPECT_EQ(0x40000100U, frame0->function_base); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ("marsupial", frame1->function_name); - EXPECT_EQ(0x50000100U, frame1->function_base); -} - -TEST_F(GetCallerFrame, ScanFirstFrame) { - // If the stackwalker resorts to stack scanning, it will scan much - // farther to find the caller of the context frame. - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x50000100; - uint32_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(32, 0) // space - - .D32(0x40090000) // junk that's not - .D32(0x60000000) // a return address - - .Append(96, 0) // more space - - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0) // space - - .D32(0xF0000000) // more junk - .D32(0x0000000D) - - .Append(136, 0) // more space - - .D32(return_address2) // actual return address - // (won't be found) - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); -} - -// Test that set_max_frames_scanned prevents using stack scanning -// to find caller frames. -TEST_F(GetCallerFrame, ScanningNotAllowed) { - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x50000100; - uint32_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D32(0x40090000) // junk that's not - .D32(0x60000000) // a return address - - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D32(0xF0000000) // more junk - .D32(0x0000000D) - - .D32(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - Stackwalker::set_max_frames_scanned(0); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); -} - -struct CFIFixture: public StackwalkerARMFixture { - CFIFixture() { - // Provide a bunch of STACK CFI records; we'll walk to the caller - // from every point in this series, expecting to find the same set - // of register values. - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 4000 1000 10 enchiridion\n" - // Initially, nothing has been pushed on the stack, - // and the return address is still in the link register. - "STACK CFI INIT 4000 100 .cfa: sp .ra: lr\n" - // Push r4, the frame pointer, and the link register. - "STACK CFI 4001 .cfa: sp 12 + r4: .cfa 12 - ^" - " r11: .cfa 8 - ^ .ra: .cfa 4 - ^\n" - // Save r4..r7 in r0..r3: verify that we populate - // the youngest frame with all the values we have. - "STACK CFI 4002 r4: r0 r5: r1 r6: r2 r7: r3\n" - // Restore r4..r7. Save the non-callee-saves register r1. - "STACK CFI 4003 .cfa: sp 16 + r1: .cfa 16 - ^" - " r4: r4 r5: r5 r6: r6 r7: r7\n" - // Move the .cfa back four bytes, to point at the return - // address, and restore the sp explicitly. - "STACK CFI 4005 .cfa: sp 12 + r1: .cfa 12 - ^" - " r11: .cfa 4 - ^ .ra: .cfa ^ sp: .cfa 4 +\n" - // Recover the PC explicitly from a new stack slot; - // provide garbage for the .ra. - "STACK CFI 4006 .cfa: sp 16 + pc: .cfa 16 - ^\n" - - // The calling function. - "FUNC 5000 1000 10 epictetus\n" - // Mark it as end of stack. - "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n" - - // A function whose CFI makes the stack pointer - // go backwards. - "FUNC 6000 1000 20 palinal\n" - "STACK CFI INIT 6000 1000 .cfa: sp 4 - .ra: lr\n" - - // A function with CFI expressions that can't be - // evaluated. - "FUNC 7000 1000 20 rhetorical\n" - "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n"); - - // Provide some distinctive values for the caller's registers. - expected.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; - expected.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; - expected.iregs[4] = 0xb5d55e68; - expected.iregs[5] = 0xebd134f3; - expected.iregs[6] = 0xa31e74bc; - expected.iregs[7] = 0x2dcb16b3; - expected.iregs[8] = 0x2ada2137; - expected.iregs[9] = 0xbbbb557d; - expected.iregs[10] = 0x48bf8ca7; - expected.iregs[MD_CONTEXT_ARM_REG_FP] = 0x8112e110; - - // Expect CFI to recover all callee-saves registers. Since CFI is the - // only stack frame construction technique we have, aside from the - // context frame itself, there's no way for us to have a set of valid - // registers smaller than this. - expected_validity = (StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_SP | - StackFrameARM::CONTEXT_VALID_R4 | - StackFrameARM::CONTEXT_VALID_R5 | - StackFrameARM::CONTEXT_VALID_R6 | - StackFrameARM::CONTEXT_VALID_R7 | - StackFrameARM::CONTEXT_VALID_R8 | - StackFrameARM::CONTEXT_VALID_R9 | - StackFrameARM::CONTEXT_VALID_R10 | - StackFrameARM::CONTEXT_VALID_FP); - - // By default, context frames provide all registers, as normal. - context_frame_validity = StackFrameARM::CONTEXT_VALID_ALL; - - // By default, registers are unchanged. - raw_context = expected; - } - - // Walk the stack, using stack_section as the contents of the stack - // and raw_context as the current register values. (Set the stack - // pointer to the stack's starting address.) Expect two stack - // frames; in the older frame, expect the callee-saves registers to - // have values matching those in 'expected'. - void CheckWalk() { - RegionFromSection(); - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, - &modules, &frame_symbolizer); - walker.SetContextFrameValidity(context_frame_validity); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(context_frame_validity, frame0->context_validity); - EXPECT_EQ("enchiridion", frame0->function_name); - EXPECT_EQ(0x40004000U, frame0->function_base); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ(expected_validity, frame1->context_validity); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R1) - EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R4) - EXPECT_EQ(expected.iregs[4], frame1->context.iregs[4]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R5) - EXPECT_EQ(expected.iregs[5], frame1->context.iregs[5]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R6) - EXPECT_EQ(expected.iregs[6], frame1->context.iregs[6]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R7) - EXPECT_EQ(expected.iregs[7], frame1->context.iregs[7]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R8) - EXPECT_EQ(expected.iregs[8], frame1->context.iregs[8]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R9) - EXPECT_EQ(expected.iregs[9], frame1->context.iregs[9]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_R10) - EXPECT_EQ(expected.iregs[10], frame1->context.iregs[10]); - if (expected_validity & StackFrameARM::CONTEXT_VALID_FP) - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_FP], - frame1->context.iregs[MD_CONTEXT_ARM_REG_FP]); - - // We would never have gotten a frame in the first place if the SP - // and PC weren't valid or ->instruction weren't set. - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_SP], - frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC], - frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC], - frame1->instruction + 2); - EXPECT_EQ("epictetus", frame1->function_name); - } - - // The values we expect to find for the caller's registers. - MDRawContextARM expected; - - // The validity mask for expected. - int expected_validity; - - // The validity mask to impose on the context frame. - int context_frame_validity; -}; - -class CFI: public CFIFixture, public Test { }; - -TEST_F(CFI, At4000) { - stack_section.start() = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004000; - raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510; - CheckWalk(); -} - -TEST_F(CFI, At4001) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0xb5d55e68) // saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001; - raw_context.iregs[4] = 0x635adc9f; // distinct callee r4 - raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp - CheckWalk(); -} - -// As above, but unwind from a context that has only the PC and SP. -TEST_F(CFI, At4001LimitedValidity) { - context_frame_validity = - StackFrameARM::CONTEXT_VALID_PC | StackFrameARM::CONTEXT_VALID_SP; - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001; - raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0xb5d55e68) // saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - expected_validity = (StackFrameARM::CONTEXT_VALID_PC - | StackFrameARM::CONTEXT_VALID_SP - | StackFrameARM::CONTEXT_VALID_FP - | StackFrameARM::CONTEXT_VALID_R4); - CheckWalk(); -} - -TEST_F(CFI, At4002) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0xfb81ff3d) // no longer saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004002; - raw_context.iregs[0] = 0xb5d55e68; // saved r4 - raw_context.iregs[1] = 0xebd134f3; // saved r5 - raw_context.iregs[2] = 0xa31e74bc; // saved r6 - raw_context.iregs[3] = 0x2dcb16b3; // saved r7 - raw_context.iregs[4] = 0xfdd35466; // distinct callee r4 - raw_context.iregs[5] = 0xf18c946c; // distinct callee r5 - raw_context.iregs[6] = 0xac2079e8; // distinct callee r6 - raw_context.iregs[7] = 0xa449829f; // distinct callee r7 - raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp - CheckWalk(); -} - -TEST_F(CFI, At4003) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) - .D32(0xcb78040e) // no longer saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004003; - raw_context.iregs[1] = 0xfb756319; // distinct callee r1 - raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0x0a2857ea; // distinct callee fp - expected.iregs[1] = 0x48c8dd5a; // caller's r1 - expected_validity |= StackFrameARM::CONTEXT_VALID_R1; - CheckWalk(); -} - -// We have no new rule at module offset 0x4004, so the results here should -// be the same as those at module offset 0x4003. -TEST_F(CFI, At4004) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) - .D32(0xcb78040e) // no longer saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004004; - raw_context.iregs[1] = 0xfb756319; // distinct callee r1 - expected.iregs[1] = 0x48c8dd5a; // caller's r1 - expected_validity |= StackFrameARM::CONTEXT_VALID_R1; - CheckWalk(); -} - -// Here we move the .cfa, but provide an explicit rule to recover the SP, -// so again there should be no change in the registers recovered. -TEST_F(CFI, At4005) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) - .D32(0xf013f841) // no longer saved r4 - .D32(0x8112e110) // saved fp - .D32(0x40005510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004005; - raw_context.iregs[1] = 0xfb756319; // distinct callee r1 - expected.iregs[1] = 0x48c8dd5a; // caller's r1 - expected_validity |= StackFrameARM::CONTEXT_VALID_R1; - CheckWalk(); -} - -// Here we provide an explicit rule for the PC, and have the saved .ra be -// bogus. -TEST_F(CFI, At4006) { - Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; - stack_section - .D32(0x40005510) // saved pc - .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) - .D32(0xf013f841) // no longer saved r4 - .D32(0x8112e110) // saved fp - .D32(0xf8d15783) // .ra rule recovers this, which is garbage - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004006; - raw_context.iregs[1] = 0xfb756319; // callee's r1, different from caller's - expected.iregs[1] = 0x48c8dd5a; // caller's r1 - expected_validity |= StackFrameARM::CONTEXT_VALID_R1; - CheckWalk(); -} - -// Check that we reject rules that would cause the stack pointer to -// move in the wrong direction. -TEST_F(CFI, RejectBackwards) { - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; - raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510; - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} - -// Check that we reject rules whose expressions' evaluation fails. -TEST_F(CFI, RejectBadExpressions) { - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000; - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} - -class StackwalkerARMFixtureIOS : public StackwalkerARMFixture { - public: - StackwalkerARMFixtureIOS() { - system_info.os = "iOS"; - system_info.os_short = "ios"; - } -}; - -class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { }; - -TEST_F(GetFramesByFramePointer, OnlyFramePointer) { - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x50000100; - uint32_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - Label frame1_fp, frame2_fp; - stack_section - // frame 0 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000) // a return address. - - .Mark(&frame1_fp) // Next fp will point to the next value. - .D32(frame2_fp) // Save current frame pointer. - .D32(return_address2) // Save current link register. - .Mark(&frame1_sp) - - // frame 1 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000) // a return address. - - .Mark(&frame2_fp) - .D32(0) - .D32(0) - .Mark(&frame2_sp) - - // frame 2 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000); // a return address. - RegionFromSection(); - - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; - raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1; - raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value(); - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP, - &stack_region, &modules, &frame_symbolizer); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_LR | - StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | - StackFrameARM::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ(frame2_fp.Value(), - frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); - - StackFrameARM *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_LR | - StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | - StackFrameARM::CONTEXT_VALID_SP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); -} - -TEST_F(GetFramesByFramePointer, FramePointerAndCFI) { - // Provide the standatd STACK CFI records that is obtained when exmining an - // executable produced by XCode. - SetModuleSymbols(&module1, - // Adding a function in CFI. - "FUNC 4000 1000 10 enchiridion\n" - - "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: lr\n" - "STACK CFI 4001 .cfa: sp 8 + .ra: .cfa -4 + ^" - " r7: .cfa -8 + ^\n" - "STACK CFI 4002 .cfa: r7 8 +\n" - ); - - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x40004010; - uint32_t return_address2 = 0x50000900; - Label frame1_sp, frame2_sp; - Label frame1_fp, frame2_fp; - stack_section - // frame 0 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000) // a return address. - - .Mark(&frame1_fp) // Next fp will point to the next value. - .D32(frame2_fp) // Save current frame pointer. - .D32(return_address2) // Save current link register. - .Mark(&frame1_sp) - - // frame 1 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000) // a return address. - - .Mark(&frame2_fp) - .D32(0) - .D32(0) - .Mark(&frame2_sp) - - // frame 2 - .Append(32, 0) // Whatever values on the stack. - .D32(0x0000000D) // junk that's not - .D32(0xF0000000); // a return address. - RegionFromSection(); - - - raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x50000400; - raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1; - raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value(); - raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP, - &stack_region, &modules, &frame_symbolizer); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module2", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameARM *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameARM *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_LR | - StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | - StackFrameARM::CONTEXT_VALID_SP), - frame1->context_validity); - EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ(frame2_fp.Value(), - frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); - EXPECT_EQ("enchiridion", frame1->function_name); - EXPECT_EQ(0x40004000U, frame1->function_base); - - - StackFrameARM *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); - ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | - StackFrameARM::CONTEXT_VALID_LR | - StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | - StackFrameARM::CONTEXT_VALID_SP), - frame2->context_validity); - EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); - EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.cc deleted file mode 100644 index db55d460c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.cc +++ /dev/null @@ -1,448 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_mips.cc: MIPS-specific stackwalker. -// -// See stackwalker_mips.h for documentation. -// -// Author: Tata Elxsi - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" -#include "processor/logging.h" -#include "processor/postfix_evaluator-inl.h" -#include "processor/stackwalker_mips.h" -#include "processor/windows_frame_info.h" -#include "google_breakpad/common/minidump_cpu_mips.h" - -namespace google_breakpad { - -StackwalkerMIPS::StackwalkerMIPS(const SystemInfo* system_info, - const MDRawContextMIPS* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) -: Stackwalker(system_info, memory, modules, resolver_helper), - context_(context) { - if (context_->context_flags & MD_CONTEXT_MIPS64 ) { - if ((memory_ && memory_->GetBase() + memory_->GetSize() - 1) - > 0xffffffffffffffff) { - BPLOG(ERROR) << "Memory out of range for stackwalking mips64: " - << HexString(memory_->GetBase()) - << "+" - << HexString(memory_->GetSize()); - memory_ = NULL; - } - } else { - if ((memory_ && memory_->GetBase() + memory_->GetSize() - 1) > 0xffffffff) { - BPLOG(ERROR) << "Memory out of range for stackwalking mips32: " - << HexString(memory_->GetBase()) - << "+" - << HexString(memory_->GetSize()); - memory_ = NULL; - } - } -} - -StackFrame* StackwalkerMIPS::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context."; - return NULL; - } - - StackFrameMIPS* frame = new StackFrameMIPS(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFrameMIPS::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.epc; - - return frame; -} - -// Register names for mips. -static const char* const kRegisterNames[] = { - "$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$to", "$t1", - "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$s0", "$s1", "$s2", "$s3", - "$s4", "$s5", "$s6", "$s7", "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", - "$fp", "$ra", NULL - // TODO(gordanac): add float point save registers -}; - -StackFrameMIPS* StackwalkerMIPS::GetCallerByCFIFrameInfo( - const vector& frames, - CFIFrameInfo* cfi_frame_info) { - StackFrameMIPS* last_frame = static_cast(frames.back()); - - if (context_->context_flags & MD_CONTEXT_MIPS) { - uint32_t sp = 0, pc = 0; - - // Populate a dictionary with the valid register values in last_frame. - CFIFrameInfo::RegisterValueMap callee_registers; - // Use the STACK CFI data to recover the caller's register values. - CFIFrameInfo::RegisterValueMap caller_registers; - - for (int i = 0; kRegisterNames[i]; ++i) { - caller_registers[kRegisterNames[i]] = last_frame->context.iregs[i]; - callee_registers[kRegisterNames[i]] = last_frame->context.iregs[i]; - } - - if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, - &caller_registers)) { - return NULL; - } - - CFIFrameInfo::RegisterValueMap::const_iterator entry = - caller_registers.find(".cfa"); - - if (entry != caller_registers.end()) { - sp = entry->second; - caller_registers["$sp"] = entry->second; - } - - entry = caller_registers.find(".ra"); - if (entry != caller_registers.end()) { - caller_registers["$ra"] = entry->second; - pc = entry->second - 2 * sizeof(pc); - } - caller_registers["$pc"] = pc; - // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameMIPS()); - - for (int i = 0; kRegisterNames[i]; ++i) { - CFIFrameInfo::RegisterValueMap::const_iterator caller_entry = - caller_registers.find(kRegisterNames[i]); - - if (caller_entry != caller_registers.end()) { - // The value of this register is recovered; fill the context with the - // value from caller_registers. - frame->context.iregs[i] = caller_entry->second; - frame->context_validity |= StackFrameMIPS::RegisterValidFlag(i); - } else if (((i >= INDEX_MIPS_REG_S0 && i <= INDEX_MIPS_REG_S7) || - (i > INDEX_MIPS_REG_GP && i < INDEX_MIPS_REG_RA)) && - (last_frame->context_validity & - StackFrameMIPS::RegisterValidFlag(i))) { - // If the STACK CFI data doesn't mention some callee-save register, and - // it is valid in the callee, assume the callee has not yet changed it. - // Calee-save registers according to the MIPS o32 ABI specification are: - // $s0 to $s7 - // $sp, $s8 - frame->context.iregs[i] = last_frame->context.iregs[i]; - frame->context_validity |= StackFrameMIPS::RegisterValidFlag(i); - } - } - - frame->context.epc = caller_registers["$pc"]; - frame->instruction = caller_registers["$pc"]; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_PC; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_RA] = caller_registers["$ra"]; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_RA; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - - return frame.release(); - } else { - uint64_t sp = 0, pc = 0; - - // Populate a dictionary with the valid register values in last_frame. - CFIFrameInfo::RegisterValueMap callee_registers; - // Use the STACK CFI data to recover the caller's register values. - CFIFrameInfo::RegisterValueMap caller_registers; - - for (int i = 0; kRegisterNames[i]; ++i) { - caller_registers[kRegisterNames[i]] = last_frame->context.iregs[i]; - callee_registers[kRegisterNames[i]] = last_frame->context.iregs[i]; - } - - if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, - &caller_registers)) { - return NULL; - } - - CFIFrameInfo::RegisterValueMap::const_iterator entry = - caller_registers.find(".cfa"); - - if (entry != caller_registers.end()) { - sp = entry->second; - caller_registers["$sp"] = entry->second; - } - - entry = caller_registers.find(".ra"); - if (entry != caller_registers.end()) { - caller_registers["$ra"] = entry->second; - pc = entry->second - 2 * sizeof(pc); - } - caller_registers["$pc"] = pc; - // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameMIPS()); - - for (int i = 0; kRegisterNames[i]; ++i) { - CFIFrameInfo::RegisterValueMap::const_iterator caller_entry = - caller_registers.find(kRegisterNames[i]); - - if (caller_entry != caller_registers.end()) { - // The value of this register is recovered; fill the context with the - // value from caller_registers. - frame->context.iregs[i] = caller_entry->second; - frame->context_validity |= StackFrameMIPS::RegisterValidFlag(i); - } else if (((i >= INDEX_MIPS_REG_S0 && i <= INDEX_MIPS_REG_S7) || - (i >= INDEX_MIPS_REG_GP && i < INDEX_MIPS_REG_RA)) && - (last_frame->context_validity & - StackFrameMIPS::RegisterValidFlag(i))) { - // If the STACK CFI data doesn't mention some callee-save register, and - // it is valid in the callee, assume the callee has not yet changed it. - // Calee-save registers according to the MIPS o32 ABI specification are: - // $s0 to $s7 - // $sp, $s8 - frame->context.iregs[i] = last_frame->context.iregs[i]; - frame->context_validity |= StackFrameMIPS::RegisterValidFlag(i); - } - } - - frame->context.epc = caller_registers["$pc"]; - frame->instruction = caller_registers["$pc"]; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_PC; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_RA] = caller_registers["$ra"]; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_RA; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - - return frame.release(); - } -} - -StackFrame* StackwalkerMIPS::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - const vector& frames = *stack->frames(); - StackFrameMIPS* last_frame = static_cast(frames.back()); - scoped_ptr new_frame; - - // See if there is DWARF call frame information covering this address. - scoped_ptr cfi_frame_info( - frame_symbolizer_->FindCFIFrameInfo(last_frame)); - if (cfi_frame_info.get()) - new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); - - // If caller frame is not found in CFI try analyzing the stack. - if (stack_scan_allowed && !new_frame.get()) { - new_frame.reset(GetCallerByStackScan(frames)); - } - - // If nothing worked, tell the caller. - if (!new_frame.get()) { - return NULL; - } - - // Treat an instruction address of 0 as end-of-stack. - if (new_frame->context.epc == 0) { - return NULL; - } - - // If the new stack pointer is at a lower address than the old, then - // that's clearly incorrect. Treat this as end-of-stack to enforce - // progress and avoid infinite loops. - if (new_frame->context.iregs[MD_CONTEXT_MIPS_REG_SP] <= - last_frame->context.iregs[MD_CONTEXT_MIPS_REG_SP]) { - return NULL; - } - - return new_frame.release(); -} - -StackFrameMIPS* StackwalkerMIPS::GetCallerByStackScan( - const vector& frames) { - const uint32_t kMaxFrameStackSize = 1024; - const uint32_t kMinArgsOnStack = 4; - - StackFrameMIPS* last_frame = static_cast(frames.back()); - - if (context_->context_flags & MD_CONTEXT_MIPS) { - uint32_t last_sp = last_frame->context.iregs[MD_CONTEXT_MIPS_REG_SP]; - uint32_t caller_pc, caller_sp, caller_fp; - - // Return address cannot be obtained directly. - // Force stackwalking. - - // We cannot use frame pointer to get the return address. - // We'll scan the stack for a - // return address. This can happen if last_frame is executing code - // for a module for which we don't have symbols. - int count = kMaxFrameStackSize / sizeof(caller_pc); - - if (frames.size() > 1) { - // In case of mips32 ABI stack frame of a nonleaf function - // must have minimum stack frame assigned for 4 arguments (4 words). - // Move stack pointer for 4 words to avoid reporting non-existing frames - // for all frames except the topmost one. - // There is no way of knowing if topmost frame belongs to a leaf or - // a nonleaf function. - last_sp += kMinArgsOnStack * sizeof(caller_pc); - // Adjust 'count' so that return address is scanned only in limits - // of one stack frame. - count -= kMinArgsOnStack; - } - - do { - // Scanning for return address from stack pointer of the last frame. - if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, count)) { - // If we can't find an instruction pointer even with stack scanning, - // give up. - BPLOG(ERROR) << " ScanForReturnAddress failed "; - return NULL; - } - // Get $fp stored in the stack frame. - if (!memory_->GetMemoryAtAddress(caller_sp - sizeof(caller_pc), - &caller_fp)) { - BPLOG(INFO) << " GetMemoryAtAddress for fp failed " ; - return NULL; - } - - count = count - (caller_sp - last_sp) / sizeof(caller_pc); - // Now scan the next address in the stack. - last_sp = caller_sp + sizeof(caller_pc); - } while ((caller_fp - caller_sp >= kMaxFrameStackSize) && count > 0); - - if (!count) { - BPLOG(INFO) << " No frame found " ; - return NULL; - } - - // ScanForReturnAddress found a reasonable return address. Advance - // $sp to the location above the one where the return address was - // found. - caller_sp += sizeof(caller_pc); - // caller_pc is actually containing $ra value; - // $pc is two instructions before $ra, - // so the caller_pc needs to be decremented accordingly. - caller_pc -= 2 * sizeof(caller_pc); - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameMIPS* frame = new StackFrameMIPS(); - frame->trust = StackFrame::FRAME_TRUST_SCAN; - frame->context = last_frame->context; - frame->context.epc = caller_pc; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_PC; - frame->instruction = caller_pc; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_SP] = caller_sp; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_SP; - frame->context.iregs[MD_CONTEXT_MIPS_REG_FP] = caller_fp; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_FP; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_RA] = - caller_pc + 2 * sizeof(caller_pc); - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_RA; - - return frame; - } else { - uint64_t last_sp = last_frame->context.iregs[MD_CONTEXT_MIPS_REG_SP]; - uint64_t caller_pc, caller_sp, caller_fp; - - // Return address cannot be obtained directly. - // Force stackwalking. - - // We cannot use frame pointer to get the return address. - // We'll scan the stack for a - // return address. This can happen if last_frame is executing code - // for a module for which we don't have symbols. - int count = kMaxFrameStackSize / sizeof(caller_pc); - - do { - // Scanning for return address from stack pointer of the last frame. - if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, count)) { - // If we can't find an instruction pointer even with stack scanning, - // give up. - BPLOG(ERROR) << " ScanForReturnAddress failed "; - return NULL; - } - // Get $fp stored in the stack frame. - if (!memory_->GetMemoryAtAddress(caller_sp - sizeof(caller_pc), - &caller_fp)) { - BPLOG(INFO) << " GetMemoryAtAddress for fp failed " ; - return NULL; - } - - count = count - (caller_sp - last_sp) / sizeof(caller_pc); - // Now scan the next address in the stack. - last_sp = caller_sp + sizeof(caller_pc); - } while ((caller_fp - caller_sp >= kMaxFrameStackSize) && count > 0); - - if (!count) { - BPLOG(INFO) << " No frame found " ; - return NULL; - } - - // ScanForReturnAddress found a reasonable return address. Advance - // $sp to the location above the one where the return address was - // found. - caller_sp += sizeof(caller_pc); - // caller_pc is actually containing $ra value; - // $pc is two instructions before $ra, - // so the caller_pc needs to be decremented accordingly. - caller_pc -= 2 * sizeof(caller_pc); - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameMIPS* frame = new StackFrameMIPS(); - frame->trust = StackFrame::FRAME_TRUST_SCAN; - frame->context = last_frame->context; - frame->context.epc = caller_pc; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_PC; - frame->instruction = caller_pc; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_SP] = caller_sp; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_SP; - frame->context.iregs[MD_CONTEXT_MIPS_REG_FP] = caller_fp; - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_FP; - - frame->context.iregs[MD_CONTEXT_MIPS_REG_RA] = - caller_pc + 2 * sizeof(caller_pc); - frame->context_validity |= StackFrameMIPS::CONTEXT_VALID_RA; - - return frame; - } -} - -} // namespace google_breakpad - diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.h deleted file mode 100644 index 5f97791fb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_mips.h: MIPS-specific stackwalker. -// -// Provides stack frames given MIPS register context and a memory region -// corresponding to a MIPSstack. -// -// Author: Tata Elxsi - -#ifndef PROCESSOR_STACKWALKER_MIPS_H__ -#define PROCESSOR_STACKWALKER_MIPS_H__ - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerMIPS : public Stackwalker { - public: - // Context is a MIPS context object that gives access to mips-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly - // through to the base Stackwalker constructor. - StackwalkerMIPS(const SystemInfo* system_info, - const MDRawContextMIPS* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // Implementation of Stackwalker, using mips context and stack conventions. - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Use cfi_frame_info (derived from STACK CFI records) to construct - // the frame that called frames.back(). The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameMIPS* GetCallerByCFIFrameInfo(const vector& frames, - CFIFrameInfo* cfi_frame_info); - - // Scan the stack for plausible return address and frame pointer pair. - // The caller takes ownership of the returned frame. Return NULL on failure. - StackFrameMIPS* GetCallerByStackScan(const vector& frames); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextMIPS* context_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STACKWALKER_MIPS_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips_unittest.cc deleted file mode 100644 index 5398c2b33..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips_unittest.cc +++ /dev/null @@ -1,707 +0,0 @@ -// Copyright (c) 2013, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Gordana Cmiljanovic - -// stackwalker_mips_unittest.cc: Unit tests for StackwalkerMIPS class. - -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_mips.h" -#include "processor/windows_frame_info.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::StackFrameMIPS; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerMIPS; -using google_breakpad::SystemInfo; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class StackwalkerMIPSFixture { - public: - StackwalkerMIPSFixture() - : stack_section(kLittleEndian), - // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(0x00400000, 0x10000, "module1", "version1"), - module2(0x00500000, 0x10000, "module2", "version2") { - // Identify the system as a Linux system. - system_info.os = "Linux"; - system_info.os_short = "linux"; - system_info.os_version = "Observant Opossum"; // Jealous Jellyfish - system_info.cpu = "mips"; - system_info.cpu_info = ""; - - // Put distinctive values in the raw CPU context. - BrandContext(&raw_context); - - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - - // Reset max_frames_scanned since it's static. - Stackwalker::set_max_frames_scanned(1024); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule* module, const string& info) { - size_t buffer_size; - char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - // Populate stack_region with the contents of stack_section. Use - // stack_section.start() as the region's starting address. - void RegionFromSection() { - string contents; - ASSERT_TRUE(stack_section.GetContents(&contents)); - stack_region.Init(stack_section.start().Value(), contents); - } - - // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. - void BrandContext(MDRawContextMIPS* raw_context) { - uint8_t x = 173; - for (size_t i = 0; i < sizeof(*raw_context); ++i) - reinterpret_cast(raw_context)[i] = (x += 17); - } - - SystemInfo system_info; - MDRawContextMIPS raw_context; - Section stack_section; - MockMemoryRegion stack_region; - MockCodeModule module1; - MockCodeModule module2; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - CallStack call_stack; - const vector* frames; -}; - -class SanityCheck: public StackwalkerMIPSFixture, public Test { }; - -TEST_F(SanityCheck, NoResolver) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - stack_section.start() = 0x80000000; - stack_section.D32(0).D32(0x0); - RegionFromSection(); - raw_context.epc = 0x00400020; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(NULL, NULL); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - // This should succeed, even without a resolver or supplier. - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - StackFrameMIPS* frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetContextFrame: public StackwalkerMIPSFixture, public Test { }; - -TEST_F(GetContextFrame, Simple) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - stack_section.start() = 0x80000000; - stack_section.D32(0).D32(0x0); - RegionFromSection(); - raw_context.epc = 0x00400020; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - StackFrameMIPS* frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -// The stackwalker should be able to produce the context frame even -// without stack memory present. -TEST_F(GetContextFrame, NoStackMemory) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - raw_context.epc = 0x00400020; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - StackFrameMIPS* frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetCallerFrame: public StackwalkerMIPSFixture, public Test { }; - -TEST_F(GetCallerFrame, ScanWithoutSymbols) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - // When the stack walker resorts to scanning the stack, - // only addresses located within loaded modules are - // considered valid return addresses. - // Force scanning through three frames to ensure that the - // stack pointer is set properly in scan-recovered frames. - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x00400100; - uint32_t return_address2 = 0x00400900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D32(0x00490000) // junk that's not - .D32(0x00600000) // a return address - - .D32(frame1_sp) // stack pointer - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(16, 0) // space - - .D32(0xF0000000) // more junk - .D32(0x0000000D) - - .D32(frame2_sp) // stack pointer - .D32(return_address2) // actual return address - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.epc = 0x00405510; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - StackFrameMIPS* frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameMIPS* frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | - StackFrameMIPS::CONTEXT_VALID_SP | - StackFrameMIPS::CONTEXT_VALID_FP | - StackFrameMIPS::CONTEXT_VALID_RA), - frame1->context_validity); - EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); - - StackFrameMIPS* frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); - ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | - StackFrameMIPS::CONTEXT_VALID_SP | - StackFrameMIPS::CONTEXT_VALID_FP | - StackFrameMIPS::CONTEXT_VALID_RA), - frame2->context_validity); - EXPECT_EQ(return_address2 - 2 * sizeof(return_address2), frame2->context.epc); - EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_MIPS_REG_SP]); -} - -TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - // During stack scanning, if a potential return address - // is located within a loaded module that has symbols, - // it is only considered a valid return address if it - // lies within a function's bounds. - stack_section.start() = 0x80000000; - uint32_t return_address = 0x00500200; - Label frame1_sp; - stack_section - // frame 0 - .Append(16, 0) // space - - .D32(0x00490000) // junk that's not - .D32(0x00600000) // a return address - - .D32(0x00401000) // a couple of plausible addresses - .D32(0x0050F000) // that are not within functions - - .D32(frame1_sp) // stack pointer - .D32(return_address) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.epc = 0x00400200; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address; - - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 100 400 10 monotreme\n"); - SetModuleSymbols(&module2, - // The calling frame's function. - "FUNC 100 400 10 marsupial\n"); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameMIPS* frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - EXPECT_EQ("monotreme", frame0->function_name); - EXPECT_EQ(0x00400100U, frame0->function_base); - - StackFrameMIPS* frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | - StackFrameMIPS::CONTEXT_VALID_SP | - StackFrameMIPS::CONTEXT_VALID_FP | - StackFrameMIPS::CONTEXT_VALID_RA), - frame1->context_validity); - EXPECT_EQ(return_address - 2 * sizeof(return_address), frame1->context.epc); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); - EXPECT_EQ("marsupial", frame1->function_name); - EXPECT_EQ(0x00500100U, frame1->function_base); -} - -TEST_F(GetCallerFrame, CheckStackFrameSizeLimit) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - // If the stackwalker resorts to stack scanning, it will scan only - // 1024 bytes of stack which correspondes to maximum size of stack frame. - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x00500100; - uint32_t return_address2 = 0x00500900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(32, 0) // space - - .D32(0x00490000) // junk that's not - .D32(0x00600000) // a return address - - .Append(96, 0) // more space - - .D32(frame1_sp) // stack pointer - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(128 * 4, 0) // space - - .D32(0x00F00000) // more junk - .D32(0x0000000D) - - .Append(128 * 4, 0) // more space - - .D32(frame2_sp) // stack pointer - .D32(return_address2) // actual return address - // (won't be found) - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.epc = 0x00405510; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(2U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameMIPS* frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); - - StackFrameMIPS* frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | - StackFrameMIPS::CONTEXT_VALID_SP | - StackFrameMIPS::CONTEXT_VALID_FP | - StackFrameMIPS::CONTEXT_VALID_RA), - frame1->context_validity); - EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); - EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); -} - -// Test that set_max_frames_scanned prevents using stack scanning -// to find caller frames. -TEST_F(GetCallerFrame, ScanningNotAllowed) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - // When the stack walker resorts to scanning the stack, - // only fixed number of frames are allowed to be scanned out from stack - stack_section.start() = 0x80000000; - uint32_t return_address1 = 0x00500100; - uint32_t return_address2 = 0x00500900; - Label frame1_sp, frame2_sp; - stack_section - // frame 0 - .Append(32, 0) // space - - .D32(0x00490000) // junk that's not - .D32(0x00600000) // a return address - - .Append(96, 0) // more space - - .D32(frame1_sp) // stack pointer - .D32(return_address1) // actual return address - // frame 1 - .Mark(&frame1_sp) - .Append(128 * 4, 0) // space - - .D32(0x00F00000) // more junk - .D32(0x0000000D) - - .Append(128 * 4, 0) // more space - - .D32(frame2_sp) // stack pointer - .D32(return_address2) // actual return address - // (won't be found) - // frame 2 - .Mark(&frame2_sp) - .Append(32, 0); // end of stack - RegionFromSection(); - - raw_context.epc = 0x00405510; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - Stackwalker::set_max_frames_scanned(0); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - - StackFrameMIPS* frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); -} - -struct CFIFixture: public StackwalkerMIPSFixture { - CFIFixture() { - // Provide some STACK CFI records; - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 4000 1000 0 enchiridion\n" - // Initially, nothing has been pushed on the stack, - // and the return address is still in the $ra register. - "STACK CFI INIT 4000 1000 .cfa: $sp 0 + .ra: $ra\n" - // Move stack pointer. - "STACK CFI 4004 .cfa: $sp 32 +\n" - // store $fp and ra - "STACK CFI 4008 $fp: .cfa -8 + ^ .ra: .cfa -4 + ^\n" - // restore $fp - "STACK CFI 400c .cfa: $fp 32 +\n" - // restore $sp - "STACK CFI 4018 .cfa: $sp 32 +\n" - - "STACK CFI 4020 $fp: $fp .cfa: $sp 0 + .ra: .ra\n" - - // The calling function. - "FUNC 5000 1000 0 epictetus\n" - // Initially, nothing has been pushed on the stack, - // and the return address is still in the $ra register. - "STACK CFI INIT 5000 1000 .cfa: $sp .ra: $ra\n" - // Mark it as end of stack. - "STACK CFI INIT 5000 8 .cfa: $sp 0 + .ra: $ra\n" - - // A function whose CFI makes the stack pointer - // go backwards. - "FUNC 6000 1000 20 palinal\n" - "STACK CFI INIT 6000 1000 .cfa: $sp 4 - .ra: $ra\n" - - // A function with CFI expressions that can't be - // evaluated. - "FUNC 7000 1000 20 rhetorical\n" - "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n" - ); - - // Provide some distinctive values for the caller's registers. - expected.epc = 0x00405508; - expected.iregs[MD_CONTEXT_MIPS_REG_S0] = 0x0; - expected.iregs[MD_CONTEXT_MIPS_REG_S1] = 0x1; - expected.iregs[MD_CONTEXT_MIPS_REG_S2] = 0x2; - expected.iregs[MD_CONTEXT_MIPS_REG_S3] = 0x3; - expected.iregs[MD_CONTEXT_MIPS_REG_S4] = 0x4; - expected.iregs[MD_CONTEXT_MIPS_REG_S5] = 0x5; - expected.iregs[MD_CONTEXT_MIPS_REG_S6] = 0x6; - expected.iregs[MD_CONTEXT_MIPS_REG_S7] = 0x7; - expected.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - expected.iregs[MD_CONTEXT_MIPS_REG_FP] = 0x80000000; - expected.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; - - // Expect CFI to recover all callee-save registers. Since CFI is the - // only stack frame construction technique we have, aside from the - // context frame itself, there's no way for us to have a set of valid - // registers smaller than this. - expected_validity = (StackFrameMIPS::CONTEXT_VALID_PC | - StackFrameMIPS::CONTEXT_VALID_S0 | - StackFrameMIPS::CONTEXT_VALID_S1 | - StackFrameMIPS::CONTEXT_VALID_S2 | - StackFrameMIPS::CONTEXT_VALID_S3 | - StackFrameMIPS::CONTEXT_VALID_S4 | - StackFrameMIPS::CONTEXT_VALID_S5 | - StackFrameMIPS::CONTEXT_VALID_S6 | - StackFrameMIPS::CONTEXT_VALID_S7 | - StackFrameMIPS::CONTEXT_VALID_SP | - StackFrameMIPS::CONTEXT_VALID_FP | - StackFrameMIPS::CONTEXT_VALID_RA); - - // By default, context frames provide all registers, as normal. - context_frame_validity = StackFrameMIPS::CONTEXT_VALID_ALL; - - // By default, registers are unchanged. - raw_context = expected; - } - - // Walk the stack, using stack_section as the contents of the stack - // and raw_context as the current register values. (Set the stack - // pointer to the stack's starting address.) Expect two stack - // frames; in the older frame, expect the callee-saves registers to - // have values matching those in 'expected'. - void CheckWalk() { - RegionFromSection(); - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, - &modules, &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - StackFrameMIPS* frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ("enchiridion", frame0->function_name); - EXPECT_EQ(0x00404000U, frame0->function_base); - - StackFrameMIPS* frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ(expected_validity, frame1->context_validity); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S0], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S0]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S1], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S1]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S2], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S2]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S3], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S3]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S4], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S4]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S5], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S5]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S6], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S6]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S7], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_S7]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_FP], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_FP]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_RA], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_RA]); - EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_SP], - frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); - EXPECT_EQ(expected.epc, frame1->context.epc); - EXPECT_EQ(expected.epc, frame1->instruction); - EXPECT_EQ("epictetus", frame1->function_name); - EXPECT_EQ(0x00405000U, frame1->function_base); - } - - // The values we expect to find for the caller's registers. - MDRawContextMIPS expected; - - // The validity mask for expected. - int expected_validity; - - // The validity mask to impose on the context frame. - int context_frame_validity; -}; - -class CFI: public CFIFixture, public Test { }; - -// TODO(gordanac): add CFI tests - -TEST_F(CFI, At4004) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - Label frame1_sp = expected.iregs[MD_CONTEXT_MIPS_REG_SP]; - stack_section - // frame0 - .Append(24, 0) // space - .D32(frame1_sp) // stack pointer - .D32(0x00405510) // return address - .Mark(&frame1_sp); // This effectively sets stack_section.start(). - raw_context.epc = 0x00404004; - CheckWalk(); -} - -// Check that we reject rules that would cause the stack pointer to -// move in the wrong direction. -TEST_F(CFI, RejectBackwards) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - raw_context.epc = 0x40005000; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} - -// Check that we reject rules whose expressions' evaluation fails. -TEST_F(CFI, RejectBadExpressions) { - raw_context.context_flags = raw_context.context_flags | MD_CONTEXT_MIPS_FULL; - raw_context.epc = 0x00407000; - raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.cc deleted file mode 100644 index 7e2088440..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.cc +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_ppc.cc: ppc-specific stackwalker. -// -// See stackwalker_ppc.h for documentation. -// -// Author: Mark Mentovai - - -#include "processor/stackwalker_ppc.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/logging.h" - -namespace google_breakpad { - - -StackwalkerPPC::StackwalkerPPC(const SystemInfo* system_info, - const MDRawContextPPC* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context) { - if (memory_ && memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) { - // This implementation only covers 32-bit ppc CPUs. The limits of the - // supplied stack are invalid. Mark memory_ = NULL, which will cause - // stackwalking to fail. - BPLOG(ERROR) << "Memory out of range for stackwalking: " << - HexString(memory_->GetBase()) << "+" << - HexString(memory_->GetSize()); - memory_ = NULL; - } -} - - -StackFrame* StackwalkerPPC::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFramePPC* frame = new StackFramePPC(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFramePPC::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.srr0; - - return frame; -} - - -StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - // The instruction pointers for previous frames are saved on the stack. - // The typical ppc calling convention is for the called procedure to store - // its return address in the calling procedure's stack frame at 8(%r1), - // and to allocate its own stack frame by decrementing %r1 (the stack - // pointer) and saving the old value of %r1 at 0(%r1). Because the ppc has - // no hardware stack, there is no distinction between the stack pointer and - // frame pointer, and what is typically thought of as the frame pointer on - // an x86 is usually referred to as the stack pointer on a ppc. - - StackFramePPC* last_frame = static_cast( - stack->frames()->back()); - - // A caller frame must reside higher in memory than its callee frames. - // Anything else is an error, or an indication that we've reached the - // end of the stack. - uint32_t stack_pointer; - if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1], - &stack_pointer) || - stack_pointer <= last_frame->context.gpr[1]) { - return NULL; - } - - // Mac OS X/Darwin gives 1 as the return address from the bottom-most - // frame in a stack (a thread's entry point). I haven't found any - // documentation on this, but 0 or 1 would be bogus return addresses, - // so check for them here and return false (end of stack) when they're - // hit to avoid having a phantom frame. - uint32_t instruction; - if (!memory_->GetMemoryAtAddress(stack_pointer + 8, &instruction) || - instruction <= 1) { - return NULL; - } - - StackFramePPC* frame = new StackFramePPC(); - - frame->context = last_frame->context; - frame->context.srr0 = instruction; - frame->context.gpr[1] = stack_pointer; - frame->context_validity = StackFramePPC::CONTEXT_VALID_SRR0 | - StackFramePPC::CONTEXT_VALID_GPR1; - frame->trust = StackFrame::FRAME_TRUST_FP; - - // frame->context.srr0 is the return address, which is one instruction - // past the branch that caused us to arrive at the callee. Set - // frame_ppc->instruction to four less than that. Since all ppc - // instructions are 4 bytes wide, this is the address of the branch - // instruction. This allows source line information to match up with the - // line that contains a function call. Callers that require the exact - // return address value may access the context.srr0 field of StackFramePPC. - frame->instruction = frame->context.srr0 - 4; - - return frame; -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h deleted file mode 100644 index 012e5c32f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_ppc.h: ppc-specific stackwalker. -// -// Provides stack frames given ppc register context and a memory region -// corresponding to a ppc stack. -// -// Author: Mark Mentovai - - -#ifndef PROCESSOR_STACKWALKER_PPC_H__ -#define PROCESSOR_STACKWALKER_PPC_H__ - - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerPPC : public Stackwalker { - public: - // context is a ppc context object that gives access to ppc-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerPPC(const SystemInfo* system_info, - const MDRawContextPPC* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // Implementation of Stackwalker, using ppc context (stack pointer in %r1, - // saved program counter in %srr0) and stack conventions (saved stack - // pointer at 0(%r1), return address at 8(0(%r1)). - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextPPC* context_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_PPC_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.cc deleted file mode 100644 index 51c71fe56..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_ppc64.cc: ppc64-specific stackwalker. -// -// See stackwalker_ppc64.h for documentation. - - -#include "processor/stackwalker_ppc64.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/logging.h" - -#include - -namespace google_breakpad { - - -StackwalkerPPC64::StackwalkerPPC64(const SystemInfo* system_info, - const MDRawContextPPC64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context) { -} - - -StackFrame* StackwalkerPPC64::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFramePPC64* frame = new StackFramePPC64(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFramePPC64::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.srr0; - - return frame; -} - - -StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - // The instruction pointers for previous frames are saved on the stack. - // The typical ppc64 calling convention is for the called procedure to store - // its return address in the calling procedure's stack frame at 8(%r1), - // and to allocate its own stack frame by decrementing %r1 (the stack - // pointer) and saving the old value of %r1 at 0(%r1). Because the ppc64 has - // no hardware stack, there is no distinction between the stack pointer and - // frame pointer, and what is typically thought of as the frame pointer on - // an x86 is usually referred to as the stack pointer on a ppc64. - - StackFramePPC64* last_frame = static_cast( - stack->frames()->back()); - - // A caller frame must reside higher in memory than its callee frames. - // Anything else is an error, or an indication that we've reached the - // end of the stack. - uint64_t stack_pointer; - if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1], - &stack_pointer) || - stack_pointer <= last_frame->context.gpr[1]) { - return NULL; - } - - // Mac OS X/Darwin gives 1 as the return address from the bottom-most - // frame in a stack (a thread's entry point). I haven't found any - // documentation on this, but 0 or 1 would be bogus return addresses, - // so check for them here and return false (end of stack) when they're - // hit to avoid having a phantom frame. - uint64_t instruction; - if (!memory_->GetMemoryAtAddress(stack_pointer + 16, &instruction) || - instruction <= 1) { - return NULL; - } - - StackFramePPC64* frame = new StackFramePPC64(); - - frame->context = last_frame->context; - frame->context.srr0 = instruction; - frame->context.gpr[1] = stack_pointer; - frame->context_validity = StackFramePPC64::CONTEXT_VALID_SRR0 | - StackFramePPC64::CONTEXT_VALID_GPR1; - frame->trust = StackFrame::FRAME_TRUST_FP; - - // frame->context.srr0 is the return address, which is one instruction - // past the branch that caused us to arrive at the callee. Set - // frame_ppc64->instruction to eight less than that. Since all ppc64 - // instructions are 8 bytes wide, this is the address of the branch - // instruction. This allows source line information to match up with the - // line that contains a function call. Callers that require the exact - // return address value may access the context.srr0 field of StackFramePPC64. - frame->instruction = frame->context.srr0 - 8; - - return frame; -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.h deleted file mode 100644 index a406343af..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2013 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_ppc64.h: ppc-specific stackwalker. -// -// Provides stack frames given ppc64 register context and a memory region -// corresponding to a ppc64 stack. - - -#ifndef PROCESSOR_STACKWALKER_PPC64_H__ -#define PROCESSOR_STACKWALKER_PPC64_H__ - - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerPPC64 : public Stackwalker { - public: - // context is a ppc64 context object that gives access to ppc64-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerPPC64(const SystemInfo* system_info, - const MDRawContextPPC64* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // Implementation of Stackwalker, using ppc64 context (stack pointer in %r1, - // saved program counter in %srr0) and stack conventions (saved stack - // pointer at 0(%r1), return address at 8(0(%r1)). - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextPPC64* context_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_PPC64_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest.cc deleted file mode 100644 index f692d4c4c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest.cc +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_selftest.cc: Tests StackwalkerX86 or StackwalkerPPC using the -// running process' stack as test data, if running on an x86 or ppc and -// compiled with gcc. This test is not enabled in the "make check" suite -// by default, because certain optimizations interfere with its proper -// operation. To turn it on, configure with --enable-selftest. -// -// Optimizations that cause problems: -// - stack frame reuse. The Recursor function here calls itself with -// |return Recursor|. When the caller's frame is reused, it will cause -// CountCallerFrames to correctly return the same number of frames -// in both the caller and callee. This is considered an unexpected -// condition in the test, which expects a callee to have one more -// caller frame in the stack than its caller. -// - frame pointer omission. Even with a stackwalker that understands -// this optimization, the code to harness debug information currently -// only exists to retrieve it from minidumps, not the current process. -// -// This test can also serve as a developmental and debugging aid if -// PRINT_STACKS is defined. -// -// Author: Mark Mentovai - -#include - -#include "processor/logging.h" - -#if defined(__i386) && !defined(__i386__) -#define __i386__ -#endif -#if defined(__sparc) && !defined(__sparc__) -#define __sparc__ -#endif - -#if (defined(__SUNPRO_CC) || defined(__GNUC__)) && \ - (defined(__i386__) || defined(__ppc__) || defined(__sparc__)) - - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/stack_frame.h" -#include "google_breakpad/processor/stack_frame_cpu.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::MemoryRegion; -using google_breakpad::scoped_ptr; -using google_breakpad::StackFrame; -using google_breakpad::StackFramePPC; -using google_breakpad::StackFrameX86; -using google_breakpad::StackFrameSPARC; - -#if defined(__i386__) -#include "processor/stackwalker_x86.h" -using google_breakpad::StackwalkerX86; -#elif defined(__ppc__) -#include "processor/stackwalker_ppc.h" -using google_breakpad::StackwalkerPPC; -#elif defined(__sparc__) -#include "processor/stackwalker_sparc.h" -using google_breakpad::StackwalkerSPARC; -#endif // __i386__ || __ppc__ || __sparc__ - -#define RECURSION_DEPTH 100 - - -// A simple MemoryRegion subclass that provides direct access to this -// process' memory space by pointer. -class SelfMemoryRegion : public MemoryRegion { - public: - virtual uint64_t GetBase() const { return 0; } - virtual uint32_t GetSize() const { return 0xffffffff; } - - bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const { - return GetMemoryAtAddressInternal(address, value); } - bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const { - return GetMemoryAtAddressInternal(address, value); } - bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const { - return GetMemoryAtAddressInternal(address, value); } - bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const { - return GetMemoryAtAddressInternal(address, value); } - void Print() const { - assert(false); - } - - private: - template bool GetMemoryAtAddressInternal(uint64_t address, - T* value) { - // Without knowing what addresses are actually mapped, just assume that - // everything low is not mapped. This helps the stackwalker catch the - // end of a stack when it tries to dereference a null or low pointer - // in an attempt to find the caller frame. Other unmapped accesses will - // cause the program to crash, but that would properly be a test failure. - if (address < 0x100) - return false; - - uint8_t* memory = 0; - *value = *reinterpret_cast(&memory[address]); - return true; - } -}; - - -#if defined(__GNUC__) - - -#if defined(__i386__) - -// GetEBP returns the current value of the %ebp register. Because it's -// implemented as a function, %ebp itself contains GetEBP's frame pointer -// and not the caller's frame pointer. Dereference %ebp to obtain the -// caller's frame pointer, which the compiler-generated preamble stored -// on the stack (provided frame pointers are not being omitted.) Because -// this function depends on the compiler-generated preamble, inlining is -// disabled. -static uint32_t GetEBP() __attribute__((noinline)); -static uint32_t GetEBP() { - uint32_t ebp; - __asm__ __volatile__( - "movl (%%ebp), %0" - : "=a" (ebp) - ); - return ebp; -} - - -// The caller's %esp is 8 higher than the value of %ebp in this function, -// assuming that it's not inlined and that the standard prolog is used. -// The CALL instruction places a 4-byte return address on the stack above -// the caller's %esp, and this function's prolog will save the caller's %ebp -// on the stack as well, for another 4 bytes, before storing %esp in %ebp. -static uint32_t GetESP() __attribute__((noinline)); -static uint32_t GetESP() { - uint32_t ebp; - __asm__ __volatile__( - "movl %%ebp, %0" - : "=a" (ebp) - ); - return ebp + 8; -} - - -// GetEIP returns the instruction pointer identifying the next instruction -// to execute after GetEIP returns. It obtains this information from the -// stack, where it was placed by the call instruction that called GetEIP. -// This function depends on frame pointers not being omitted. It is possible -// to write a pure asm version of this routine that has no compiler-generated -// preamble and uses %esp instead of %ebp; that would function in the -// absence of frame pointers. However, the simpler approach is used here -// because GetEBP and stackwalking necessarily depends on access to frame -// pointers. Because this function depends on a call instruction and the -// compiler-generated preamble, inlining is disabled. -static uint32_t GetEIP() __attribute__((noinline)); -static uint32_t GetEIP() { - uint32_t eip; - __asm__ __volatile__( - "movl 4(%%ebp), %0" - : "=a" (eip) - ); - return eip; -} - - -#elif defined(__ppc__) - - -// GetSP returns the current value of the %r1 register, which by convention, -// is the stack pointer on ppc. Because it's implemented as a function, -// %r1 itself contains GetSP's own stack pointer and not the caller's stack -// pointer. Dereference %r1 to obtain the caller's stack pointer, which the -// compiler-generated prolog stored on the stack. Because this function -// depends on the compiler-generated prolog, inlining is disabled. -static uint32_t GetSP() __attribute__((noinline)); -static uint32_t GetSP() { - uint32_t sp; - __asm__ __volatile__( - "lwz %0, 0(r1)" - : "=r" (sp) - ); - return sp; -} - - -// GetPC returns the program counter identifying the next instruction to -// execute after GetPC returns. It obtains this information from the -// link register, where it was placed by the branch instruction that called -// GetPC. Because this function depends on the caller's use of a branch -// instruction, inlining is disabled. -static uint32_t GetPC() __attribute__((noinline)); -static uint32_t GetPC() { - uint32_t lr; - __asm__ __volatile__( - "mflr %0" - : "=r" (lr) - ); - return lr; -} - - -#elif defined(__sparc__) - - -// GetSP returns the current value of the %sp/%o6/%g_r[14] register, which -// by convention, is the stack pointer on sparc. Because it's implemented -// as a function, %sp itself contains GetSP's own stack pointer and not -// the caller's stack pointer. Dereference to obtain the caller's stack -// pointer, which the compiler-generated prolog stored on the stack. -// Because this function depends on the compiler-generated prolog, inlining -// is disabled. -static uint32_t GetSP() __attribute__((noinline)); -static uint32_t GetSP() { - uint32_t sp; - __asm__ __volatile__( - "mov %%fp, %0" - : "=r" (sp) - ); - return sp; -} - -// GetFP returns the current value of the %fp register. Because it's -// implemented as a function, %fp itself contains GetFP's frame pointer -// and not the caller's frame pointer. Dereference %fp to obtain the -// caller's frame pointer, which the compiler-generated preamble stored -// on the stack (provided frame pointers are not being omitted.) Because -// this function depends on the compiler-generated preamble, inlining is -// disabled. -static uint32_t GetFP() __attribute__((noinline)); -static uint32_t GetFP() { - uint32_t fp; - __asm__ __volatile__( - "ld [%%fp+56], %0" - : "=r" (fp) - ); - return fp; -} - -// GetPC returns the program counter identifying the next instruction to -// execute after GetPC returns. It obtains this information from the -// link register, where it was placed by the branch instruction that called -// GetPC. Because this function depends on the caller's use of a branch -// instruction, inlining is disabled. -static uint32_t GetPC() __attribute__((noinline)); -static uint32_t GetPC() { - uint32_t pc; - __asm__ __volatile__( - "mov %%i7, %0" - : "=r" (pc) - ); - return pc + 8; -} - -#endif // __i386__ || __ppc__ || __sparc__ - -#elif defined(__SUNPRO_CC) - -#if defined(__i386__) -extern "C" { -extern uint32_t GetEIP(); -extern uint32_t GetEBP(); -extern uint32_t GetESP(); -} -#elif defined(__sparc__) -extern "C" { -extern uint32_t GetPC(); -extern uint32_t GetFP(); -extern uint32_t GetSP(); -} -#endif // __i386__ || __sparc__ - -#endif // __GNUC__ || __SUNPRO_CC - -// CountCallerFrames returns the number of stack frames beneath the function -// that called CountCallerFrames. Because this function's return value -// is dependent on the size of the stack beneath it, inlining is disabled, -// and any function that calls this should not be inlined either. -#if defined(__GNUC__) -static unsigned int CountCallerFrames() __attribute__((noinline)); -#elif defined(__SUNPRO_CC) -static unsigned int CountCallerFrames(); -#endif -static unsigned int CountCallerFrames() { - SelfMemoryRegion memory; - BasicSourceLineResolver resolver; - -#if defined(__i386__) - MDRawContextX86 context = MDRawContextX86(); - context.eip = GetEIP(); - context.ebp = GetEBP(); - context.esp = GetESP(); - - StackwalkerX86 stackwalker = StackwalkerX86(NULL, &context, &memory, NULL, - NULL, &resolver); -#elif defined(__ppc__) - MDRawContextPPC context = MDRawContextPPC(); - context.srr0 = GetPC(); - context.gpr[1] = GetSP(); - - StackwalkerPPC stackwalker = StackwalkerPPC(NULL, &context, &memory, NULL, - NULL, &resolver); -#elif defined(__sparc__) - MDRawContextSPARC context = MDRawContextSPARC(); - context.pc = GetPC(); - context.g_r[14] = GetSP(); - context.g_r[30] = GetFP(); - - StackwalkerSPARC stackwalker = StackwalkerSPARC(NULL, &context, &memory, - NULL, NULL, &resolver); -#endif // __i386__ || __ppc__ || __sparc__ - - CallStack stack; - vector modules_without_symbols; - stackwalker.Walk(&stack, &modules_without_symbols); - -#ifdef PRINT_STACKS - printf("\n"); - for (unsigned int frame_index = 0; - frame_index < stack.frames()->size(); - ++frame_index) { - StackFrame *frame = stack.frames()->at(frame_index); - printf("frame %-3d instruction = 0x%08" PRIx64, - frame_index, frame->instruction); -#if defined(__i386__) - StackFrameX86 *frame_x86 = reinterpret_cast(frame); - printf(" esp = 0x%08x ebp = 0x%08x\n", - frame_x86->context.esp, frame_x86->context.ebp); -#elif defined(__ppc__) - StackFramePPC *frame_ppc = reinterpret_cast(frame); - printf(" gpr[1] = 0x%08x\n", frame_ppc->context.gpr[1]); -#elif defined(__sparc__) - StackFrameSPARC *frame_sparc = reinterpret_cast(frame); - printf(" sp = 0x%08x fp = 0x%08x\n", - frame_sparc->context.g_r[14], frame_sparc->context.g_r[30]); -#endif // __i386__ || __ppc__ || __sparc__ - } -#endif // PRINT_STACKS - - // Subtract 1 because the caller wants the number of frames beneath - // itself. Because the caller called us, subract two for our frame and its - // frame, which are included in stack.size(). - return stack.frames()->size() - 2; -} - - -// Recursor verifies that the number stack frames beneath itself is one more -// than the number of stack frames beneath its parent. When depth frames -// have been reached, Recursor stops checking and returns success. If the -// frame count check fails at any depth, Recursor will stop and return false. -// Because this calls CountCallerFrames, inlining is disabled. -#if defined(__GNUC__) -static bool Recursor(unsigned int depth, unsigned int parent_callers) - __attribute__((noinline)); -#elif defined(__SUNPRO_CC) -static bool Recursor(unsigned int depth, unsigned int parent_callers); -#endif -static bool Recursor(unsigned int depth, unsigned int parent_callers) { - unsigned int callers = CountCallerFrames(); - if (callers != parent_callers + 1) - return false; - - if (depth) - return Recursor(depth - 1, callers); - - // depth == 0 - return true; -} - - -// Because this calls CountCallerFrames, inlining is disabled - but because -// it's main (and nobody calls it other than the entry point), it wouldn't -// be inlined anyway. -#if defined(__GNUC__) -int main(int argc, char** argv) __attribute__((noinline)); -#elif defined(__SUNPRO_CC) -int main(int argc, char** argv); -#endif -int main(int argc, char** argv) { - BPLOG_INIT(&argc, &argv); - - return Recursor(RECURSION_DEPTH, CountCallerFrames()) ? 0 : 1; -} - - -#else -// Not i386 or ppc or sparc? We can only test stacks we know how to walk. - - -int main(int argc, char **argv) { - BPLOG_INIT(&argc, &argv); - - // "make check" interprets an exit status of 77 to mean that the test is - // not supported. - BPLOG(ERROR) << "Selftest not supported here"; - return 77; -} - - -#endif // (__GNUC__ || __SUNPRO_CC) && (__i386__ || __ppc__ || __sparc__) diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest_sol.s b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest_sol.s deleted file mode 100644 index 648b0499a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest_sol.s +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2007, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* stackwalker_selftest_sol.s - * On Solaris, the recommeded compiler is CC, so we can not use gcc inline - * asm, use this method instead. - * - * How to compile: as -P -L -D_ASM -D_STDC -K PIC -o \ - * src/processor/stackwalker_selftest_sol.o \ - * src/processor/stackwalker_selftest_sol.s - * - * Author: Michael Shang - */ - -#include - -#if defined(__i386) - - -ENTRY(GetEBP) - pushl %ebp - movl %esp,%ebp - subl $0x00000004,%esp - movl 0x00000000(%ebp),%eax - movl %eax,0xfffffffc(%ebp) - movl 0xfffffffc(%ebp),%eax - leave - ret -SET_SIZE(GetEBP) - -ENTRY(GetEIP) - pushl %ebp - movl %esp,%ebp - subl $0x00000004,%esp - movl 0x00000004(%ebp),%eax - movl %eax,0xfffffffc(%ebp) - movl 0xfffffffc(%ebp),%eax - leave - ret -SET_SIZE(GetEIP) - -ENTRY(GetESP) - pushl %ebp - movl %esp,%ebp - subl $0x00000004,%esp - movl %ebp,%eax - movl %eax,0xfffffffc(%ebp) - movl 0xfffffffc(%ebp),%eax - addl $0x00000008,%eax - leave - ret -SET_SIZE(GetESP) - - -#elif defined(__sparc) - - -ENTRY(GetPC) - save %sp, -120, %sp - mov %i7, %i4 - inccc 8, %i4 - mov %i4, %i0 - ret - restore -SET_SIZE(GetPC) - -ENTRY(GetSP) - save %sp, -120, %sp - mov %fp, %i4 - mov %i4, %i0 - ret - restore -SET_SIZE(GetSP) - -ENTRY(GetFP) - save %sp, -120, %sp - ld [%fp + 56], %g1 - mov %g1, %i0 - ret - restore -SET_SIZE(GetFP) - - -#endif // __i386 || __sparc diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.cc deleted file mode 100644 index ff2ea75a8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.cc +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_sparc.cc: sparc-specific stackwalker. -// -// See stackwalker_sparc.h for documentation. -// -// Author: Michael Shang - - -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/logging.h" -#include "processor/stackwalker_sparc.h" - -namespace google_breakpad { - - -StackwalkerSPARC::StackwalkerSPARC(const SystemInfo* system_info, - const MDRawContextSPARC* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context) { -} - - -StackFrame* StackwalkerSPARC::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFrameSPARC* frame = new StackFrameSPARC(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFrameSPARC::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.pc; - - return frame; -} - - -StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - StackFrameSPARC* last_frame = static_cast( - stack->frames()->back()); - - // new: caller - // old: callee - // %fp, %i6 and g_r[30] is the same, see minidump_format.h - // %sp, %o6 and g_r[14] is the same, see minidump_format.h - // %sp_new = %fp_old - // %fp_new = *(%fp_old + 32 + 32 - 8), where the callee's %i6 - // %pc_new = *(%fp_old + 32 + 32 - 4) + 8 - // which is callee's %i7 plus 8 - - // A caller frame must reside higher in memory than its callee frames. - // Anything else is an error, or an indication that we've reached the - // end of the stack. - uint64_t stack_pointer = last_frame->context.g_r[30]; - if (stack_pointer <= last_frame->context.g_r[14]) { - return NULL; - } - - uint32_t instruction; - if (!memory_->GetMemoryAtAddress(stack_pointer + 60, - &instruction) || instruction <= 1) { - return NULL; - } - - uint32_t stack_base; - if (!memory_->GetMemoryAtAddress(stack_pointer + 56, - &stack_base) || stack_base <= 1) { - return NULL; - } - - StackFrameSPARC* frame = new StackFrameSPARC(); - - frame->context = last_frame->context; - frame->context.g_r[14] = stack_pointer; - frame->context.g_r[30] = stack_base; - - // frame->context.pc is the return address, which is 2 instruction - // past the branch that caused us to arrive at the callee, which are - // a CALL instruction then a NOP instruction. - // frame_ppc->instruction to 8 less than that. Since all sparc - // instructions are 4 bytes wide, this is the address of the branch - // instruction. This allows source line information to match up with the - // line that contains a function call. Callers that require the exact - // return address value may access the %i7/g_r[31] field of StackFrameSPARC. - frame->context.pc = instruction + 8; - frame->instruction = instruction; - frame->context_validity = StackFrameSPARC::CONTEXT_VALID_PC | - StackFrameSPARC::CONTEXT_VALID_SP | - StackFrameSPARC::CONTEXT_VALID_FP; - frame->trust = StackFrame::FRAME_TRUST_FP; - - return frame; -} - - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h deleted file mode 100644 index e8f2a3888..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_sparc.h: sparc-specific stackwalker. -// -// Provides stack frames given sparc register context and a memory region -// corresponding to an sparc stack. -// -// Author: Michael Shang - - -#ifndef PROCESSOR_STACKWALKER_SPARC_H__ -#define PROCESSOR_STACKWALKER_SPARC_H__ - - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" - -namespace google_breakpad { - -class CodeModules; - -class StackwalkerSPARC : public Stackwalker { - public: - // context is a sparc context object that gives access to sparc-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerSPARC(const SystemInfo* system_info, - const MDRawContextSPARC* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // Implementation of Stackwalker, using sparc context (%fp, %sp, %pc) and - // stack conventions - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextSPARC* context_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_SPARC_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h deleted file mode 100644 index ee22a8fe1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h +++ /dev/null @@ -1,224 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// Mock classes for writing stackwalker tests, shared amongst architectures. - -#ifndef PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ -#define PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ - -#include -#include -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/symbol_supplier.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/linked_ptr.h" - -class MockMemoryRegion: public google_breakpad::MemoryRegion { - public: - MockMemoryRegion(): base_address_(0) { } - - // Set this region's address and contents. If we have placed an - // instance of this class in a test fixture class, individual tests - // can use this to provide the region's contents. - void Init(uint64_t base_address, const string &contents) { - base_address_ = base_address; - contents_ = contents; - } - - uint64_t GetBase() const { return base_address_; } - uint32_t GetSize() const { return contents_.size(); } - - bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { - return GetMemoryLittleEndian(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { - return GetMemoryLittleEndian(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { - return GetMemoryLittleEndian(address, value); - } - bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { - return GetMemoryLittleEndian(address, value); - } - void Print() const { - assert(false); - } - - private: - // Fetch a little-endian value from ADDRESS in contents_ whose size - // is BYTES, and store it in *VALUE. Return true on success. - template - bool GetMemoryLittleEndian(uint64_t address, ValueType *value) const { - if (address < base_address_ || - address - base_address_ + sizeof(ValueType) > contents_.size()) - return false; - ValueType v = 0; - int start = address - base_address_; - // The loop condition is odd, but it's correct for size_t. - for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--) - v = (v << 8) | static_cast(contents_[start + i]); - *value = v; - return true; - } - - uint64_t base_address_; - string contents_; -}; - -class MockCodeModule: public google_breakpad::CodeModule { - public: - MockCodeModule(uint64_t base_address, uint64_t size, - const string &code_file, const string &version) - : base_address_(base_address), size_(size), code_file_(code_file) { } - - uint64_t base_address() const { return base_address_; } - uint64_t size() const { return size_; } - string code_file() const { return code_file_; } - string code_identifier() const { return code_file_; } - string debug_file() const { return code_file_; } - string debug_identifier() const { return code_file_; } - string version() const { return version_; } - google_breakpad::CodeModule *Copy() const { - abort(); // Tests won't use this. - } - virtual uint64_t shrink_down_delta() const { return 0; } - virtual void SetShrinkDownDelta(uint64_t shrink_down_delta) {} - - private: - uint64_t base_address_; - uint64_t size_; - string code_file_; - string version_; -}; - -class MockCodeModules: public google_breakpad::CodeModules { - public: - typedef google_breakpad::CodeModule CodeModule; - typedef google_breakpad::CodeModules CodeModules; - - void Add(const MockCodeModule *module) { - modules_.push_back(module); - } - - unsigned int module_count() const { return modules_.size(); } - - const CodeModule *GetModuleForAddress(uint64_t address) const { - for (ModuleVector::const_iterator i = modules_.begin(); - i != modules_.end(); i++) { - const MockCodeModule *module = *i; - if (module->base_address() <= address && - address - module->base_address() < module->size()) - return module; - } - return NULL; - }; - - const CodeModule *GetMainModule() const { return modules_[0]; } - - const CodeModule *GetModuleAtSequence(unsigned int sequence) const { - return modules_.at(sequence); - } - - const CodeModule *GetModuleAtIndex(unsigned int index) const { - return modules_.at(index); - } - - CodeModules *Copy() const { abort(); } // Tests won't use this - - virtual std::vector > - GetShrunkRangeModules() const { - return std::vector >(); - } - - // Returns true, if module address range shrink is enabled. - bool IsModuleShrinkEnabled() const { - return false; - } - - private: - typedef std::vector ModuleVector; - ModuleVector modules_; -}; - -class MockSymbolSupplier: public google_breakpad::SymbolSupplier { - public: - typedef google_breakpad::CodeModule CodeModule; - typedef google_breakpad::SystemInfo SystemInfo; - MOCK_METHOD3(GetSymbolFile, SymbolResult(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file)); - MOCK_METHOD4(GetSymbolFile, SymbolResult(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data)); - MOCK_METHOD5(GetCStringSymbolData, SymbolResult(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size)); - MOCK_METHOD1(FreeSymbolData, void(const CodeModule *module)); - - // Copies the passed string contents into a newly allocated buffer. - // The newly allocated buffer will be freed during destruction. - char* CopySymbolDataAndOwnTheCopy(const std::string &info, - size_t *symbol_data_size) { - *symbol_data_size = info.size() + 1; - char *symbol_data = new char[*symbol_data_size]; - memcpy(symbol_data, info.c_str(), info.size()); - symbol_data[info.size()] = '\0'; - symbol_data_to_free_.push_back(symbol_data); - return symbol_data; - } - - virtual ~MockSymbolSupplier() { - for (SymbolDataVector::const_iterator i = symbol_data_to_free_.begin(); - i != symbol_data_to_free_.end(); i++) { - char* symbol_data = *i; - delete [] symbol_data; - } - } - - private: - // List of symbol data to be freed upon destruction - typedef std::vector SymbolDataVector; - SymbolDataVector symbol_data_to_free_; -}; - -#endif // PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc deleted file mode 100644 index 29d98e4b8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_x86.cc: x86-specific stackwalker. -// -// See stackwalker_x86.h for documentation. -// -// Author: Mark Mentovai - -#include -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_modules.h" -#include "google_breakpad/processor/memory_region.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/logging.h" -#include "processor/postfix_evaluator-inl.h" -#include "processor/stackwalker_x86.h" -#include "processor/windows_frame_info.h" -#include "processor/cfi_frame_info.h" - -namespace google_breakpad { - -// Max reasonable size for a single x86 frame is 128 KB. This value is used in -// a heuristic for recovering of the EBP chain after a scan for return address. -// This value is based on a stack frame size histogram built for a set of -// popular third party libraries which suggests that 99.5% of all frames are -// smaller than 128 KB. -static const uint32_t kMaxReasonableGapBetweenFrames = 128 * 1024; - -const StackwalkerX86::CFIWalker::RegisterSet -StackwalkerX86::cfi_register_map_[] = { - // It may seem like $eip and $esp are callee-saves, because (with Unix or - // cdecl calling conventions) the callee is responsible for having them - // restored upon return. But the callee_saves flags here really means - // that the walker should assume they're unchanged if the CFI doesn't - // mention them, which is clearly wrong for $eip and $esp. - { "$eip", ".ra", false, - StackFrameX86::CONTEXT_VALID_EIP, &MDRawContextX86::eip }, - { "$esp", ".cfa", false, - StackFrameX86::CONTEXT_VALID_ESP, &MDRawContextX86::esp }, - { "$ebp", NULL, true, - StackFrameX86::CONTEXT_VALID_EBP, &MDRawContextX86::ebp }, - { "$eax", NULL, false, - StackFrameX86::CONTEXT_VALID_EAX, &MDRawContextX86::eax }, - { "$ebx", NULL, true, - StackFrameX86::CONTEXT_VALID_EBX, &MDRawContextX86::ebx }, - { "$ecx", NULL, false, - StackFrameX86::CONTEXT_VALID_ECX, &MDRawContextX86::ecx }, - { "$edx", NULL, false, - StackFrameX86::CONTEXT_VALID_EDX, &MDRawContextX86::edx }, - { "$esi", NULL, true, - StackFrameX86::CONTEXT_VALID_ESI, &MDRawContextX86::esi }, - { "$edi", NULL, true, - StackFrameX86::CONTEXT_VALID_EDI, &MDRawContextX86::edi }, -}; - -StackwalkerX86::StackwalkerX86(const SystemInfo* system_info, - const MDRawContextX86* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* resolver_helper) - : Stackwalker(system_info, memory, modules, resolver_helper), - context_(context), - cfi_walker_(cfi_register_map_, - (sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) { - if (memory_ && memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) { - // The x86 is a 32-bit CPU, the limits of the supplied stack are invalid. - // Mark memory_ = NULL, which will cause stackwalking to fail. - BPLOG(ERROR) << "Memory out of range for stackwalking: " << - HexString(memory_->GetBase()) << "+" << - HexString(memory_->GetSize()); - memory_ = NULL; - } -} - -StackFrameX86::~StackFrameX86() { - if (windows_frame_info) - delete windows_frame_info; - windows_frame_info = NULL; - if (cfi_frame_info) - delete cfi_frame_info; - cfi_frame_info = NULL; -} - -uint64_t StackFrameX86::ReturnAddress() const { - assert(context_validity & StackFrameX86::CONTEXT_VALID_EIP); - return context.eip; -} - -StackFrame* StackwalkerX86::GetContextFrame() { - if (!context_) { - BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; - } - - StackFrameX86* frame = new StackFrameX86(); - - // The instruction pointer is stored directly in a register, so pull it - // straight out of the CPU context structure. - frame->context = *context_; - frame->context_validity = StackFrameX86::CONTEXT_VALID_ALL; - frame->trust = StackFrame::FRAME_TRUST_CONTEXT; - frame->instruction = frame->context.eip; - - return frame; -} - -StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( - const vector &frames, - WindowsFrameInfo* last_frame_info, - bool stack_scan_allowed) { - StackFrame::FrameTrust trust = StackFrame::FRAME_TRUST_NONE; - - StackFrameX86* last_frame = static_cast(frames.back()); - - // Save the stack walking info we found, in case we need it later to - // find the callee of the frame we're constructing now. - last_frame->windows_frame_info = last_frame_info; - - // This function only covers the full STACK WIN case. If - // last_frame_info is VALID_PARAMETER_SIZE-only, then we should - // assume the traditional frame format or use some other strategy. - if (last_frame_info->valid != WindowsFrameInfo::VALID_ALL) - return NULL; - - // This stackwalker sets each frame's %esp to its value immediately prior - // to the CALL into the callee. This means that %esp points to the last - // callee argument pushed onto the stack, which may not be where %esp points - // after the callee returns. Specifically, the value is correct for the - // cdecl calling convention, but not other conventions. The cdecl - // convention requires a caller to pop its callee's arguments from the - // stack after the callee returns. This is usually accomplished by adding - // the known size of the arguments to %esp. Other calling conventions, - // including stdcall, thiscall, and fastcall, require the callee to pop any - // parameters stored on the stack before returning. This is usually - // accomplished by using the RET n instruction, which pops n bytes off - // the stack after popping the return address. - // - // Because each frame's %esp will point to a location on the stack after - // callee arguments have been PUSHed, when locating things in a stack frame - // relative to %esp, the size of the arguments to the callee need to be - // taken into account. This seems a little bit unclean, but it's better - // than the alternative, which would need to take these same things into - // account, but only for cdecl functions. With this implementation, we get - // to be agnostic about each function's calling convention. Furthermore, - // this is how Windows debugging tools work, so it means that the %esp - // values produced by this stackwalker directly correspond to the %esp - // values you'll see there. - // - // If the last frame has no callee (because it's the context frame), just - // set the callee parameter size to 0: the stack pointer can't point to - // callee arguments because there's no callee. This is correct as long - // as the context wasn't captured while arguments were being pushed for - // a function call. Note that there may be functions whose parameter sizes - // are unknown, 0 is also used in that case. When that happens, it should - // be possible to walk to the next frame without reference to %esp. - - uint32_t last_frame_callee_parameter_size = 0; - int frames_already_walked = frames.size(); - if (frames_already_walked >= 2) { - const StackFrameX86* last_frame_callee - = static_cast(frames[frames_already_walked - 2]); - WindowsFrameInfo* last_frame_callee_info - = last_frame_callee->windows_frame_info; - if (last_frame_callee_info && - (last_frame_callee_info->valid - & WindowsFrameInfo::VALID_PARAMETER_SIZE)) { - last_frame_callee_parameter_size = - last_frame_callee_info->parameter_size; - } - } - - // Set up the dictionary for the PostfixEvaluator. %ebp and %esp are used - // in each program string, and their previous values are known, so set them - // here. - PostfixEvaluator::DictionaryType dictionary; - // Provide the current register values. - dictionary["$ebp"] = last_frame->context.ebp; - dictionary["$esp"] = last_frame->context.esp; - // Provide constants from the debug info for last_frame and its callee. - // .cbCalleeParams is a Breakpad extension that allows us to use the - // PostfixEvaluator engine when certain types of debugging information - // are present without having to write the constants into the program - // string as literals. - dictionary[".cbCalleeParams"] = last_frame_callee_parameter_size; - dictionary[".cbSavedRegs"] = last_frame_info->saved_register_size; - dictionary[".cbLocals"] = last_frame_info->local_size; - - uint32_t raSearchStart = last_frame->context.esp + - last_frame_callee_parameter_size + - last_frame_info->local_size + - last_frame_info->saved_register_size; - - uint32_t raSearchStartOld = raSearchStart; - uint32_t found = 0; // dummy value - // Scan up to three words above the calculated search value, in case - // the stack was aligned to a quadword boundary. - // - // TODO(ivan.penkov): Consider cleaning up the scan for return address that - // follows. The purpose of this scan is to adjust the .raSearchStart - // calculation (which is based on register %esp) in the cases where register - // %esp may have been aligned (up to a quadword). There are two problems - // with this approach: - // 1) In practice, 64 byte boundary alignment is seen which clearly can not - // be handled by a three word scan. - // 2) A search for a return address is "guesswork" by definition because - // the results will be different depending on what is left on the stack - // from previous executions. - // So, basically, the results from this scan should be ignored if other means - // for calculation of the value of .raSearchStart are available. - if (ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3) && - last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT && - last_frame->windows_frame_info != NULL && - last_frame_info->type_ == WindowsFrameInfo::STACK_INFO_FPO && - raSearchStartOld == raSearchStart && - found == last_frame->context.eip) { - // The context frame represents an FPO-optimized Windows system call. - // On the top of the stack we have a pointer to the current instruction. - // This means that the callee has returned but the return address is still - // on the top of the stack which is very atypical situaltion. - // Skip one slot from the stack and do another scan in order to get the - // actual return address. - raSearchStart += 4; - ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3); - } - - dictionary[".cbParams"] = last_frame_info->parameter_size; - - // Decide what type of program string to use. The program string is in - // postfix notation and will be passed to PostfixEvaluator::Evaluate. - // Given the dictionary and the program string, it is possible to compute - // the return address and the values of other registers in the calling - // function. Because of bugs described below, the stack may need to be - // scanned for these values. The results of program string evaluation - // will be used to determine whether to scan for better values. - string program_string; - bool recover_ebp = true; - - trust = StackFrame::FRAME_TRUST_CFI; - if (!last_frame_info->program_string.empty()) { - // The FPO data has its own program string, which will tell us how to - // get to the caller frame, and may even fill in the values of - // nonvolatile registers and provide pointers to local variables and - // parameters. In some cases, particularly with program strings that use - // .raSearchStart, the stack may need to be scanned afterward. - program_string = last_frame_info->program_string; - } else if (last_frame_info->allocates_base_pointer) { - // The function corresponding to the last frame doesn't use the frame - // pointer for conventional purposes, but it does allocate a new - // frame pointer and use it for its own purposes. Its callee's - // information is still accessed relative to %esp, and the previous - // value of %ebp can be recovered from a location in its stack frame, - // within the saved-register area. - // - // Functions that fall into this category use the %ebp register for - // a purpose other than the frame pointer. They restore the caller's - // %ebp before returning. These functions create their stack frame - // after a CALL by decrementing the stack pointer in an amount - // sufficient to store local variables, and then PUSHing saved - // registers onto the stack. Arguments to a callee function, if any, - // are PUSHed after that. Walking up to the caller, therefore, - // can be done solely with calculations relative to the stack pointer - // (%esp). The return address is recovered from the memory location - // above the known sizes of the callee's parameters, saved registers, - // and locals. The caller's stack pointer (the value of %esp when - // the caller executed CALL) is the location immediately above the - // saved return address. The saved value of %ebp to be restored for - // the caller is at a known location in the saved-register area of - // the stack frame. - // - // For this type of frame, MSVC 14 (from Visual Studio 8/2005) in - // link-time code generation mode (/LTCG and /GL) can generate erroneous - // debugging data. The reported size of saved registers can be 0, - // which is clearly an error because these frames must, at the very - // least, save %ebp. For this reason, in addition to those given above - // about the use of .raSearchStart, the stack may need to be scanned - // for a better return address and a better frame pointer after the - // program string is evaluated. - // - // %eip_new = *(%esp_old + callee_params + saved_regs + locals) - // %ebp_new = *(%esp_old + callee_params + saved_regs - 8) - // %esp_new = %esp_old + callee_params + saved_regs + locals + 4 - program_string = "$eip .raSearchStart ^ = " - "$ebp $esp .cbCalleeParams + .cbSavedRegs + 8 - ^ = " - "$esp .raSearchStart 4 + ="; - } else { - // The function corresponding to the last frame doesn't use %ebp at - // all. The callee frame is located relative to %esp. - // - // The called procedure's instruction pointer and stack pointer are - // recovered in the same way as the case above, except that no - // frame pointer (%ebp) is used at all, so it is not saved anywhere - // in the callee's stack frame and does not need to be recovered. - // Because %ebp wasn't used in the callee, whatever value it has - // is the value that it had in the caller, so it can be carried - // straight through without bringing its validity into question. - // - // Because of the use of .raSearchStart, the stack will possibly be - // examined to locate a better return address after program string - // evaluation. The stack will not be examined to locate a saved - // %ebp value, because these frames do not save (or use) %ebp. - // - // %eip_new = *(%esp_old + callee_params + saved_regs + locals) - // %esp_new = %esp_old + callee_params + saved_regs + locals + 4 - // %ebp_new = %ebp_old - program_string = "$eip .raSearchStart ^ = " - "$esp .raSearchStart 4 + ="; - recover_ebp = false; - } - - // Check for alignment operators in the program string. If alignment - // operators are found, then current %ebp must be valid and it is the only - // reliable data point that can be used for getting to the previous frame. - // E.g. the .raSearchStart calculation (above) is based on %esp and since - // %esp was aligned in the current frame (which is a lossy operation) the - // calculated value of .raSearchStart cannot be correct and should not be - // used. Instead .raSearchStart must be calculated based on %ebp. - // The code that follows assumes that .raSearchStart is supposed to point - // at the saved return address (ebp + 4). - // For some more details on this topic, take a look at the following thread: - // https://groups.google.com/forum/#!topic/google-breakpad-dev/ZP1FA9B1JjM - if ((StackFrameX86::CONTEXT_VALID_EBP & last_frame->context_validity) != 0 && - program_string.find('@') != string::npos) { - raSearchStart = last_frame->context.ebp + 4; - } - - // The difference between raSearch and raSearchStart is unknown, - // but making them the same seems to work well in practice. - dictionary[".raSearchStart"] = raSearchStart; - dictionary[".raSearch"] = raSearchStart; - - // Now crank it out, making sure that the program string set at least the - // two required variables. - PostfixEvaluator evaluator = - PostfixEvaluator(&dictionary, memory_); - PostfixEvaluator::DictionaryValidityType dictionary_validity; - if (!evaluator.Evaluate(program_string, &dictionary_validity) || - dictionary_validity.find("$eip") == dictionary_validity.end() || - dictionary_validity.find("$esp") == dictionary_validity.end()) { - // Program string evaluation failed. It may be that %eip is not somewhere - // with stack frame info, and %ebp is pointing to non-stack memory, so - // our evaluation couldn't succeed. We'll scan the stack for a return - // address. This can happen if the stack is in a module for which - // we don't have symbols, and that module is compiled without a - // frame pointer. - uint32_t location_start = last_frame->context.esp; - uint32_t location, eip; - if (!stack_scan_allowed - || !ScanForReturnAddress(location_start, &location, &eip, - frames.size() == 1 /* is_context_frame */)) { - // if we can't find an instruction pointer even with stack scanning, - // give up. - return NULL; - } - - // This seems like a reasonable return address. Since program string - // evaluation failed, use it and set %esp to the location above the - // one where the return address was found. - dictionary["$eip"] = eip; - dictionary["$esp"] = location + 4; - trust = StackFrame::FRAME_TRUST_SCAN; - } - - // Since this stack frame did not use %ebp in a traditional way, - // locating the return address isn't entirely deterministic. In that - // case, the stack can be scanned to locate the return address. - // - // However, if program string evaluation resulted in both %eip and - // %ebp values of 0, trust that the end of the stack has been - // reached and don't scan for anything else. - if (dictionary["$eip"] != 0 || dictionary["$ebp"] != 0) { - int offset = 0; - - // This scan can only be done if a CodeModules object is available, to - // check that candidate return addresses are in fact inside a module. - // - // TODO(mmentovai): This ignores dynamically-generated code. One possible - // solution is to check the minidump's memory map to see if the candidate - // %eip value comes from a mapped executable page, although this would - // require dumps that contain MINIDUMP_MEMORY_INFO, which the Breakpad - // client doesn't currently write (it would need to call MiniDumpWriteDump - // with the MiniDumpWithFullMemoryInfo type bit set). Even given this - // ability, older OSes (pre-XP SP2) and CPUs (pre-P4) don't enforce - // an independent execute privilege on memory pages. - - uint32_t eip = dictionary["$eip"]; - if (modules_ && !modules_->GetModuleForAddress(eip)) { - // The instruction pointer at .raSearchStart was invalid, so start - // looking one 32-bit word above that location. - uint32_t location_start = dictionary[".raSearchStart"] + 4; - uint32_t location; - if (stack_scan_allowed - && ScanForReturnAddress(location_start, &location, &eip, - frames.size() == 1 /* is_context_frame */)) { - // This is a better return address that what program string - // evaluation found. Use it, and set %esp to the location above the - // one where the return address was found. - dictionary["$eip"] = eip; - dictionary["$esp"] = location + 4; - offset = location - location_start; - trust = StackFrame::FRAME_TRUST_CFI_SCAN; - } - } - - if (recover_ebp) { - // When trying to recover the previous value of the frame pointer (%ebp), - // start looking at the lowest possible address in the saved-register - // area, and look at the entire saved register area, increased by the - // size of |offset| to account for additional data that may be on the - // stack. The scan is performed from the highest possible address to - // the lowest, because the expectation is that the function's prolog - // would have saved %ebp early. - uint32_t ebp = dictionary["$ebp"]; - - // When a scan for return address is used, it is possible to skip one or - // more frames (when return address is not in a known module). One - // indication for skipped frames is when the value of %ebp is lower than - // the location of the return address on the stack - bool has_skipped_frames = - (trust != StackFrame::FRAME_TRUST_CFI && ebp <= raSearchStart + offset); - - uint32_t value; // throwaway variable to check pointer validity - if (has_skipped_frames || !memory_->GetMemoryAtAddress(ebp, &value)) { - int fp_search_bytes = last_frame_info->saved_register_size + offset; - uint32_t location_end = last_frame->context.esp + - last_frame_callee_parameter_size; - - for (uint32_t location = location_end + fp_search_bytes; - location >= location_end; - location -= 4) { - if (!memory_->GetMemoryAtAddress(location, &ebp)) - break; - - if (memory_->GetMemoryAtAddress(ebp, &value)) { - // The candidate value is a pointer to the same memory region - // (the stack). Prefer it as a recovered %ebp result. - dictionary["$ebp"] = ebp; - break; - } - } - } - } - } - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameX86* frame = new StackFrameX86(); - - frame->trust = trust; - frame->context = last_frame->context; - frame->context.eip = dictionary["$eip"]; - frame->context.esp = dictionary["$esp"]; - frame->context.ebp = dictionary["$ebp"]; - frame->context_validity = StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP; - - // These are nonvolatile (callee-save) registers, and the program string - // may have filled them in. - if (dictionary_validity.find("$ebx") != dictionary_validity.end()) { - frame->context.ebx = dictionary["$ebx"]; - frame->context_validity |= StackFrameX86::CONTEXT_VALID_EBX; - } - if (dictionary_validity.find("$esi") != dictionary_validity.end()) { - frame->context.esi = dictionary["$esi"]; - frame->context_validity |= StackFrameX86::CONTEXT_VALID_ESI; - } - if (dictionary_validity.find("$edi") != dictionary_validity.end()) { - frame->context.edi = dictionary["$edi"]; - frame->context_validity |= StackFrameX86::CONTEXT_VALID_EDI; - } - - return frame; -} - -StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo( - const vector &frames, - CFIFrameInfo* cfi_frame_info) { - StackFrameX86* last_frame = static_cast(frames.back()); - last_frame->cfi_frame_info = cfi_frame_info; - - scoped_ptr frame(new StackFrameX86()); - if (!cfi_walker_ - .FindCallerRegisters(*memory_, *cfi_frame_info, - last_frame->context, last_frame->context_validity, - &frame->context, &frame->context_validity)) - return NULL; - - // Make sure we recovered all the essentials. - static const int essentials = (StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP); - if ((frame->context_validity & essentials) != essentials) - return NULL; - - frame->trust = StackFrame::FRAME_TRUST_CFI; - - return frame.release(); -} - -StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase( - const vector &frames, - bool stack_scan_allowed) { - StackFrame::FrameTrust trust; - StackFrameX86* last_frame = static_cast(frames.back()); - uint32_t last_esp = last_frame->context.esp; - uint32_t last_ebp = last_frame->context.ebp; - - // Assume that the standard %ebp-using x86 calling convention is in - // use. - // - // The typical x86 calling convention, when frame pointers are present, - // is for the calling procedure to use CALL, which pushes the return - // address onto the stack and sets the instruction pointer (%eip) to - // the entry point of the called routine. The called routine then - // PUSHes the calling routine's frame pointer (%ebp) onto the stack - // before copying the stack pointer (%esp) to the frame pointer (%ebp). - // Therefore, the calling procedure's frame pointer is always available - // by dereferencing the called procedure's frame pointer, and the return - // address is always available at the memory location immediately above - // the address pointed to by the called procedure's frame pointer. The - // calling procedure's stack pointer (%esp) is 8 higher than the value - // of the called procedure's frame pointer at the time the calling - // procedure made the CALL: 4 bytes for the return address pushed by the - // CALL itself, and 4 bytes for the callee's PUSH of the caller's frame - // pointer. - // - // %eip_new = *(%ebp_old + 4) - // %esp_new = %ebp_old + 8 - // %ebp_new = *(%ebp_old) - - uint32_t caller_eip, caller_esp, caller_ebp; - - if (memory_->GetMemoryAtAddress(last_ebp + 4, &caller_eip) && - memory_->GetMemoryAtAddress(last_ebp, &caller_ebp)) { - caller_esp = last_ebp + 8; - trust = StackFrame::FRAME_TRUST_FP; - } else { - // We couldn't read the memory %ebp refers to. It may be that %ebp - // is pointing to non-stack memory. We'll scan the stack for a - // return address. This can happen if last_frame is executing code - // for a module for which we don't have symbols, and that module - // is compiled without a frame pointer. - if (!stack_scan_allowed - || !ScanForReturnAddress(last_esp, &caller_esp, &caller_eip, - frames.size() == 1 /* is_context_frame */)) { - // if we can't find an instruction pointer even with stack scanning, - // give up. - return NULL; - } - - // ScanForReturnAddress found a reasonable return address. Advance %esp to - // the location immediately above the one where the return address was - // found. - caller_esp += 4; - // Try to restore the %ebp chain. The caller %ebp should be stored at a - // location immediately below the one where the return address was found. - // A valid caller %ebp must be greater than the address where it is stored - // and the gap between the two adjacent frames should be reasonable. - uint32_t restored_ebp_chain = caller_esp - 8; - if (!memory_->GetMemoryAtAddress(restored_ebp_chain, &caller_ebp) || - caller_ebp <= restored_ebp_chain || - caller_ebp - restored_ebp_chain > kMaxReasonableGapBetweenFrames) { - // The restored %ebp chain doesn't appear to be valid. - // Assume that %ebp is unchanged. - caller_ebp = last_ebp; - } - - trust = StackFrame::FRAME_TRUST_SCAN; - } - - // Create a new stack frame (ownership will be transferred to the caller) - // and fill it in. - StackFrameX86* frame = new StackFrameX86(); - - frame->trust = trust; - frame->context = last_frame->context; - frame->context.eip = caller_eip; - frame->context.esp = caller_esp; - frame->context.ebp = caller_ebp; - frame->context_validity = StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP; - - return frame; -} - -StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed) { - if (!memory_ || !stack) { - BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; - } - - const vector &frames = *stack->frames(); - StackFrameX86* last_frame = static_cast(frames.back()); - scoped_ptr new_frame; - - // If the resolver has Windows stack walking information, use that. - WindowsFrameInfo* windows_frame_info - = frame_symbolizer_->FindWindowsFrameInfo(last_frame); - if (windows_frame_info) - new_frame.reset(GetCallerByWindowsFrameInfo(frames, windows_frame_info, - stack_scan_allowed)); - - // If the resolver has DWARF CFI information, use that. - if (!new_frame.get()) { - CFIFrameInfo* cfi_frame_info = - frame_symbolizer_->FindCFIFrameInfo(last_frame); - if (cfi_frame_info) - new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info)); - } - - // Otherwise, hope that the program was using a traditional frame structure. - if (!new_frame.get()) - new_frame.reset(GetCallerByEBPAtBase(frames, stack_scan_allowed)); - - // If nothing worked, tell the caller. - if (!new_frame.get()) - return NULL; - - // Treat an instruction address of 0 as end-of-stack. - if (new_frame->context.eip == 0) - return NULL; - - // If the new stack pointer is at a lower address than the old, then - // that's clearly incorrect. Treat this as end-of-stack to enforce - // progress and avoid infinite loops. - if (new_frame->context.esp <= last_frame->context.esp) - return NULL; - - // new_frame->context.eip is the return address, which is the instruction - // after the CALL that caused us to arrive at the callee. Set - // new_frame->instruction to one less than that, so it points within the - // CALL instruction. See StackFrame::instruction for details, and - // StackFrameAMD64::ReturnAddress. - new_frame->instruction = new_frame->context.eip - 1; - - return new_frame.release(); -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h deleted file mode 100644 index 0659a13bf..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h +++ /dev/null @@ -1,117 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// stackwalker_x86.h: x86-specific stackwalker. -// -// Provides stack frames given x86 register context and a memory region -// corresponding to an x86 stack. -// -// Author: Mark Mentovai - - -#ifndef PROCESSOR_STACKWALKER_X86_H__ -#define PROCESSOR_STACKWALKER_X86_H__ - -#include - -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/stackwalker.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/cfi_frame_info.h" - -namespace google_breakpad { - -class CodeModules; - - -class StackwalkerX86 : public Stackwalker { - public: - // context is an x86 context object that gives access to x86-specific - // register state corresponding to the innermost called frame to be - // included in the stack. The other arguments are passed directly through - // to the base Stackwalker constructor. - StackwalkerX86(const SystemInfo* system_info, - const MDRawContextX86* context, - MemoryRegion* memory, - const CodeModules* modules, - StackFrameSymbolizer* frame_symbolizer); - - private: - // A STACK CFI-driven frame walker for the X86. - typedef SimpleCFIWalker CFIWalker; - - // Implementation of Stackwalker, using x86 context (%ebp, %esp, %eip) and - // stack conventions (saved %ebp at [%ebp], saved %eip at 4[%ebp], or - // alternate conventions as guided by any WindowsFrameInfo available for the - // code in question.). - virtual StackFrame* GetContextFrame(); - virtual StackFrame* GetCallerFrame(const CallStack* stack, - bool stack_scan_allowed); - - // Use windows_frame_info (derived from STACK WIN and FUNC records) - // to construct the frame that called frames.back(). The caller - // takes ownership of the returned frame. Return NULL on failure. - StackFrameX86* GetCallerByWindowsFrameInfo( - const vector &frames, - WindowsFrameInfo* windows_frame_info, - bool stack_scan_allowed); - - // Use cfi_frame_info (derived from STACK CFI records) to construct - // the frame that called frames.back(). The caller takes ownership - // of the returned frame. Return NULL on failure. - StackFrameX86* GetCallerByCFIFrameInfo(const vector &frames, - CFIFrameInfo* cfi_frame_info); - - // Assuming a traditional frame layout --- where the caller's %ebp - // has been pushed just after the return address and the callee's - // %ebp points to the saved %ebp --- construct the frame that called - // frames.back(). The caller takes ownership of the returned frame. - // Return NULL on failure. - StackFrameX86* GetCallerByEBPAtBase(const vector &frames, - bool stack_scan_allowed); - - // Stores the CPU context corresponding to the innermost stack frame to - // be returned by GetContextFrame. - const MDRawContextX86* context_; - - // Our register map, for cfi_walker_. - static const CFIWalker::RegisterSet cfi_register_map_[]; - - // Our CFI frame walker. - const CFIWalker cfi_walker_; -}; - - -} // namespace google_breakpad - - -#endif // PROCESSOR_STACKWALKER_X86_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc deleted file mode 100644 index d4c61c8c4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc +++ /dev/null @@ -1,2128 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class. - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/source_line_resolver_interface.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "processor/stackwalker_unittest_utils.h" -#include "processor/stackwalker_x86.h" -#include "processor/windows_frame_info.h" - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::StackFrameSymbolizer; -using google_breakpad::StackFrame; -using google_breakpad::StackFrameX86; -using google_breakpad::Stackwalker; -using google_breakpad::StackwalkerX86; -using google_breakpad::SystemInfo; -using google_breakpad::WindowsFrameInfo; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; -using google_breakpad::test_assembler::Section; -using std::vector; -using testing::_; -using testing::AnyNumber; -using testing::Return; -using testing::SetArgumentPointee; -using testing::Test; - -class StackwalkerX86Fixture { - public: - StackwalkerX86Fixture() - : stack_section(kLittleEndian), - // Give the two modules reasonable standard locations and names - // for tests to play with. - module1(0x40000000, 0x10000, "module1", "version1"), - module2(0x50000000, 0x10000, "module2", "version2"), - module3(0x771d0000, 0x180000, "module3", "version3"), - module4(0x75f90000, 0x46000, "module4", "version4"), - module5(0x75730000, 0x110000, "module5", "version5"), - module6(0x647f0000, 0x1ba8000, "module6", "version6") { - // Identify the system as a Linux system. - system_info.os = "Linux"; - system_info.os_short = "linux"; - system_info.os_version = "Salacious Skink"; - system_info.cpu = "x86"; - system_info.cpu_info = ""; - - // Put distinctive values in the raw CPU context. - BrandContext(&raw_context); - - // Create some modules with some stock debugging information. - modules.Add(&module1); - modules.Add(&module2); - modules.Add(&module3); - modules.Add(&module4); - modules.Add(&module5); - modules.Add(&module6); - - // By default, none of the modules have symbol info; call - // SetModuleSymbols to override this. - EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) - .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); - - // Avoid GMOCK WARNING "Uninteresting mock function call - returning - // directly" for FreeSymbolData(). - EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); - - // Reset max_frames_scanned since it's static. - Stackwalker::set_max_frames_scanned(1024); - } - - // Set the Breakpad symbol information that supplier should return for - // MODULE to INFO. - void SetModuleSymbols(MockCodeModule *module, const string &info) { - size_t buffer_size; - char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) - .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), - SetArgumentPointee<4>(buffer_size), - Return(MockSymbolSupplier::FOUND))); - } - - // Populate stack_region with the contents of stack_section. Use - // stack_section.start() as the region's starting address. - void RegionFromSection() { - string contents; - ASSERT_TRUE(stack_section.GetContents(&contents)); - stack_region.Init(stack_section.start().Value(), contents); - } - - // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. - void BrandContext(MDRawContextX86 *raw_context) { - uint8_t x = 173; - for (size_t i = 0; i < sizeof(*raw_context); i++) - reinterpret_cast(raw_context)[i] = (x += 17); - } - - SystemInfo system_info; - MDRawContextX86 raw_context; - Section stack_section; - MockMemoryRegion stack_region; - MockCodeModule module1; - MockCodeModule module2; - MockCodeModule module3; - MockCodeModule module4; - MockCodeModule module5; - MockCodeModule module6; - MockCodeModules modules; - MockSymbolSupplier supplier; - BasicSourceLineResolver resolver; - CallStack call_stack; - const vector *frames; -}; - -class SanityCheck: public StackwalkerX86Fixture, public Test { }; - -TEST_F(SanityCheck, NoResolver) { - stack_section.start() = 0x80000000; - stack_section.D32(0).D32(0); // end-of-stack marker - RegionFromSection(); - raw_context.eip = 0x40000200; - raw_context.ebp = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(NULL, NULL); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - // This should succeed, even without a resolver or supplier. - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - StackFrameX86 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetContextFrame: public StackwalkerX86Fixture, public Test { }; - -TEST_F(GetContextFrame, Simple) { - stack_section.start() = 0x80000000; - stack_section.D32(0).D32(0); // end-of-stack marker - RegionFromSection(); - raw_context.eip = 0x40000200; - raw_context.ebp = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - StackFrameX86 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -// The stackwalker should be able to produce the context frame even -// without stack memory present. -TEST_F(GetContextFrame, NoStackMemory) { - raw_context.eip = 0x40000200; - raw_context.ebp = 0x80000000; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - StackFrameX86 *frame = static_cast(frames->at(0)); - // Check that the values from the original raw context made it - // through to the context in the stack frame. - EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); -} - -class GetCallerFrame: public StackwalkerX86Fixture, public Test { - protected: - void IPAddressIsNotInKnownModuleTestImpl(bool has_corrupt_symbols); -}; - -// Walk a traditional frame. A traditional frame saves the caller's -// %ebp just below the return address, and has its own %ebp pointing -// at the saved %ebp. -TEST_F(GetCallerFrame, Traditional) { - stack_section.start() = 0x80000000; - Label frame0_ebp, frame1_ebp; - stack_section - .Append(12, 0) // frame 0: space - .Mark(&frame0_ebp) // frame 0 %ebp points here - .D32(frame1_ebp) // frame 0: saved %ebp - .D32(0x40008679) // frame 0: return address - .Append(8, 0) // frame 1: space - .Mark(&frame1_ebp) // frame 1 %ebp points here - .D32(0) // frame 1: saved %ebp (stack end) - .D32(0); // frame 1: return address (stack end) - RegionFromSection(); - raw_context.eip = 0x4000c7a5; - raw_context.esp = stack_section.start().Value(); - raw_context.ebp = frame0_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000c7a5U, frame0->instruction); - EXPECT_EQ(0x4000c7a5U, frame0->context.eip); - EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x40008679U, frame1->instruction + 1); - EXPECT_EQ(0x40008679U, frame1->context.eip); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Walk a traditional frame, but use a bogus %ebp value, forcing a scan -// of the stack for something that looks like a return address. -TEST_F(GetCallerFrame, TraditionalScan) { - stack_section.start() = 0x80000000; - Label frame1_ebp; - Label frame1_esp; - stack_section - // frame 0 - .D32(0xf065dc76) // locals area: - .D32(0x46ee2167) // garbage that doesn't look like - .D32(0xbab023ec) // a return address - .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) - .D32(0x4000129d) // return address - // frame 1 - .Mark(&frame1_esp) - .Append(8, 0) // space - .Mark(&frame1_ebp) // %ebp points here - .D32(0) // saved %ebp (stack end) - .D32(0); // return address (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000f49d; - raw_context.esp = stack_section.start().Value(); - // Make the frame pointer bogus, to make the stackwalker scan the stack - // for something that looks like a return address. - raw_context.ebp = 0xd43eed6e; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000f49dU, frame0->instruction); - EXPECT_EQ(0x4000f49dU, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x4000129dU, frame1->instruction + 1); - EXPECT_EQ(0x4000129dU, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Force scanning for a return address a long way down the stack -TEST_F(GetCallerFrame, TraditionalScanLongWay) { - stack_section.start() = 0x80000000; - Label frame1_ebp; - Label frame1_esp; - stack_section - // frame 0 - .D32(0xf065dc76) // locals area: - .D32(0x46ee2167) // garbage that doesn't look like - .D32(0xbab023ec) // a return address - .Append(20 * 4, 0) // a bunch of space - .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) - .D32(0x4000129d) // return address - // frame 1 - .Mark(&frame1_esp) - .Append(8, 0) // space - .Mark(&frame1_ebp) // %ebp points here - .D32(0) // saved %ebp (stack end) - .D32(0); // return address (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000f49d; - raw_context.esp = stack_section.start().Value(); - // Make the frame pointer bogus, to make the stackwalker scan the stack - // for something that looks like a return address. - raw_context.ebp = 0xd43eed6e; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000f49dU, frame0->instruction); - EXPECT_EQ(0x4000f49dU, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x4000129dU, frame1->instruction + 1); - EXPECT_EQ(0x4000129dU, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Test that set_max_frames_scanned prevents using stack scanning -// to find caller frames. -TEST_F(GetCallerFrame, ScanningNotAllowed) { - stack_section.start() = 0x80000000; - Label frame1_ebp; - stack_section - // frame 0 - .D32(0xf065dc76) // locals area: - .D32(0x46ee2167) // garbage that doesn't look like - .D32(0xbab023ec) // a return address - .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) - .D32(0x4000129d) // return address - // frame 1 - .Append(8, 0) // space - .Mark(&frame1_ebp) // %ebp points here - .D32(0) // saved %ebp (stack end) - .D32(0); // return address (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000f49d; - raw_context.esp = stack_section.start().Value(); - // Make the frame pointer bogus, to make the stackwalker scan the stack - // for something that looks like a return address. - raw_context.ebp = 0xd43eed6e; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - Stackwalker::set_max_frames_scanned(0); - - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(1U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000f49dU, frame0->instruction); - EXPECT_EQ(0x4000f49dU, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); - } -} - -// Use Windows frame data (a "STACK WIN 4" record, from a -// FrameTypeFrameData DIA record) to walk a stack frame. -TEST_F(GetCallerFrame, WindowsFrameData) { - SetModuleSymbols(&module1, - "STACK WIN 4 aa85 176 0 0 4 10 4 0 1" - " $T2 $esp .cbSavedRegs + =" - " $T0 .raSearchStart =" - " $eip $T0 ^ =" - " $esp $T0 4 + =" - " $ebx $T2 4 - ^ =" - " $edi $T2 8 - ^ =" - " $esi $T2 12 - ^ =" - " $ebp $T2 16 - ^ =\n"); - Label frame1_esp, frame1_ebp; - stack_section.start() = 0x80000000; - stack_section - // frame 0 - .D32(frame1_ebp) // saved regs: %ebp - .D32(0xa7120d1a) // %esi - .D32(0x630891be) // %edi - .D32(0x9068a878) // %ebx - .D32(0xa08ea45f) // locals: unused - .D32(0x40001350) // return address - // frame 1 - .Mark(&frame1_esp) - .Append(12, 0) // empty space - .Mark(&frame1_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000aa85; - raw_context.esp = stack_section.start().Value(); - raw_context.ebp = 0xf052c1de; // should not be needed to walk frame - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000aa85U, frame0->instruction); - EXPECT_EQ(0x4000aa85U, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(0xf052c1deU, frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP - | StackFrameX86::CONTEXT_VALID_EBX - | StackFrameX86::CONTEXT_VALID_ESI - | StackFrameX86::CONTEXT_VALID_EDI), - frame1->context_validity); - EXPECT_EQ(0x40001350U, frame1->instruction + 1); - EXPECT_EQ(0x40001350U, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(0x9068a878U, frame1->context.ebx); - EXPECT_EQ(0xa7120d1aU, frame1->context.esi); - EXPECT_EQ(0x630891beU, frame1->context.edi); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Use Windows frame data (a "STACK WIN 4" record, from a -// FrameTypeFrameData DIA record) to walk a stack frame where the stack -// is aligned and we must search -TEST_F(GetCallerFrame, WindowsFrameDataAligned) { - SetModuleSymbols(&module1, - "STACK WIN 4 aa85 176 0 0 4 4 8 0 1" - " $T1 .raSearch =" - " $T0 $T1 4 - 8 @ =" - " $ebp $T1 4 - ^ =" - " $eip $T1 ^ =" - " $esp $T1 4 + ="); - Label frame0_esp, frame0_ebp; - Label frame1_esp, frame1_ebp; - stack_section.start() = 0x80000000; - stack_section - // frame 0 - .Mark(&frame0_esp) - .D32(0x0ffa0ffa) // unused saved register - .D32(0xdeaddead) // locals - .D32(0xbeefbeef) - .D32(0) // 8-byte alignment - .Mark(&frame0_ebp) - .D32(frame1_ebp) // saved %ebp - .D32(0x5000129d) // return address - // frame 1 - .Mark(&frame1_esp) - .D32(0x1) // parameter - .Mark(&frame1_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000aa85; - raw_context.esp = frame0_esp.Value(); - raw_context.ebp = frame0_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(1U, modules_without_symbols.size()); - ASSERT_EQ("module2", modules_without_symbols[0]->debug_file()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000aa85U, frame0->instruction); - EXPECT_EQ(0x4000aa85U, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x5000129dU, frame1->instruction + 1); - EXPECT_EQ(0x5000129dU, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Use Windows frame data (a "STACK WIN 4" record, from a -// FrameTypeFrameData DIA record) to walk a frame, and depend on the -// parameter size from the callee as well. -TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) { - SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n"); - SetModuleSymbols(&module2, - // Note bogus parameter size in FUNC record; the stack walker - // should prefer the STACK WIN record, and see '4' below. - "FUNC aa85 176 beef module2::whine\n" - "STACK WIN 4 aa85 176 0 0 4 10 4 0 1" - " $T2 $esp .cbLocals + .cbSavedRegs + =" - " $T0 .raSearchStart =" - " $eip $T0 ^ =" - " $esp $T0 4 + =" - " $ebp $T0 20 - ^ =" - " $ebx $T0 8 - ^ =\n"); - Label frame0_esp, frame0_ebp; - Label frame1_esp; - Label frame2_esp, frame2_ebp; - stack_section.start() = 0x80000000; - stack_section - // frame 0, in module1::wheedle. Traditional frame. - .Mark(&frame0_esp) - .Append(16, 0) // frame space - .Mark(&frame0_ebp) - .D32(0x6fa902e0) // saved %ebp. Not a frame pointer. - .D32(0x5000aa95) // return address, in module2::whine - // frame 1, in module2::whine. FrameData frame. - .Mark(&frame1_esp) - .D32(0xbaa0cb7a) // argument 3 passed to module1::wheedle - .D32(0xbdc92f9f) // argument 2 - .D32(0x0b1d8442) // argument 1 - .D32(frame2_ebp) // saved %ebp - .D32(0xb1b90a15) // unused - .D32(0xf18e072d) // unused - .D32(0x2558c7f3) // saved %ebx - .D32(0x0365e25e) // unused - .D32(0x2a179e38) // return address; $T0 points here - // frame 2, in no module - .Mark(&frame2_esp) - .Append(12, 0) // empty space - .Mark(&frame2_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x40001004; // in module1::wheedle - raw_context.esp = stack_section.start().Value(); - raw_context.ebp = frame0_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(3U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x40001004U, frame0->instruction); - EXPECT_EQ(0x40001004U, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(&module1, frame0->module); - EXPECT_EQ("module1::wheedle", frame0->function_name); - EXPECT_EQ(0x40001000U, frame0->function_base); - // The FUNC record for module1::wheedle should have produced a - // WindowsFrameInfo structure with only the parameter size valid. - ASSERT_TRUE(frame0->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, - frame0->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN, - frame0->windows_frame_info->type_); - EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x5000aa95U, frame1->instruction + 1); - EXPECT_EQ(0x5000aa95U, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(0x6fa902e0U, frame1->context.ebp); - EXPECT_EQ(&module2, frame1->module); - EXPECT_EQ("module2::whine", frame1->function_name); - EXPECT_EQ(0x5000aa85U, frame1->function_base); - ASSERT_TRUE(frame1->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame1->windows_frame_info->type_); - // This should not see the 0xbeef parameter size from the FUNC - // record, but should instead see the STACK WIN record. - EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP - | StackFrameX86::CONTEXT_VALID_EBX), - frame2->context_validity); - EXPECT_EQ(0x2a179e38U, frame2->instruction + 1); - EXPECT_EQ(0x2a179e38U, frame2->context.eip); - EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); - EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp); - EXPECT_EQ(0x2558c7f3U, frame2->context.ebx); - EXPECT_EQ(NULL, frame2->module); - EXPECT_EQ(NULL, frame2->windows_frame_info); - } -} - -// Use Windows frame data (a "STACK WIN 4" record, from a -// FrameTypeFrameData DIA record) to walk a stack frame, where the -// expression fails to yield both an $eip and an $ebp value, and the stack -// walker must scan. -TEST_F(GetCallerFrame, WindowsFrameDataScan) { - SetModuleSymbols(&module1, - "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n"); - // Mark frame 1's PC as the end of the stack. - SetModuleSymbols(&module2, - "FUNC 7c38 accf 0 module2::function\n" - "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n"); - Label frame1_esp; - stack_section.start() = 0x80000000; - stack_section - // frame 0 - .Append(16, 0x2a) // unused, garbage - .D32(0x50007ce9) // return address - // frame 1 - .Mark(&frame1_esp) - .Append(8, 0); // empty space - - RegionFromSection(); - raw_context.eip = 0x40000c9c; - raw_context.esp = stack_section.start().Value(); - raw_context.ebp = 0x2ae314cd; // should not be needed to walk frame - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x40000c9cU, frame0->instruction); - EXPECT_EQ(0x40000c9cU, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(0x2ae314cdU, frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker - // does not actually fetch the EBP after a scan (forcing the next frame - // to be scanned as well). But let's grandfather the existing behavior in - // for now. - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x50007ce9U, frame1->instruction + 1); - EXPECT_EQ(0x50007ce9U, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_TRUE(frame1->windows_frame_info != NULL); - } -} - -// Use Windows frame data (a "STACK WIN 4" record, from a -// FrameTypeFrameData DIA record) to walk a stack frame, where the -// expression yields an $eip that falls outside of any module, and the -// stack walker must scan. -TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) { - SetModuleSymbols(&module1, - "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1" - // A traditional frame, actually. - " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n"); - // Mark frame 1's PC as the end of the stack. - SetModuleSymbols(&module2, - "FUNC cfdb 8406 0 module2::function\n" - "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n"); - stack_section.start() = 0x80000000; - - // In this stack, the context's %ebp is pointing at the wrong place, so - // the stack walker needs to scan to find the return address, and then - // scan again to find the caller's saved %ebp. - Label frame0_ebp, frame1_ebp, frame1_esp; - stack_section - // frame 0 - .Append(8, 0x2a) // garbage - .Mark(&frame0_ebp) // frame 0 %ebp points here, but should point - // at *** below - // The STACK WIN record says that the following two values are - // frame 1's saved %ebp and return address, but the %ebp is wrong; - // they're garbage. The stack walker will scan for the right values. - .D32(0x3d937b2b) // alleged to be frame 1's saved %ebp - .D32(0x17847f5b) // alleged to be frame 1's return address - .D32(frame1_ebp) // frame 1's real saved %ebp; scan will find - .D32(0x2b2b2b2b) // first word of realigned register save area - // *** frame 0 %ebp ought to be pointing here - .D32(0x2c2c2c2c) // realigned locals area - .D32(0x5000d000) // frame 1's real saved %eip; scan will find - // Frame 1, in module2::function. The STACK WIN record describes - // this as the oldest frame, without referring to its contents, so - // we needn't to provide any actual data here. - .Mark(&frame1_esp) - .Mark(&frame1_ebp) // frame 1 %ebp points here - // A dummy value for frame 1's %ebp to point at. The scan recognizes the - // saved %ebp because it points to a valid word in the stack memory region. - .D32(0x2d2d2d2d); - - RegionFromSection(); - raw_context.eip = 0x40000700; - raw_context.esp = stack_section.start().Value(); - raw_context.ebp = frame0_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x40000700U, frame0->instruction); - EXPECT_EQ(0x40000700U, frame0->context.eip); - EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); - EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust); - // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the - // walker does not actually fetch the EBP after a scan (forcing the - // next frame to be scanned as well). But let's grandfather the existing - // behavior in for now. - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x5000d000U, frame1->instruction + 1); - EXPECT_EQ(0x5000d000U, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_TRUE(frame1->windows_frame_info != NULL); - } -} - -// Use Windows FrameTypeFPO data to walk a stack frame for a function that -// does not modify %ebp from the value it had in the caller. -TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) { - SetModuleSymbols(&module1, - // Note bogus parameter size in FUNC record; the walker - // should prefer the STACK WIN record, and see the '8' below. - "FUNC e8a8 100 feeb module1::discombobulated\n" - "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n"); - Label frame0_esp; - Label frame1_esp, frame1_ebp; - stack_section.start() = 0x80000000; - stack_section - // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame. - .Mark(&frame0_esp) - // no outgoing parameters; this is the youngest frame. - .D32(0x7c521352) // four bytes of saved registers - .Append(0x10, 0x42) // local area - .D32(0x40009b5b) // return address, in module1, no function - // frame 1, in module1, no function. - .Mark(&frame1_esp) - .D32(0xf60ea7fc) // junk - .Mark(&frame1_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x4000e8b8; // in module1::whine - raw_context.esp = stack_section.start().Value(); - // Frame pointer unchanged from caller. - raw_context.ebp = frame1_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x4000e8b8U, frame0->instruction); - EXPECT_EQ(0x4000e8b8U, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - // unchanged from caller - EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(&module1, frame0->module); - EXPECT_EQ("module1::discombobulated", frame0->function_name); - EXPECT_EQ(0x4000e8a8U, frame0->function_base); - // The STACK WIN record for module1::discombobulated should have - // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, - frame0->windows_frame_info->type_); - EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x40009b5bU, frame1->instruction + 1); - EXPECT_EQ(0x40009b5bU, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(&module1, frame1->module); - EXPECT_EQ("", frame1->function_name); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// Use Windows FrameTypeFPO data to walk a stack frame for a function -// that uses %ebp for its own purposes, saving the value it had in the -// caller in the standard place in the saved register area. -TEST_F(GetCallerFrame, WindowsFPOUsedEBP) { - SetModuleSymbols(&module1, - // Note bogus parameter size in FUNC record; the walker - // should prefer the STACK WIN record, and see the '8' below. - "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n" - "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n"); - Label frame0_esp; - Label frame1_esp, frame1_ebp; - stack_section.start() = 0x80000000; - stack_section - // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame. - .Mark(&frame0_esp) - // no outgoing parameters; this is the youngest frame. - .D32(frame1_ebp) // saved register area: saved %ebp - .D32(0xb68bd5f9) // saved register area: something else - .D32(0xd25d05fc) // local area - .D32(0x4000debe) // return address, in module1, no function - // frame 1, in module1, no function. - .Mark(&frame1_esp) - .D32(0xf0c9a974) // junk - .Mark(&frame1_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens - raw_context.esp = stack_section.start().Value(); - // RaisedByTheAliens uses %ebp for its own mysterious purposes. - raw_context.ebp = 0xecbdd1a5; - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x40009ab8U, frame0->instruction); - EXPECT_EQ(0x40009ab8U, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - EXPECT_EQ(0xecbdd1a5, frame0->context.ebp); - EXPECT_EQ(&module1, frame0->module); - EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name); - EXPECT_EQ(0x40009aa8U, frame0->function_base); - // The STACK WIN record for module1::RaisedByTheAliens should have - // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, - frame0->windows_frame_info->type_); - EXPECT_EQ("", frame0->windows_frame_info->program_string); - EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x4000debeU, frame1->instruction + 1); - EXPECT_EQ(0x4000debeU, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(&module1, frame1->module); - EXPECT_EQ("", frame1->function_name); - EXPECT_EQ(NULL, frame1->windows_frame_info); - } -} - -// This is a regression unit test which covers a bug which has to do with -// FPO-optimized Windows system call stubs in the context frame. There is -// a more recent Windows system call dispatch mechanism which differs from -// the one which is being tested here. The newer system call dispatch -// mechanism creates an extra context frame (KiFastSystemCallRet). -TEST_F(GetCallerFrame, WindowsFPOSystemCall) { - SetModuleSymbols(&module3, // ntdll.dll - "PUBLIC 1f8ac c ZwWaitForSingleObject\n" - "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n"); - SetModuleSymbols(&module4, // kernelbase.dll - "PUBLIC 109f9 c WaitForSingleObjectEx\n" - "PUBLIC 36590 0 _except_handler4\n" - "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip " - "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " - "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n" - "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip " - "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 " - ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n"); - SetModuleSymbols(&module5, // kernel32.dll - "PUBLIC 11136 8 WaitForSingleObject\n" - "PUBLIC 11151 c WaitForSingleObjectExImplementation\n" - "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip " - "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " - "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n" - "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip " - "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " - "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"); - SetModuleSymbols(&module6, // chrome.dll - "FILE 7038 some_file_name.h\n" - "FILE 839776 some_file_name.cc\n" - "FUNC 217fda 17 4 function_217fda\n" - "217fda 4 102 839776\n" - "FUNC 217ff1 a 4 function_217ff1\n" - "217ff1 0 594 7038\n" - "217ff1 a 596 7038\n" - "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n"); - - Label frame0_esp, frame1_esp; - Label frame1_ebp, frame2_ebp, frame3_ebp; - stack_section.start() = 0x002ff290; - stack_section - .Mark(&frame0_esp) - .D32(0x771ef8c1) // EIP in frame 0 (system call) - .D32(0x75fa0a91) // return address of frame 0 - .Mark(&frame1_esp) - .D32(0x000017b0) // args to child - .D32(0x00000000) - .D32(0x002ff2d8) - .D32(0x88014a2e) - .D32(0x002ff364) - .D32(0x000017b0) - .D32(0x00000000) - .D32(0x00000024) - .D32(0x00000001) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x9e3b9800) - .D32(0xfffffff7) - .D32(0x00000000) - .D32(0x002ff2a4) - .D32(0x64a07ff1) // random value to be confused with a return address - .D32(0x002ff8dc) - .D32(0x75fc6590) // random value to be confused with a return address - .D32(0xfdd2c6ea) - .D32(0x00000000) - .Mark(&frame1_ebp) - .D32(frame2_ebp) // Child EBP - .D32(0x75741194) // return address of frame 1 - .D32(0x000017b0) // args to child - .D32(0x0036ee80) - .D32(0x00000000) - .D32(0x65bc7d14) - .Mark(&frame2_ebp) - .D32(frame3_ebp) // Child EBP - .D32(0x75741148) // return address of frame 2 - .D32(0x000017b0) // args to child - .D32(0x0036ee80) - .D32(0x00000000) - .Mark(&frame3_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x771ef8c1; // in ntdll::ZwWaitForSingleObject - raw_context.esp = stack_section.start().Value(); - ASSERT_TRUE(raw_context.esp == frame0_esp.Value()); - raw_context.ebp = frame1_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - - ASSERT_EQ(4U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x771ef8c1U, frame0->instruction); - EXPECT_EQ(0x771ef8c1U, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(&module3, frame0->module); - EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name); - // The STACK WIN record for module3!ZwWaitForSingleObject should have - // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, - frame0->windows_frame_info->type_); - EXPECT_EQ("", frame0->windows_frame_info->program_string); - EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP - | StackFrameX86::CONTEXT_VALID_ESP - | StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1); - EXPECT_EQ(0x75fa0a91U, frame1->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(&module4, frame1->module); - EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name); - // The STACK WIN record for module4!WaitForSingleObjectEx should have - // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame1->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame1->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " - "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =", - frame1->windows_frame_info->program_string); - EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); - } -} - -// Scan the stack for a better return address and potentially skip frames -// when the calculated return address is not in a known module. Note, that -// the span of this scan is somewhat arbitrarily limited to 160 search words -// for the context frame and 40 search words (pointers) for the other frames: -// const int kRASearchWords = 40; -// This means that frames can be skipped only when their size is relatively -// small: smaller than 4 * kRASearchWords * sizeof(InstructionType) -TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) { - MockCodeModule msvcrt_dll(0x77be0000, 0x58000, "msvcrt.dll", "version1"); - SetModuleSymbols(&msvcrt_dll, // msvcrt.dll - "PUBLIC 38180 0 wcsstr\n" - "STACK WIN 4 38180 61 10 0 8 0 0 0 1 $T0 $ebp = $eip $T0 " - "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " - "- = $P $T0 4 + .cbParams + =\n"); - - MockCodeModule kernel32_dll(0x7c800000, 0x103000, "kernel32.dll", "version1"); - SetModuleSymbols(&kernel32_dll, // kernel32.dll - "PUBLIC efda 8 FindNextFileW\n" - "STACK WIN 4 efda 1bb c 0 8 8 3c 0 1 $T0 $ebp = $eip $T0 " - "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " - "- = $P $T0 4 + .cbParams + =\n"); - - MockCodeModule chrome_dll(0x1c30000, 0x28C8000, "chrome.dll", "version1"); - SetModuleSymbols(&chrome_dll, // chrome.dll - "FUNC e3cff 4af 0 file_util::FileEnumerator::Next()\n" - "e3cff 1a 711 2505\n" - "STACK WIN 4 e3cff 4af 20 0 4 c 94 0 1 $T1 .raSearch = " - "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " - "$T1 4 + = $20 $T0 152 - ^ = $23 $T0 156 - ^ = $24 " - "$T0 160 - ^ =\n"); - - // Create some modules with some stock debugging information. - MockCodeModules local_modules; - local_modules.Add(&msvcrt_dll); - local_modules.Add(&kernel32_dll); - local_modules.Add(&chrome_dll); - - Label frame0_esp; - Label frame0_ebp; - Label frame1_ebp; - Label frame2_ebp; - Label frame3_ebp; - - stack_section.start() = 0x0932f2d0; - stack_section - .Mark(&frame0_esp) - .D32(0x0764e000) - .D32(0x0764e068) - .Mark(&frame0_ebp) - .D32(frame1_ebp) // Child EBP - .D32(0x001767a0) // return address of frame 0 - // Not in known module - .D32(0x0764e0c6) - .D32(0x001bb1b8) - .D32(0x0764e068) - .D32(0x00000003) - .D32(0x0764e068) - .D32(0x00000003) - .D32(0x07578828) - .D32(0x0764e000) - .D32(0x00000000) - .D32(0x001c0010) - .D32(0x0764e0c6) - .Mark(&frame1_ebp) - .D32(frame2_ebp) // Child EBP - .D32(0x7c80f10f) // return address of frame 1 - // inside kernel32!FindNextFileW - .D32(0x000008f8) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x0932f34c) - .D32(0x0764e000) - .D32(0x00001000) - .D32(0x00000000) - .D32(0x00000001) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x0932f6a8) - .D32(0x00000000) - .D32(0x0932f6d8) - .D32(0x00000000) - .D32(0x000000d6) - .D32(0x0764e000) - .D32(0x7ff9a000) - .D32(0x0932f3fc) - .D32(0x00000001) - .D32(0x00000001) - .D32(0x07578828) - .D32(0x0000002e) - .D32(0x0932f340) - .D32(0x0932eef4) - .D32(0x0932ffdc) - .D32(0x7c839ad8) - .D32(0x7c80f0d8) - .D32(0x00000000) - .Mark(&frame2_ebp) - .D32(frame3_ebp) // Child EBP - .D32(0x01d13f91) // return address of frame 2 - // inside chrome_dll!file_util::FileEnumerator::Next - .D32(0x07578828) - .D32(0x0932f6ac) - .D32(0x0932f9c4) - .D32(0x0932f9b4) - .D32(0x00000000) - .D32(0x00000003) - .D32(0x0932f978) - .D32(0x01094330) - .D32(0x00000000) - .D32(0x00000001) - .D32(0x01094330) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x07f30000) - .D32(0x01c3ba17) - .D32(0x08bab840) - .D32(0x07f31580) - .D32(0x00000000) - .D32(0x00000007) - .D32(0x0932f940) - .D32(0x0000002e) - .D32(0x0932f40c) - .D32(0x01d13b53) - .D32(0x0932f958) - .D32(0x00000001) - .D32(0x00000007) - .D32(0x0932f940) - .D32(0x0000002e) - .D32(0x00000000) - .D32(0x0932f6ac) - .D32(0x01e13ef0) - .D32(0x00000001) - .D32(0x00000007) - .D32(0x0932f958) - .D32(0x08bab840) - .D32(0x0932f9b4) - .D32(0x00000000) - .D32(0x0932f9b4) - .D32(0x000000a7) - .D32(0x000000a7) - .D32(0x0932f998) - .D32(0x579627a2) - .Mark(&frame3_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x77c181cd; // inside msvcrt!wcsstr - raw_context.esp = frame0_esp.Value(); - raw_context.ebp = frame0_ebp.Value(); - // sanity - ASSERT_TRUE(raw_context.esp == stack_section.start().Value()); - ASSERT_TRUE(raw_context.ebp == stack_section.start().Value() + 8); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, - &local_modules, &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - - ASSERT_EQ(3U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(0x77c181cdU, frame0->instruction); - EXPECT_EQ(0x77c181cdU, frame0->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); - EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(&msvcrt_dll, frame0->module); - EXPECT_EQ("wcsstr", frame0->function_name); - ASSERT_TRUE(frame0->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame0->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 " - "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " - "- = $P $T0 4 + .cbParams + =", - frame0->windows_frame_info->program_string); - // It has program string, so allocates_base_pointer is not expected - EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(0x7c80f10fU, frame1->instruction + 1); - EXPECT_EQ(0x7c80f10fU, frame1->context.eip); - // frame 1 was skipped, so intead of frame1_ebp compare with frame2_ebp. - EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(&kernel32_dll, frame1->module); - EXPECT_EQ("FindNextFileW", frame1->function_name); - ASSERT_TRUE(frame1->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame1->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 " - "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " - "- = $P $T0 4 + .cbParams + =", - frame1->windows_frame_info->program_string); - EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame2->context_validity); - EXPECT_EQ(0x01d13f91U, frame2->instruction + 1); - EXPECT_EQ(0x01d13f91U, frame2->context.eip); - // frame 1 was skipped, so intead of frame2_ebp compare with frame3_ebp. - EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp); - EXPECT_EQ(&chrome_dll, frame2->module); - EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name); - ASSERT_TRUE(frame2->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame2->windows_frame_info->type_); - EXPECT_EQ("$T1 .raSearch = " - "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " - "$T1 4 + = $20 $T0 152 - ^ = $23 $T0 156 - ^ = $24 " - "$T0 160 - ^ =", - frame2->windows_frame_info->program_string); - EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer); - } -} - -// Test the .raSearchStart/.raSearch calculation when alignment operators are -// used in the program string. The current %ebp must be valid and it is the -// only reliable data point that can be used for that calculation. -TEST_F(GetCallerFrame, HandleAlignmentInProgramString) { - MockCodeModule chrome_dll(0x59630000, 0x19e3000, "chrome.dll", "version1"); - SetModuleSymbols(&chrome_dll, // chrome.dll - "FUNC 56422 50c 8 base::MessageLoop::RunTask" - "(base::PendingTask const &)\n" - "56422 e 458 4589\n" - "STACK WIN 4 56422 50c 11 0 8 c ac 0 1 $T1 .raSearch = $T0 " - "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " - "$20 $T0 176 - ^ = $23 $T0 180 - ^ = $24 $T0 184 - ^ =\n" - "FUNC 55d34 34a 0 base::MessageLoop::DoWork()\n" - "55d34 11 596 4589\n" - "STACK WIN 4 55d34 34a 19 0 0 c 134 0 1 $T1 .raSearch = " - "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " - "$T1 4 + = $20 $T0 312 - ^ = $23 $T0 316 - ^ = $24 $T0 " - "320 - ^ =\n" - "FUNC 55c39 fb 0 base::MessagePumpForIO::DoRunLoop()\n" - "55c39 d 518 19962\n" - "STACK WIN 4 55c39 fb d 0 0 c 34 0 1 $T1 .raSearch = $T0 " - "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + " - "= $20 $T0 56 - ^ = $23 $T0 60 - ^ = $24 $T0 64 - ^ =\n" - "FUNC 55bf0 49 4 base::MessagePumpWin::Run(base::" - "MessagePump::Delegate *)\n" - "55bf0 49 48 4724\n" - "STACK WIN 4 55bf0 49 c 0 4 0 10 0 1 $T0 $ebp = $eip $T0 4 " - "+ ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" - "FUNC 165d de 4 malloc\n" - "165d 6 119 54\n" - "STACK WIN 4 165d de d 0 4 8 0 0 1 $T1 .raSearch = $T0 " - "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 " - "+ = $23 $T0 4 - ^ = $24 $T0 8 - ^ =\n" - "FUNC 55ac9 79 0 base::MessageLoop::RunInternal()\n" - "55ac9 d 427 4589\n" - "STACK WIN 4 55ac9 79 d 0 0 8 10 0 1 $T1 .raSearch = $T0 " - "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " - "$23 $T0 20 - ^ = $24 $T0 24 - ^ =\n"); - - // Create some modules with some stock debugging information. - MockCodeModules local_modules; - local_modules.Add(&chrome_dll); - - Label frame0_esp; - Label frame0_ebp; - Label frame1_esp; - Label frame1_ebp; - Label frame2_esp; - Label frame2_ebp; - Label frame3_esp; - Label frame3_ebp; - - stack_section.start() = 0x046bfc80; - stack_section - .D32(0) - .Mark(&frame0_esp) - .D32(0x01e235a0) - .D32(0x00000000) - .D32(0x01e9f580) - .D32(0x01e9f580) - .D32(0x00000020) - .D32(0x00000000) - .D32(0x00463674) - .D32(0x00000020) - .D32(0x00000000) - .D32(0x046bfcd8) - .D32(0x046bfcd8) - .D32(0x0001204b) - .D32(0x00000000) - .D32(0xfdddb523) - .D32(0x00000000) - .D32(0x00000007) - .D32(0x00000040) - .D32(0x00000000) - .D32(0x59631693) // chrome_59630000!malloc+0x36 - .D32(0x01e9f580) - .D32(0x01e9f580) - .D32(0x046bfcf8) - .D32(0x77da6704) // ntdll!NtSetIoCompletion+0xc - .D32(0x046bfd4c) - .D32(0x59685bec) // chrome_59630000!base::MessageLoop::StartHistogrammer.. - .D32(0x01e235a0) - - .Mark(&frame0_ebp) - .D32(frame1_ebp) // Child EBP .D32(0x046bfd0c) - .D32(0x59685c2e) // Return address in - // chrome_59630000!base::MessagePumpWin::Run+0x3e - .Mark(&frame1_esp) - .D32(0x01e75a90) - .D32(0x046bfd4c) - .D32(0x01e75a90) - .D32(0x00000000) - .D32(0x00000300) - .D32(0x00000001) - - .Mark(&frame1_ebp) - .D32(frame2_ebp) // Child EBP .D32(0x046bfd30) - .D32(0x59685b3c) // Return address in - // chrome_59630000!base::MessageLoop::RunInternal+0x73 - .Mark(&frame2_esp) - .D32(0x01e75a90) - .D32(0x00000000) - .D32(0x046bfd4c) - .D32(0x59658123) // chrome_59630000!std::deque.. - .D32(0x046bfda0) - .D32(0x01e79d70) - .D32(0x046bfda0) - - .Mark(&frame2_ebp) // .D32(0x046bfd40) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x59685c46; // Context frame in - // base::MessagePumpForIO::DoRunLoop - raw_context.esp = frame0_esp.Value(); - raw_context.ebp = frame0_ebp.Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, - &local_modules, &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - - ASSERT_EQ(3U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame->context_validity); - EXPECT_EQ("base::MessagePumpForIO::DoRunLoop()", frame->function_name); - EXPECT_EQ(0x59685c46U, frame->instruction); - EXPECT_EQ(0x59685c46U, frame->context.eip); - EXPECT_EQ(frame0_esp.Value(), frame->context.esp); - EXPECT_EQ(frame0_ebp.Value(), frame->context.ebp); - EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame->windows_frame_info->type_); - EXPECT_EQ("$T1 .raSearch = $T0 " - "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + " - "= $20 $T0 56 - ^ = $23 $T0 60 - ^ = $24 $T0 64 - ^ =", - frame->windows_frame_info->program_string); - EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame->context_validity); - EXPECT_EQ("base::MessagePumpWin::Run(base::MessagePump::Delegate *)", - frame->function_name); - EXPECT_EQ(1500011566U, frame->instruction + 1); - EXPECT_EQ(1500011566U, frame->context.eip); - EXPECT_EQ(frame1_esp.Value(), frame->context.esp); - EXPECT_EQ(frame1_ebp.Value(), frame->context.ebp); - EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", - frame->windows_frame_info->program_string); - EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame->context_validity); - EXPECT_EQ("base::MessageLoop::RunInternal()", frame->function_name); - EXPECT_EQ(1500011324U, frame->instruction + 1); - EXPECT_EQ(1500011324U, frame->context.eip); - EXPECT_EQ(frame2_esp.Value(), frame->context.esp); - EXPECT_EQ(frame2_ebp.Value(), frame->context.ebp); - EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame->windows_frame_info->type_); - EXPECT_EQ("$T1 .raSearch = $T0 " - "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " - "$23 $T0 20 - ^ = $24 $T0 24 - ^ =", - frame->windows_frame_info->program_string); - EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); - } -} - -// Scan the stack for a return address and potentially skip frames when the -// current IP address is not in a known module. Note, that that the span of -// this scan is limited to 120 search words for the context frame and 30 -// search words (pointers) for the other frames: -// const int kRASearchWords = 30; -void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( - bool has_corrupt_symbols) { - MockCodeModule remoting_core_dll(0x54080000, 0x501000, "remoting_core.dll", - "version1"); - string symbols_func_section = - "FUNC 137214 17d 10 PK11_Verify\n" - "FUNC 15c834 37 14 nsc_ECDSAVerifyStub\n" - "FUNC 1611d3 91 14 NSC_Verify\n" - "FUNC 162ff7 60 4 sftk_SessionFromHandle\n"; - string symbols_stack_section = - "STACK WIN 4 137214 17d 9 0 10 0 10 0 1 $T0 $ebp = " - "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" - "STACK WIN 4 15c834 37 6 0 14 0 18 0 1 $T0 $ebp = " - "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" - "STACK WIN 4 1611d3 91 7 0 14 0 8 0 1 $T0 $ebp = " - "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" - "STACK WIN 4 162ff7 60 5 0 4 0 0 0 1 $T0 $ebp = " - "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"; - - string symbols = symbols_func_section; - if (has_corrupt_symbols) { - symbols.append(string(1, '\0')); // null terminator in the middle - symbols.append("\n"); - symbols.append("FUNC 1234\n" // invalid FUNC records - "FUNNC 1234\n" - "STACK WIN 4 1234 234 23 " // invalid STACK record - "23423423 234 23 234 234 " - "234 23 234 23 234 234 " - "234 234 234\n"); - } - symbols.append(symbols_stack_section); - SetModuleSymbols(&remoting_core_dll, symbols); - - // Create some modules with some stock debugging information. - MockCodeModules local_modules; - local_modules.Add(&remoting_core_dll); - - Label frame0_esp; - Label frame0_ebp; - Label frame1_ebp; - Label frame1_esp; - Label frame2_ebp; - Label frame2_esp; - Label frame3_ebp; - Label frame3_esp; - Label bogus_stack_location_1; - Label bogus_stack_location_2; - Label bogus_stack_location_3; - - stack_section.start() = 0x01a3ea28; - stack_section - .Mark(&frame0_esp) - .D32(bogus_stack_location_2) - .D32(bogus_stack_location_1) - .D32(0x042478e4) - .D32(bogus_stack_location_2) - .D32(0x00000000) - .D32(0x041f0420) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000001) - .D32(0x00b7e0d0) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000001) - .D32(0x00b7f570) - .Mark(&bogus_stack_location_1) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x04289530) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x00b7e910) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x00b7d998) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x00b7dec0) - .Mark(&bogus_stack_location_2) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x04289428) - .D32(0x00000000) - .D32(0x00000040) - .D32(0x00000008) - .D32(0x00b7f258) - .Mark(&bogus_stack_location_3) - .D32(0x00000000) - .D32(0x041f3560) - .D32(0x00000041) - .D32(0x00000020) - .D32(0xffffffff) - .Mark(&frame0_ebp) - .D32(frame1_ebp) // Child %ebp - .D32(0x541dc866) // return address of frame 0 - // inside remoting_core!nsc_ECDSAVerifyStub+0x32 - .Mark(&frame1_esp) - .D32(0x04247860) - .D32(0x01a3eaec) - .D32(0x01a3eaf8) - .D32(0x541e304f) // remoting_core!sftk_SessionFromHandle+0x58 - .D32(0x0404c620) - .D32(0x00000040) - .D32(0x01a3eb2c) - .D32(0x01a3ec08) - .D32(0x00000014) - .Mark(&frame1_ebp) - .D32(frame2_ebp) // Child %ebp - .D32(0x541e1234) // return address of frame 1 - // inside remoting_core!NSC_Verify+0x61 - .Mark(&frame2_esp) - .D32(0x04247858) - .D32(0x0404c620) - .D32(0x00000040) - .D32(0x01a3ec08) - .D32(0x00000014) - .D32(0x01000005) - .D32(0x00b2f7a0) - .D32(0x041f0420) - .D32(0x041f3650) - .Mark(&frame2_ebp) - .D32(frame3_ebp) // Child %ebp - .D32(0x541b734d) // return address of frame 1 - // inside remoting_core!PK11_Verify+0x139 - .Mark(&frame3_esp) - .D32(0x01000005) - .D32(0x01a3ec08) - .D32(0x00000014) - .D32(0x0404c620) - .D32(0x00000040) - .D32(0x04073e00) - .D32(0x04073e00) - .D32(0x04247050) - .D32(0x00001041) - .D32(0x00000000) - .D32(0x00000000) - .D32(0x00000000) - .Mark(&frame3_ebp) - .D32(0) // saved %ebp (stack end) - .D32(0); // saved %eip (stack end) - - RegionFromSection(); - raw_context.eip = 0x4247860; // IP address not in known module - raw_context.ebp = 0x5420362d; // bogus - raw_context.esp = frame0_esp.Value(); - - // sanity - ASSERT_TRUE(raw_context.esp == stack_section.start().Value()); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, - &local_modules, &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - if (has_corrupt_symbols) { - ASSERT_EQ(1U, modules_with_corrupt_symbols.size()); - ASSERT_EQ("remoting_core.dll", - modules_with_corrupt_symbols[0]->debug_file()); - } else { - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - } - frames = call_stack.frames(); - - ASSERT_EQ(4U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ(raw_context.eip, frame0->context.eip); - EXPECT_EQ(raw_context.ebp, frame0->context.ebp); - EXPECT_EQ(raw_context.esp, frame0->context.esp); - EXPECT_EQ(NULL, frame0->module); // IP not in known module - EXPECT_EQ("", frame0->function_name); - ASSERT_EQ(NULL, frame0->windows_frame_info); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame1->context_validity); - EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_EQ(&remoting_core_dll, frame1->module); - EXPECT_EQ("nsc_ECDSAVerifyStub", frame1->function_name); - ASSERT_TRUE(frame1->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame1->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", - frame1->windows_frame_info->program_string); - EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame2 = static_cast(frames->at(2)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame2->context_validity); - EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp); - EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); - EXPECT_EQ(&remoting_core_dll, frame2->module); - EXPECT_EQ("NSC_Verify", frame2->function_name); - ASSERT_TRUE(frame2->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame2->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", - frame2->windows_frame_info->program_string); - EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame3 = static_cast(frames->at(3)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame3->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP), - frame3->context_validity); - EXPECT_EQ(frame3_ebp.Value(), frame3->context.ebp); - EXPECT_EQ(frame3_esp.Value(), frame3->context.esp); - EXPECT_EQ(&remoting_core_dll, frame3->module); - EXPECT_EQ("PK11_Verify", frame3->function_name); - ASSERT_TRUE(frame3->windows_frame_info != NULL); - EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame3->windows_frame_info->valid); - EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, - frame3->windows_frame_info->type_); - EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", - frame3->windows_frame_info->program_string); - EXPECT_FALSE(frame3->windows_frame_info->allocates_base_pointer); - } -} - -// Runs IPAddressIsNotInKnownModule test with good symbols -TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule) { - IPAddressIsNotInKnownModuleTestImpl(false /* has_corrupt_modules */); -} - -// Runs IPAddressIsNotInKnownModule test with corrupt symbols -TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule_CorruptSymbols) { - IPAddressIsNotInKnownModuleTestImpl(true /* has_corrupt_modules */); -} - -struct CFIFixture: public StackwalkerX86Fixture { - CFIFixture() { - // Provide a bunch of STACK CFI records; individual tests walk to the - // caller from every point in this series, expecting to find the same - // set of register values. - SetModuleSymbols(&module1, - // The youngest frame's function. - "FUNC 4000 1000 10 enchiridion\n" - // Initially, just a return address. - "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n" - // Push %ebx. - "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n" - // Move %esi into %ebx. Weird, but permitted. - "STACK CFI 4002 $esi: $ebx\n" - // Allocate frame space, and save %edi. - "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n" - // Put the return address in %edi. - "STACK CFI 4005 .ra: $edi\n" - // Save %ebp, and use it as a frame pointer. - "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n" - - // The calling function. - "FUNC 5000 1000 10 epictetus\n" - // Mark it as end of stack. - "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n"); - - // Provide some distinctive values for the caller's registers. - expected.esp = 0x80000000; - expected.eip = 0x40005510; - expected.ebp = 0xc0d4aab9; - expected.ebx = 0x60f20ce6; - expected.esi = 0x53d1379d; - expected.edi = 0xafbae234; - - // By default, registers are unchanged. - raw_context = expected; - } - - // Walk the stack, using stack_section as the contents of the stack - // and raw_context as the current register values. (Set - // raw_context.esp to the stack's starting address.) Expect two - // stack frames; in the older frame, expect the callee-saves - // registers to have values matching those in 'expected'. - void CheckWalk() { - RegionFromSection(); - raw_context.esp = stack_section.start().Value(); - - StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, - &frame_symbolizer); - vector modules_without_symbols; - vector modules_with_corrupt_symbols; - ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, - &modules_with_corrupt_symbols)); - ASSERT_EQ(0U, modules_without_symbols.size()); - ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); - frames = call_stack.frames(); - ASSERT_EQ(2U, frames->size()); - - { // To avoid reusing locals by mistake - StackFrameX86 *frame0 = static_cast(frames->at(0)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); - ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); - EXPECT_EQ("enchiridion", frame0->function_name); - EXPECT_EQ(0x40004000U, frame0->function_base); - ASSERT_TRUE(frame0->windows_frame_info != NULL); - ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, - frame0->windows_frame_info->valid); - ASSERT_TRUE(frame0->cfi_frame_info != NULL); - } - - { // To avoid reusing locals by mistake - StackFrameX86 *frame1 = static_cast(frames->at(1)); - EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); - ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | - StackFrameX86::CONTEXT_VALID_ESP | - StackFrameX86::CONTEXT_VALID_EBP | - StackFrameX86::CONTEXT_VALID_EBX | - StackFrameX86::CONTEXT_VALID_ESI | - StackFrameX86::CONTEXT_VALID_EDI), - frame1->context_validity); - EXPECT_EQ(expected.eip, frame1->context.eip); - EXPECT_EQ(expected.esp, frame1->context.esp); - EXPECT_EQ(expected.ebp, frame1->context.ebp); - EXPECT_EQ(expected.ebx, frame1->context.ebx); - EXPECT_EQ(expected.esi, frame1->context.esi); - EXPECT_EQ(expected.edi, frame1->context.edi); - EXPECT_EQ("epictetus", frame1->function_name); - } - } - - // The values the stack walker should find for the caller's registers. - MDRawContextX86 expected; -}; - -class CFI: public CFIFixture, public Test { }; - -TEST_F(CFI, At4000) { - Label frame1_esp = expected.esp; - stack_section - .D32(0x40005510) // return address - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004000; - CheckWalk(); -} - -TEST_F(CFI, At4001) { - Label frame1_esp = expected.esp; - stack_section - .D32(0x60f20ce6) // saved %ebx - .D32(0x40005510) // return address - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004001; - raw_context.ebx = 0x91aa9a8b; // callee's %ebx value - CheckWalk(); -} - -TEST_F(CFI, At4002) { - Label frame1_esp = expected.esp; - stack_section - .D32(0x60f20ce6) // saved %ebx - .D32(0x40005510) // return address - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004002; - raw_context.ebx = 0x53d1379d; // saved %esi - raw_context.esi = 0xa5c790ed; // callee's %esi value - CheckWalk(); -} - -TEST_F(CFI, At4003) { - Label frame1_esp = expected.esp; - stack_section - .D32(0x56ec3db7) // garbage - .D32(0xafbae234) // saved %edi - .D32(0x53d67131) // garbage - .D32(0x60f20ce6) // saved %ebx - .D32(0x40005510) // return address - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004003; - raw_context.ebx = 0x53d1379d; // saved %esi - raw_context.esi = 0xa97f229d; // callee's %esi - raw_context.edi = 0xb05cc997; // callee's %edi - CheckWalk(); -} - -// The results here should be the same as those at module offset -// 0x4003. -TEST_F(CFI, At4004) { - Label frame1_esp = expected.esp; - stack_section - .D32(0xe29782c2) // garbage - .D32(0xafbae234) // saved %edi - .D32(0x5ba29ce9) // garbage - .D32(0x60f20ce6) // saved %ebx - .D32(0x40005510) // return address - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004004; - raw_context.ebx = 0x53d1379d; // saved %esi - raw_context.esi = 0x0fb7dc4e; // callee's %esi - raw_context.edi = 0x993b4280; // callee's %edi - CheckWalk(); -} - -TEST_F(CFI, At4005) { - Label frame1_esp = expected.esp; - stack_section - .D32(0xe29782c2) // garbage - .D32(0xafbae234) // saved %edi - .D32(0x5ba29ce9) // garbage - .D32(0x60f20ce6) // saved %ebx - .D32(0x8036cc02) // garbage - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004005; - raw_context.ebx = 0x53d1379d; // saved %esi - raw_context.esi = 0x0fb7dc4e; // callee's %esi - raw_context.edi = 0x40005510; // return address - CheckWalk(); -} - -TEST_F(CFI, At4006) { - Label frame0_ebp; - Label frame1_esp = expected.esp; - stack_section - .D32(0xdcdd25cd) // garbage - .D32(0xafbae234) // saved %edi - .D32(0xc0d4aab9) // saved %ebp - .Mark(&frame0_ebp) // frame pointer points here - .D32(0x60f20ce6) // saved %ebx - .D32(0x8036cc02) // garbage - .Mark(&frame1_esp); // This effectively sets stack_section.start(). - raw_context.eip = 0x40004006; - raw_context.ebp = frame0_ebp.Value(); - raw_context.ebx = 0x53d1379d; // saved %esi - raw_context.esi = 0x743833c9; // callee's %esi - raw_context.edi = 0x40005510; // return address - CheckWalk(); -} - diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/static_address_map-inl.h deleted file mode 100644 index 67e07976e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map-inl.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_address_map-inl.h: StaticAddressMap implementation. -// -// See static_address_map.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_ADDRESS_MAP_INL_H__ -#define PROCESSOR_STATIC_ADDRESS_MAP_INL_H__ - -#include "processor/static_address_map.h" - -#include "processor/logging.h" - -namespace google_breakpad { - -template -bool StaticAddressMap::Retrieve( - const AddressType &address, - const EntryType *&entry, AddressType *entry_address) const { - - // upper_bound gives the first element whose key is greater than address, - // but we want the first element whose key is less than or equal to address. - // Decrement the iterator to get there, but not if the upper_bound already - // points to the beginning of the map - in that case, address is lower than - // the lowest stored key, so return false. - - MapConstIterator iterator = map_.upper_bound(address); - if (iterator == map_.begin()) - return false; - --iterator; - - entry = iterator.GetValuePtr(); - // Make sure AddressType is a copyable basic type - if (entry_address) - *entry_address = iterator.GetKey(); - - return true; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_ADDRESS_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map.h b/toolkit/crashreporter/google-breakpad/src/processor/static_address_map.h deleted file mode 100644 index 6bafc6675..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_address_map.h: StaticAddressMap. -// -// StaticAddressMap is a wrapper class of StaticMap, just as AddressMap wraps -// std::map. StaticAddressMap provides read-only Retrieve() operation, similar -// as AddressMap. However, the difference between StaticAddressMap and -// AddressMap is that StaticAddressMap does not support dynamic operation -// Store() due to the static nature of the underlying StaticMap. -// -// See address_map.h for reference. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_ADDRESS_MAP_H__ -#define PROCESSOR_STATIC_ADDRESS_MAP_H__ - -#include "processor/static_map-inl.h" - -namespace google_breakpad { - -// AddressType MUST be a basic type, e.g.: integer types etc -// EntryType could be a complex type, so we retrieve its pointer instead. -template -class StaticAddressMap { - public: - StaticAddressMap(): map_() { } - explicit StaticAddressMap(const char *map_data): map_(map_data) { } - - // Locates the entry stored at the highest address less than or equal to - // the address argument. If there is no such range, returns false. The - // entry is returned in entry, which is a required argument. If - // entry_address is not NULL, it will be set to the address that the entry - // was stored at. - bool Retrieve(const AddressType &address, - const EntryType *&entry, AddressType *entry_address) const; - - private: - friend class ModuleComparer; - // Convenience types. - typedef StaticAddressMap* SelfPtr; - typedef StaticMap AddressToEntryMap; - typedef typename AddressToEntryMap::const_iterator MapConstIterator; - - AddressToEntryMap map_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_ADDRESS_MAP_H__ - diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/static_address_map_unittest.cc deleted file mode 100644 index 12c735cff..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_address_map_unittest.cc +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_address_map_unittest.cc: Unit tests for StaticAddressMap. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include -#include -#include -#include -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "processor/address_map-inl.h" -#include "processor/static_address_map-inl.h" -#include "processor/simple_serializer-inl.h" -#include "map_serializers-inl.h" - -typedef google_breakpad::StaticAddressMap TestMap; -typedef google_breakpad::AddressMap AddrMap; - -class TestStaticAddressMap : public ::testing::Test { - protected: - void SetUp() { - for (int testcase = 0; testcase < kNumberTestCases; ++testcase) { - testdata[testcase] = new int[testsize[testcase]]; - } - - // Test data set0: NULL (empty map) - - // Test data set1: single element. - testdata[1][0] = 10; - - // Test data set2: six elements. - const int tempdata[] = {5, 10, 14, 15, 16, 20}; - for (int i = 0; i < testsize[2]; ++i) - testdata[2][i] = tempdata[i]; - - // Test data set3: - srand(time(NULL)); - for (int i = 0; i < testsize[3]; ++i) - testdata[3][i] = rand(); - - // Setup maps. - std::stringstream sstream; - for (int testcase = 0; testcase < kNumberTestCases; ++testcase) { - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - sstream.clear(); - sstream << "test " << testdata[testcase][data_item]; - addr_map[testcase].Store(testdata[testcase][data_item], sstream.str()); - } - map_data[testcase] = serializer.Serialize(addr_map[testcase], NULL); - test_map[testcase] = TestMap(map_data[testcase]); - } - } - - void TearDown() { - for (int i = 0; i < kNumberTestCases; ++i) { - delete [] map_data[i]; - delete [] testdata[i]; - } - } - - void CompareRetrieveResult(int testcase, int target) { - int address; - int address_test; - string entry; - string entry_test; - const char *entry_cstring = NULL; - bool found; - bool found_test; - - found = addr_map[testcase].Retrieve(target, &entry, &address); - found_test = - test_map[testcase].Retrieve(target, entry_cstring, &address_test); - - ASSERT_EQ(found, found_test); - - if (found && found_test) { - ASSERT_EQ(address, address_test); - entry_test = entry_cstring; - ASSERT_EQ(entry, entry_test); - } - } - - void RetrieveTester(int testcase) { - int target; - target = INT_MIN; - CompareRetrieveResult(testcase, target); - target = INT_MAX; - CompareRetrieveResult(testcase, target); - - srand(time(0)); - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - // Retrive (aka, search) for target address and compare results from - // AddressMap and StaticAddressMap. - - // First, assign the search target to be one of original testdata that is - // known to exist in the map. - target = testdata[testcase][data_item]; - CompareRetrieveResult(testcase, target); - // Then, add +2 / -1 bias to target value, in order to test searching for - // a target address not stored in the map. - target -= 1; - CompareRetrieveResult(testcase, target); - target += 3; - CompareRetrieveResult(testcase, target); - // Repeatedly test searching for random target addresses. - target = rand(); - CompareRetrieveResult(testcase, target); - } - } - - // Test data sets: - static const int kNumberTestCases = 4; - static const int testsize[]; - int *testdata[kNumberTestCases]; - - AddrMap addr_map[kNumberTestCases]; - TestMap test_map[kNumberTestCases]; - char *map_data[kNumberTestCases]; - google_breakpad::AddressMapSerializer serializer; -}; - -const int TestStaticAddressMap::testsize[] = {0, 1, 6, 1000}; - -TEST_F(TestStaticAddressMap, TestEmptyMap) { - int testcase = 0; - int target; - target = INT_MIN; - CompareRetrieveResult(testcase, target); - target = INT_MAX; - CompareRetrieveResult(testcase, target); - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - target = testdata[testcase][data_item]; - CompareRetrieveResult(testcase, target); - target -= 1; - CompareRetrieveResult(testcase, target); - target += 3; - CompareRetrieveResult(testcase, target); - target = rand(); - CompareRetrieveResult(testcase, target); - } -} - -TEST_F(TestStaticAddressMap, TestOneElementMap) { - int testcase = 1; - int target; - target = INT_MIN; - CompareRetrieveResult(testcase, target); - target = INT_MAX; - CompareRetrieveResult(testcase, target); - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - target = testdata[testcase][data_item]; - CompareRetrieveResult(testcase, target); - target -= 1; - CompareRetrieveResult(testcase, target); - target += 3; - CompareRetrieveResult(testcase, target); - target = rand(); - CompareRetrieveResult(testcase, target); - } -} - -TEST_F(TestStaticAddressMap, TestSixElementsMap) { - int testcase = 2; - int target; - target = INT_MIN; - CompareRetrieveResult(testcase, target); - target = INT_MAX; - CompareRetrieveResult(testcase, target); - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - target = testdata[testcase][data_item]; - CompareRetrieveResult(testcase, target); - target -= 1; - CompareRetrieveResult(testcase, target); - target += 3; - CompareRetrieveResult(testcase, target); - target = rand(); - CompareRetrieveResult(testcase, target); - } -} - -TEST_F(TestStaticAddressMap, Test1000RandomElementsMap) { - int testcase = 3; - int target; - target = INT_MIN; - CompareRetrieveResult(testcase, target); - target = INT_MAX; - CompareRetrieveResult(testcase, target); - for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - target = testdata[testcase][data_item]; - CompareRetrieveResult(testcase, target); - target -= 1; - CompareRetrieveResult(testcase, target); - target += 3; - CompareRetrieveResult(testcase, target); - target = rand(); - CompareRetrieveResult(testcase, target); - } -} - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map-inl.h deleted file mode 100644 index 777c76218..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map-inl.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_contained_range_map-inl.h: Hierarchically-organized range map, -// i.e., StaticContainedRangeMap implementation. -// -// See static_contained_range_map.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_CONTAINED_RANGE_MAP_INL_H__ -#define PROCESSOR_STATIC_CONTAINED_RANGE_MAP_INL_H__ - -#include "processor/static_contained_range_map.h" -#include "processor/logging.h" - -namespace google_breakpad { - -template -StaticContainedRangeMap::StaticContainedRangeMap( - const char *base) - : base_(*(reinterpret_cast(base))), - entry_size_(*(reinterpret_cast(base + sizeof(base_)))), - entry_ptr_(reinterpret_cast( - base + sizeof(base_) + sizeof(entry_size_))), - map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) { - if (entry_size_ == 0) - entry_ptr_ = NULL; -} - - -template -bool StaticContainedRangeMap::RetrieveRange( - const AddressType &address, const EntryType *&entry) const { - - // Get an iterator to the child range whose high address is equal to or - // greater than the supplied address. If the supplied address is higher - // than all of the high addresses in the range, then this range does not - // contain a child at address, so return false. If the supplied address - // is lower than the base address of the child range, then it is not within - // the child range, so return false. - MapConstIterator iterator = map_.lower_bound(address); - - if (iterator == map_.end()) - return false; - - const char *memory_child = - reinterpret_cast(iterator.GetValuePtr()); - - StaticContainedRangeMap child_map(memory_child); - - if (address < child_map.base_) - return false; - - // The child in iterator->second contains the specified address. Find out - // if it has a more-specific descendant that also contains it. If it does, - // it will set |entry| appropriately. If not, set |entry| to the child. - if (!child_map.RetrieveRange(address, entry)) - entry = child_map.entry_ptr_; - - return true; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_CONTAINED_RANGE_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map.h b/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map.h deleted file mode 100644 index 6a9b8b7b6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_contained_range_map.h: StaticContainedRangeMap. -// -// StaticContainedRangeMap is similar to ContainedRangeMap. However, -// StaticContainedRangeMap wraps a StaticMap instead of std::map, and does not -// support dynamic operations like StoreRange(...). -// StaticContainedRangeMap provides same RetrieveRange(...) interfaces as -// ContainedRangeMap. -// -// Please see contained_range_map.h for more documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_CONTAINED_RANGE_MAP_H__ -#define PROCESSOR_STATIC_CONTAINED_RANGE_MAP_H__ - -#include "processor/static_map-inl.h" - -namespace google_breakpad { - -template -class StaticContainedRangeMap { - public: - StaticContainedRangeMap(): base_(), entry_size_(), entry_ptr_(), map_() { } - explicit StaticContainedRangeMap(const char *base); - - // Retrieves the most specific (smallest) descendant range encompassing - // the specified address. This method will only return entries held by - // child ranges, and not the entry contained by |this|. This is necessary - // to support a sparsely-populated root range. If no descendant range - // encompasses the address, returns false. - bool RetrieveRange(const AddressType &address, const EntryType *&entry) const; - - private: - friend class ModuleComparer; - // AddressToRangeMap stores pointers. This makes reparenting simpler in - // StoreRange, because it doesn't need to copy entire objects. - typedef StaticContainedRangeMap* SelfPtr; - typedef - StaticMap AddressToRangeMap; - typedef typename AddressToRangeMap::const_iterator MapConstIterator; - - // The base address of this range. The high address does not need to - // be stored, because it is used as the key to an object in its parent's - // map, and all ContainedRangeMaps except for the root range are contained - // within maps. The root range does not actually contain an entry, so its - // base_ field is meaningless, and the fact that it has no parent and thus - // no key is unimportant. For this reason, the base_ field should only be - // is accessed on child ContainedRangeMap objects, and never on |this|. - AddressType base_; - - // The entry corresponding to this range. The root range does not - // actually contain an entry, so its entry_ field is meaningless. For - // this reason, the entry_ field should only be accessed on child - // ContainedRangeMap objects, and never on |this|. - uint32_t entry_size_; - const EntryType *entry_ptr_; - - // The map containing child ranges, keyed by each child range's high - // address. This is a pointer to avoid allocating map structures for - // leaf nodes, where they are not needed. - AddressToRangeMap map_; -}; - -} // namespace google_breakpad - - -#endif // PROCESSOR_STATIC_CONTAINED_RANGE_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map_unittest.cc deleted file mode 100644 index 4ee47578e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map_unittest.cc +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_contained_range_map_unittest.cc: Unit tests for -// StaticContainedRangeMap. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" -#include "processor/contained_range_map-inl.h" -#include "processor/static_contained_range_map-inl.h" -#include "processor/simple_serializer-inl.h" -#include "processor/map_serializers-inl.h" -#include "processor/logging.h" - -namespace { - -typedef google_breakpad::ContainedRangeMap CRMMap; -typedef google_breakpad::StaticContainedRangeMap TestMap; - -// Each element in test_data contains the expected result when calling -// RetrieveRange on an address. -const int test_data[] = { - 0, // 0 - 0, // 1 - 0, // 2 - 0, // 3 - 0, // 4 - 0, // 5 - 0, // 6 - 0, // 7 - 9, // 8 - 7, // 9 - 1, // 10 - 5, // 11 - 6, // 12 - 6, // 13 - 6, // 14 - 6, // 15 - 6, // 16 - 6, // 17 - 6, // 18 - 5, // 19 - 7, // 20 - 8, // 21 - 0, // 22 - 0, // 23 - 0, // 24 - 0, // 25 - 0, // 26 - 0, // 27 - 0, // 28 - 0, // 29 - 10, // 30 - 10, // 31 - 10, // 32 - 11, // 33 - 11, // 34 - 11, // 35 - 0, // 36 - 0, // 37 - 0, // 38 - 0, // 39 - 14, // 40 - 14, // 41 - 14, // 42 - 14, // 43 - 15, // 44 - 15, // 45 - 15, // 46 - 15, // 47 - 0, // 48 - 0, // 49 - 19, // 50 - 18, // 51 - 18, // 52 - 18, // 53 - 18, // 54 - 18, // 55 - 18, // 56 - 18, // 57 - 18, // 58 - 20, // 59 - 21, // 60 - 25, // 61 - 26, // 62 - 26, // 63 - 26, // 64 - 26, // 65 - 26, // 66 - 26, // 67 - 24, // 68 - 22, // 69 - 30, // 70 - 30, // 71 - 30, // 72 - 30, // 73 - 31, // 74 - 31, // 75 - 30, // 76 - 32, // 77 - 32, // 78 - 30, // 79 - 34, // 80 - 35, // 81 - 36, // 82 - 39, // 83 - 38, // 84 - 37, // 85 - 43, // 86 - 44, // 87 - 41, // 88 - 45, // 89 - 42, // 90 - 0, // 91 - 0, // 92 - 0, // 93 - 0, // 94 - 0, // 95 - 0, // 96 - 0, // 97 - 0, // 98 - 0 // 99 -}; - -} // namespace - -namespace google_breakpad { - -class TestStaticCRMMap : public ::testing::Test { - protected: - void SetUp(); - - // A referrence map for testing StaticCRMMap. - google_breakpad::ContainedRangeMap crm_map_; - - // Static version of crm_map using serialized data of crm_map. - // The goal of testing is to make sure TestMap provides same results for - // lookup operation(s) as CRMMap does. - google_breakpad::StaticContainedRangeMap test_map_; - - google_breakpad::ContainedRangeMapSerializer serializer_; - - scoped_array serialized_data_; -}; - -void TestStaticCRMMap::SetUp() { - // First, do the StoreRange tests. This validates the containment - // rules. - // We confirm the referrence map correctly stores data during setup. - ASSERT_TRUE (crm_map_.StoreRange(10, 10, 1)); - ASSERT_FALSE(crm_map_.StoreRange(10, 10, 2)); // exactly equal to 1 - ASSERT_FALSE(crm_map_.StoreRange(11, 10, 3)); // begins inside 1 and extends up - ASSERT_FALSE(crm_map_.StoreRange( 9, 10, 4)); // begins below 1 and ends inside - ASSERT_TRUE (crm_map_.StoreRange(11, 9, 5)); // contained by existing - ASSERT_TRUE (crm_map_.StoreRange(12, 7, 6)); - ASSERT_TRUE (crm_map_.StoreRange( 9, 12, 7)); // contains existing - ASSERT_TRUE (crm_map_.StoreRange( 9, 13, 8)); - ASSERT_TRUE (crm_map_.StoreRange( 8, 14, 9)); - ASSERT_TRUE (crm_map_.StoreRange(30, 3, 10)); - ASSERT_TRUE (crm_map_.StoreRange(33, 3, 11)); - ASSERT_TRUE (crm_map_.StoreRange(30, 6, 12)); // storable but totally masked - ASSERT_TRUE (crm_map_.StoreRange(40, 8, 13)); // will be totally masked - ASSERT_TRUE (crm_map_.StoreRange(40, 4, 14)); - ASSERT_TRUE (crm_map_.StoreRange(44, 4, 15)); - ASSERT_FALSE(crm_map_.StoreRange(32, 10, 16)); // begins in #10, ends in #14 - ASSERT_FALSE(crm_map_.StoreRange(50, 0, 17)); // zero length - ASSERT_TRUE (crm_map_.StoreRange(50, 10, 18)); - ASSERT_TRUE (crm_map_.StoreRange(50, 1, 19)); - ASSERT_TRUE (crm_map_.StoreRange(59, 1, 20)); - ASSERT_TRUE (crm_map_.StoreRange(60, 1, 21)); - ASSERT_TRUE (crm_map_.StoreRange(69, 1, 22)); - ASSERT_TRUE (crm_map_.StoreRange(60, 10, 23)); - ASSERT_TRUE (crm_map_.StoreRange(68, 1, 24)); - ASSERT_TRUE (crm_map_.StoreRange(61, 1, 25)); - ASSERT_TRUE (crm_map_.StoreRange(61, 8, 26)); - ASSERT_FALSE(crm_map_.StoreRange(59, 9, 27)); - ASSERT_FALSE(crm_map_.StoreRange(59, 10, 28)); - ASSERT_FALSE(crm_map_.StoreRange(59, 11, 29)); - ASSERT_TRUE (crm_map_.StoreRange(70, 10, 30)); - ASSERT_TRUE (crm_map_.StoreRange(74, 2, 31)); - ASSERT_TRUE (crm_map_.StoreRange(77, 2, 32)); - ASSERT_FALSE(crm_map_.StoreRange(72, 6, 33)); - ASSERT_TRUE (crm_map_.StoreRange(80, 3, 34)); - ASSERT_TRUE (crm_map_.StoreRange(81, 1, 35)); - ASSERT_TRUE (crm_map_.StoreRange(82, 1, 36)); - ASSERT_TRUE (crm_map_.StoreRange(83, 3, 37)); - ASSERT_TRUE (crm_map_.StoreRange(84, 1, 38)); - ASSERT_TRUE (crm_map_.StoreRange(83, 1, 39)); - ASSERT_TRUE (crm_map_.StoreRange(86, 5, 40)); - ASSERT_TRUE (crm_map_.StoreRange(88, 1, 41)); - ASSERT_TRUE (crm_map_.StoreRange(90, 1, 42)); - ASSERT_TRUE (crm_map_.StoreRange(86, 1, 43)); - ASSERT_TRUE (crm_map_.StoreRange(87, 1, 44)); - ASSERT_TRUE (crm_map_.StoreRange(89, 1, 45)); - ASSERT_TRUE (crm_map_.StoreRange(87, 4, 46)); - ASSERT_TRUE (crm_map_.StoreRange(87, 3, 47)); - ASSERT_FALSE(crm_map_.StoreRange(86, 2, 48)); - - // Serialize crm_map to generate serialized data. - unsigned int size; - serialized_data_.reset(serializer_.Serialize(&crm_map_, &size)); - BPLOG(INFO) << "Serialized data size: " << size << " Bytes."; - - // Construct test_map_ from serialized data. - test_map_ = TestMap(serialized_data_.get()); -} - -TEST_F(TestStaticCRMMap, TestEmptyMap) { - CRMMap empty_crm_map; - - unsigned int size; - scoped_array serialized_data; - serialized_data.reset(serializer_.Serialize(&empty_crm_map, &size)); - scoped_ptr test_map(new TestMap(serialized_data.get())); - - const unsigned int kCorrectSizeForEmptyMap = 16; - ASSERT_EQ(kCorrectSizeForEmptyMap, size); - - const int *entry_test; - ASSERT_FALSE(test_map->RetrieveRange(-1, entry_test)); - ASSERT_FALSE(test_map->RetrieveRange(0, entry_test)); - ASSERT_FALSE(test_map->RetrieveRange(10, entry_test)); -} - -TEST_F(TestStaticCRMMap, TestSingleElementMap) { - CRMMap crm_map; - // Test on one element: - int entry = 1; - crm_map.StoreRange(10, 10, entry); - - unsigned int size; - scoped_array serialized_data; - serialized_data.reset(serializer_.Serialize(&crm_map, &size)); - scoped_ptr test_map(new TestMap(serialized_data.get())); - - const unsigned int kCorrectSizeForSingleElementMap = 40; - ASSERT_EQ(kCorrectSizeForSingleElementMap, size); - - const int *entry_test; - ASSERT_FALSE(test_map->RetrieveRange(-1, entry_test)); - ASSERT_FALSE(test_map->RetrieveRange(0, entry_test)); - ASSERT_TRUE(test_map->RetrieveRange(10, entry_test)); - ASSERT_EQ(*entry_test, entry); - ASSERT_TRUE(test_map->RetrieveRange(13, entry_test)); - ASSERT_EQ(*entry_test, entry); -} - -TEST_F(TestStaticCRMMap, RunTestData) { - unsigned int test_high = sizeof(test_data) / sizeof(test_data[0]); - - // Now, do the RetrieveRange tests. This further validates that the - // objects were stored properly and that retrieval returns the correct - // object. - // If GENERATE_TEST_DATA is defined, instead of the retrieval tests, a - // new test_data array will be printed. Exercise caution when doing this. - // Be sure to verify the results manually! -#ifdef GENERATE_TEST_DATA - printf(" const int test_data[] = {\n"); -#endif // GENERATE_TEST_DATA - - for (unsigned int address = 0; address < test_high; ++address) { - const int *entryptr; - int value = 0; - if (test_map_.RetrieveRange(address, entryptr)) - value = *entryptr; - -#ifndef GENERATE_TEST_DATA - // Don't use ASSERT inside the loop because it won't show the failed - // |address|, and the line number will always be the same. That makes - // it difficult to figure out which test failed. - EXPECT_EQ(value, test_data[address]) << "FAIL: retrieve address " - << address; -#else // !GENERATE_TEST_DATA - printf(" %d%c%s // %d\n", value, - address == test_high - 1 ? ' ' : ',', - value < 10 ? " " : "", - address); -#endif // !GENERATE_TEST_DATA - } - -#ifdef GENERATE_TEST_DATA - printf(" };\n"); -#endif // GENERATE_TEST_DATA -} - -} // namespace google_breakpad - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/static_map-inl.h deleted file mode 100644 index e6aac6aba..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_map-inl.h +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_map-inl.h: StaticMap implementation. -// -// See static_map.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - - -#ifndef PROCESSOR_STATIC_MAP_INL_H__ -#define PROCESSOR_STATIC_MAP_INL_H__ - -#include "processor/static_map.h" -#include "processor/static_map_iterator-inl.h" -#include "processor/logging.h" - -namespace google_breakpad { - -template -StaticMap::StaticMap(const char* raw_data) - : raw_data_(raw_data), - compare_() { - // First 4 Bytes store the number of nodes. - num_nodes_ = *(reinterpret_cast(raw_data_)); - - offsets_ = reinterpret_cast( - raw_data_ + sizeof(num_nodes_)); - - keys_ = reinterpret_cast( - raw_data_ + (1 + num_nodes_) * sizeof(uint32_t)); -} - -// find(), lower_bound() and upper_bound() implement binary search algorithm. -template -StaticMapIterator -StaticMap::find(const Key &key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int compare_result; - while (begin < end) { - middle = begin + (end - begin) / 2; - compare_result = compare_(key, GetKeyAtIndex(middle)); - if (compare_result == 0) - return IteratorAtIndex(middle); - if (compare_result < 0) { - end = middle; - } else { - begin = middle + 1; - } - } - return this->end(); -} - -template -StaticMapIterator -StaticMap::lower_bound(const Key &key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int comp_result; - while (begin < end) { - middle = begin + (end - begin) / 2; - comp_result = compare_(key, GetKeyAtIndex(middle)); - if (comp_result == 0) - return IteratorAtIndex(middle); - if (comp_result < 0) { - end = middle; - } else { - begin = middle + 1; - } - } - return IteratorAtIndex(begin); -} - -template -StaticMapIterator -StaticMap::upper_bound(const Key &key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int compare_result; - while (begin < end) { - middle = begin + (end - begin) / 2; - compare_result = compare_(key, GetKeyAtIndex(middle)); - if (compare_result == 0) - return IteratorAtIndex(middle + 1); - if (compare_result < 0) { - end = middle; - } else { - begin = middle + 1; - } - } - return IteratorAtIndex(begin); -} - -template -bool StaticMap::ValidateInMemoryStructure() const { - // check the number of nodes is non-negative: - if (!raw_data_) return false; - int32_t num_nodes = *(reinterpret_cast(raw_data_)); - if (num_nodes < 0) { - BPLOG(INFO) << "StaticMap check failed: negative number of nodes"; - return false; - } - - int node_index = 0; - if (num_nodes_) { - uint64_t first_offset = sizeof(int32_t) * (num_nodes_ + 1) - + sizeof(Key) * num_nodes_; - // Num_nodes_ is too large. - if (first_offset > 0xffffffffUL) { - BPLOG(INFO) << "StaticMap check failed: size exceeds limit"; - return false; - } - if (offsets_[node_index] != static_cast(first_offset)) { - BPLOG(INFO) << "StaticMap check failed: first node offset is incorrect"; - return false; - } - } - - for (node_index = 1; node_index < num_nodes_; ++node_index) { - // Check offsets[i] is strictly increasing: - if (offsets_[node_index] <= offsets_[node_index - 1]) { - BPLOG(INFO) << "StaticMap check failed: node offsets non-increasing"; - return false; - } - // Check Key[i] is strictly increasing as no duplicate keys are allowed. - if (compare_(GetKeyAtIndex(node_index), - GetKeyAtIndex(node_index - 1)) <= 0) { - BPLOG(INFO) << "StaticMap check failed: node keys non-increasing"; - return false; - } - } - return true; -} - -template -const Key StaticMap::GetKeyAtIndex(int index) const { - if (index < 0 || index >= num_nodes_) { - BPLOG(ERROR) << "Key index out of range error"; - // Key type is required to be primitive type. Return 0 if index is invalid. - return 0; - } - return keys_[index]; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_map.h b/toolkit/crashreporter/google-breakpad/src/processor/static_map.h deleted file mode 100644 index 9723ab2a8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_map.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_map.h: StaticMap. -// -// StaticMap provides lookup interfaces and iterators similar as stl::map's. -// These lookup operations are purely Read-Only, thus memory -// allocation & deallocation is mostly avoided (intentionally). -// -// The chunk of memory should contain data with pre-defined pattern: -// **************** header *************** -// uint32 (4 bytes): number of nodes -// uint32 (4 bytes): address offset of node1's mapped_value -// uint32 (4 bytes): address offset of node2's mapped_value -// ... -// uint32 (4 bytes): address offset of nodeN's mapped_value -// -// ************* Key array ************ -// (X bytes): node1's key -// (X bytes): node2's key -// ... -// (X bytes): nodeN's key -// -// ************* Value array ********** -// (? bytes): node1's mapped_value -// (? bytes): node2's mapped_value -// ... -// (? bytes): nodeN's mapped_value -// -// REQUIREMENT: Key type MUST be primitive type or pointers so that: -// X = sizeof(typename Key); -// -// Note: since address offset is stored as uint32, user should keep in mind that -// StaticMap only supports up to 4GB size of memory data. - -// Author: Siyang Xie (lambxsy@google.com) - - -#ifndef PROCESSOR_STATIC_MAP_H__ -#define PROCESSOR_STATIC_MAP_H__ - -#include "processor/static_map_iterator-inl.h" - -namespace google_breakpad { - -// Default functor to compare keys. -template -class DefaultCompare { - public: - int operator()(const Key &k1, const Key &k2) const { - if (k1 < k2) return -1; - if (k1 == k2) return 0; - return 1; - } -}; - -template > -class StaticMap { - public: - typedef StaticMapIterator iterator; - typedef StaticMapIterator const_iterator; - - StaticMap() : raw_data_(0), - num_nodes_(0), - offsets_(0), - compare_() { } - - explicit StaticMap(const char* raw_data); - - inline bool empty() const { return num_nodes_ == 0; } - inline unsigned int size() const { return num_nodes_; } - - // Return iterators. - inline iterator begin() const { return IteratorAtIndex(0); } - inline iterator last() const { return IteratorAtIndex(num_nodes_ - 1); } - inline iterator end() const { return IteratorAtIndex(num_nodes_); } - inline iterator IteratorAtIndex(int index) const { - return iterator(raw_data_, index); - } - - // Lookup operations. - iterator find(const Key &k) const; - - // lower_bound(k) searches in a sorted range for the first element that has a - // key not less than the argument k. - iterator lower_bound(const Key &k) const; - - // upper_bound(k) searches in a sorted range for the first element that has a - // key greater than the argument k. - iterator upper_bound(const Key &k) const; - - // Checks if the underlying memory data conforms to the predefined pattern: - // first check the number of nodes is non-negative, - // then check both offsets and keys are strictly increasing (sorted). - bool ValidateInMemoryStructure() const; - - private: - const Key GetKeyAtIndex(int i) const; - - // Start address of a raw memory chunk with serialized data. - const char* raw_data_; - - // Number of nodes in the static map. - int32_t num_nodes_; - - // Array of offset addresses for stored values. - // For example: - // address_of_i-th_node_value = raw_data_ + offsets_[i] - const uint32_t* offsets_; - - // keys_[i] = key of i_th node - const Key* keys_; - - Compare compare_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator-inl.h deleted file mode 100644 index 7a7db5ad9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator-inl.h +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_map_iterator-inl.h: StaticMapIterator implementation. -// -// See static_map_iterator.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_MAP_ITERATOR_INL_H__ -#define PROCESSOR_STATIC_MAP_ITERATOR_INL_H__ - -#include "processor/static_map_iterator.h" - -#include "processor/logging.h" - -namespace google_breakpad { - -template -StaticMapIterator::StaticMapIterator(const char* base, - const int &index): - index_(index), base_(base) { - // See static_map.h for documentation on - // bytes format of serialized StaticMap data. - num_nodes_ = *(reinterpret_cast(base_)); - offsets_ = reinterpret_cast(base_ + sizeof(num_nodes_)); - keys_ = reinterpret_cast( - base_ + (1 + num_nodes_) * sizeof(num_nodes_)); -} - -// Increment & Decrement operators: -template -StaticMapIterator& -StaticMapIterator::operator++() { - if (!IsValid()) { - BPLOG(ERROR) << "operator++ on invalid iterator"; - return *this; - } - if (++index_ > num_nodes_) index_ = num_nodes_; - return *this; -} - -template -StaticMapIterator -StaticMapIterator::operator++(int postfix_operator) { - if (!IsValid()) { - BPLOG(ERROR) << "operator++ on invalid iterator"; - return *this; - } - StaticMapIterator tmp = *this; - if (++index_ > num_nodes_) index_ = num_nodes_; - return tmp; -} - -template -StaticMapIterator& -StaticMapIterator::operator--() { - if (!IsValid()) { - BPLOG(ERROR) << "operator++ on invalid iterator"; - return *this; - } - - if (--index_ < 0) index_ = 0; - return *this; -} - -template -StaticMapIterator -StaticMapIterator::operator--(int postfix_operator) { - if (!IsValid()) { - BPLOG(ERROR) << "operator++ on invalid iterator"; - return *this; - } - StaticMapIterator tmp = *this; - - if (--index_ < 0) index_ = 0; - return tmp; -} - -template -const Key* StaticMapIterator::GetKeyPtr() const { - if (!IsValid()) { - BPLOG(ERROR) << "call GetKeyPtr() on invalid iterator"; - return NULL; - } - return &(keys_[index_]); -} - -template -const char* StaticMapIterator::GetValueRawPtr() const { - if (!IsValid()) { - BPLOG(ERROR) << "call GetValuePtr() on invalid iterator"; - return NULL; - } - return base_ + offsets_[index_]; -} - -template -bool StaticMapIterator::operator==( - const StaticMapIterator& x) const { - return base_ == x.base_ && index_ == x.index_; -} - -template -bool StaticMapIterator::operator!=( - const StaticMapIterator& x) const { - // Only need to compare base_ and index_. - // Other data members are auxiliary. - return base_ != x.base_ || index_ != x.index_; -} - -template -bool StaticMapIterator::IsValid() const { - if (!base_ || index_ < 0 || index_ > num_nodes_) - return false; - - return true; -} - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_MAP_ITERATOR_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator.h b/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator.h deleted file mode 100644 index 1af8fff45..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2010 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_map_iterator.h: StaticMapIterator template class declaration. -// -// StaticMapIterator provides increment and decrement operators to iterate -// through a StaticMap map. It does not provide *, -> operators, user should -// use GetKeyPtr(), GetKey(), GetValuePtr() interfaces to retrieve data or -// pointer to data. StaticMapIterator is essentially a const_iterator. -// -// Author: Siyang Xie (lambxsy@google.com) - - -#ifndef PROCESSOR_STATIC_MAP_ITERATOR_H__ -#define PROCESSOR_STATIC_MAP_ITERATOR_H__ - -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -// Forward declaration. -template class StaticMap; - -// StaticMapIterator does not support operator*() or operator->(), -// User should use GetKey(), GetKeyPtr(), GetValuePtr() instead; -template -class StaticMapIterator { - public: - // Constructors. - StaticMapIterator(): index_(-1), base_(NULL) { } - - // Increment & Decrement operators: - StaticMapIterator& operator++(); - StaticMapIterator operator++(int post_fix_operator); - - StaticMapIterator& operator--(); - StaticMapIterator operator--(int post_fix_operator); - - // Interface for retrieving data / pointer to data. - const Key* GetKeyPtr() const; - - // Run time error will occur if GetKey() is called on an invalid iterator. - inline const Key GetKey() const { return *GetKeyPtr(); } - - // return a raw memory pointer that points to the start address of value. - const char* GetValueRawPtr() const; - - // return a reinterpret-casted pointer to the value. - inline const Value* GetValuePtr() const { - return reinterpret_cast(GetValueRawPtr()); - } - - bool operator==(const StaticMapIterator& x) const; - bool operator!=(const StaticMapIterator& x) const; - - // Check if this iterator is valid. - // If iterator is invalid, user is forbidden to use ++/-- operator - // or interfaces for retrieving data / pointer to data. - bool IsValid() const; - - private: - friend class StaticMap; - - // Only StaticMap can call this constructor. - explicit StaticMapIterator(const char* base, const int32_t &index); - - // Index of node that the iterator is pointing to. - int32_t index_; - - // Beginning address of the serialized map data. - const char* base_; - - // Number of nodes in the map. Use it to identify end() iterator. - int32_t num_nodes_; - - // offsets_ is an array of offset addresses of mapped values. - // For example: - // address_of_i-th_node_value = base_ + offsets_[i] - const uint32_t* offsets_; - - // keys_[i] = key of i_th node. - const Key* keys_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_MAP_ITERATOR_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc deleted file mode 100644 index 393d43d5c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_map_unittest.cc: Unit tests for StaticMap. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "processor/static_map-inl.h" - - -typedef int ValueType; -typedef int KeyType; -typedef google_breakpad::StaticMap< KeyType, ValueType > TestMap; -typedef std::map< KeyType, ValueType > StdMap; - -template -class SimpleMapSerializer { - public: - static char* Serialize(const std::map &stdmap, - unsigned int* size = NULL) { - unsigned int size_per_node = - sizeof(uint32_t) + sizeof(Key) + sizeof(Value); - unsigned int memsize = sizeof(int32_t) + size_per_node * stdmap.size(); - if (size) *size = memsize; - - // Allocate memory for serialized data: - char* mem = reinterpret_cast(operator new(memsize)); - char* address = mem; - - // Writer the number of nodes: - new (address) uint32_t(static_cast(stdmap.size())); - address += sizeof(uint32_t); - - // Nodes' offset: - uint32_t* offsets = reinterpret_cast(address); - address += sizeof(uint32_t) * stdmap.size(); - - // Keys: - Key* keys = reinterpret_cast(address); - address += sizeof(Key) * stdmap.size(); - - // Traversing map: - typename std::map::const_iterator iter = stdmap.begin(); - for (int index = 0; iter != stdmap.end(); ++iter, ++index) { - offsets[index] = static_cast(address - mem); - keys[index] = iter->first; - new (address) Value(iter->second); - address += sizeof(Value); - } - return mem; - } -}; - - -class TestInvalidMap : public ::testing::Test { - protected: - void SetUp() { - memset(data, 0, kMemorySize); - } - - // 40 Bytes memory can hold a StaticMap with up to 3 nodes. - static const int kMemorySize = 40; - char data[kMemorySize]; - TestMap test_map; -}; - -TEST_F(TestInvalidMap, TestNegativeNumberNodes) { - memset(data, 0xff, sizeof(uint32_t)); // Set the number of nodes = -1 - test_map = TestMap(data); - ASSERT_FALSE(test_map.ValidateInMemoryStructure()); -} - -TEST_F(TestInvalidMap, TestWrongOffsets) { - uint32_t* header = reinterpret_cast(data); - const uint32_t kNumNodes = 2; - const uint32_t kHeaderOffset = - sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType)); - - header[0] = kNumNodes; - header[1] = kHeaderOffset + 3; // Wrong offset for first node - test_map = TestMap(data); - ASSERT_FALSE(test_map.ValidateInMemoryStructure()); - - header[1] = kHeaderOffset; // Correct offset for first node - header[2] = kHeaderOffset - 1; // Wrong offset for second node - test_map = TestMap(data); - ASSERT_FALSE(test_map.ValidateInMemoryStructure()); -} - -TEST_F(TestInvalidMap, TestUnSortedKeys) { - uint32_t* header = reinterpret_cast(data); - const uint32_t kNumNodes = 2; - const uint32_t kHeaderOffset = - sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType)); - header[0] = kNumNodes; - header[1] = kHeaderOffset; - header[2] = kHeaderOffset + sizeof(ValueType); - - KeyType* keys = reinterpret_cast( - data + (kNumNodes + 1) * sizeof(uint32_t)); - // Set keys in non-increasing order. - keys[0] = 10; - keys[1] = 7; - test_map = TestMap(data); - ASSERT_FALSE(test_map.ValidateInMemoryStructure()); -} - - -class TestValidMap : public ::testing::Test { - protected: - void SetUp() { - int testcase = 0; - - // Empty map. - map_data[testcase] = - serializer.Serialize(std_map[testcase], &size[testcase]); - test_map[testcase] = TestMap(map_data[testcase]); - ++testcase; - - // Single element. - std_map[testcase].insert(std::make_pair(2, 8)); - map_data[testcase] = - serializer.Serialize(std_map[testcase], &size[testcase]); - test_map[testcase] = TestMap(map_data[testcase]); - ++testcase; - - // 100 elements. - for (int i = 0; i < 100; ++i) - std_map[testcase].insert(std::make_pair(i, 2 * i)); - map_data[testcase] = - serializer.Serialize(std_map[testcase], &size[testcase]); - test_map[testcase] = TestMap(map_data[testcase]); - ++testcase; - - // 1000 random elements. - for (int i = 0; i < 1000; ++i) - std_map[testcase].insert(std::make_pair(rand(), rand())); - map_data[testcase] = - serializer.Serialize(std_map[testcase], &size[testcase]); - test_map[testcase] = TestMap(map_data[testcase]); - - // Set correct size of memory allocation for each test case. - unsigned int size_per_node = - sizeof(uint32_t) + sizeof(KeyType) + sizeof(ValueType); - for (testcase = 0; testcase < kNumberTestCases; ++testcase) { - correct_size[testcase] = - sizeof(uint32_t) + std_map[testcase].size() * size_per_node; - } - } - - void TearDown() { - for (int i = 0;i < kNumberTestCases; ++i) - ::operator delete(map_data[i]); - } - - - void IteratorTester(int test_case) { - // scan through: - iter_test = test_map[test_case].begin(); - iter_std = std_map[test_case].begin(); - - for (; iter_test != test_map[test_case].end() && - iter_std != std_map[test_case].end(); - ++iter_test, ++iter_std) { - ASSERT_EQ(iter_test.GetKey(), iter_std->first); - ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second); - } - ASSERT_TRUE(iter_test == test_map[test_case].end() - && iter_std == std_map[test_case].end()); - - // Boundary testcase. - if (!std_map[test_case].empty()) { - // rear boundary case: - iter_test = test_map[test_case].end(); - iter_std = std_map[test_case].end(); - --iter_std; - --iter_test; - ASSERT_EQ(iter_test.GetKey(), iter_std->first); - ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second); - - ++iter_test; - ++iter_std; - ASSERT_TRUE(iter_test == test_map[test_case].end()); - - --iter_test; - --iter_std; - ASSERT_TRUE(iter_test != test_map[test_case].end()); - ASSERT_TRUE(iter_test == test_map[test_case].last()); - ASSERT_EQ(iter_test.GetKey(), iter_std->first); - ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second); - - // front boundary case: - iter_test = test_map[test_case].begin(); - --iter_test; - ASSERT_TRUE(iter_test == test_map[test_case].begin()); - } - } - - void CompareLookupResult(int test_case) { - bool found1 = (iter_test != test_map[test_case].end()); - bool found2 = (iter_std != std_map[test_case].end()); - ASSERT_EQ(found1, found2); - - if (found1 && found2) { - ASSERT_EQ(iter_test.GetKey(), iter_std->first); - ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second); - } - } - - void FindTester(int test_case, const KeyType &key) { - iter_test = test_map[test_case].find(key); - iter_std = std_map[test_case].find(key); - CompareLookupResult(test_case); - } - - void LowerBoundTester(int test_case, const KeyType &key) { - iter_test = test_map[test_case].lower_bound(key); - iter_std = std_map[test_case].lower_bound(key); - CompareLookupResult(test_case); - } - - void UpperBoundTester(int test_case, const KeyType &key) { - iter_test = test_map[test_case].upper_bound(key); - iter_std = std_map[test_case].upper_bound(key); - CompareLookupResult(test_case); - } - - void LookupTester(int test_case) { - StdMap::const_iterator iter; - // Test find(): - for (iter = std_map[test_case].begin(); - iter != std_map[test_case].end(); - ++iter) { - FindTester(test_case, iter->first); - FindTester(test_case, iter->first + 1); - FindTester(test_case, iter->first - 1); - } - FindTester(test_case, INT_MIN); - FindTester(test_case, INT_MAX); - // random test: - for (int i = 0; i < rand()%5000 + 5000; ++i) - FindTester(test_case, rand()); - - // Test lower_bound(): - for (iter = std_map[test_case].begin(); - iter != std_map[test_case].end(); - ++iter) { - LowerBoundTester(test_case, iter->first); - LowerBoundTester(test_case, iter->first + 1); - LowerBoundTester(test_case, iter->first - 1); - } - LowerBoundTester(test_case, INT_MIN); - LowerBoundTester(test_case, INT_MAX); - // random test: - for (int i = 0; i < rand()%5000 + 5000; ++i) - LowerBoundTester(test_case, rand()); - - // Test upper_bound(): - for (iter = std_map[test_case].begin(); - iter != std_map[test_case].end(); - ++iter) { - UpperBoundTester(test_case, iter->first); - UpperBoundTester(test_case, iter->first + 1); - UpperBoundTester(test_case, iter->first - 1); - } - UpperBoundTester(test_case, INT_MIN); - UpperBoundTester(test_case, INT_MAX); - // random test: - for (int i = 0; i < rand()%5000 + 5000; ++i) - UpperBoundTester(test_case, rand()); - } - - static const int kNumberTestCases = 4; - StdMap std_map[kNumberTestCases]; - TestMap test_map[kNumberTestCases]; - TestMap::const_iterator iter_test; - StdMap::const_iterator iter_std; - char* map_data[kNumberTestCases]; - unsigned int size[kNumberTestCases]; - unsigned int correct_size[kNumberTestCases]; - SimpleMapSerializer serializer; -}; - -TEST_F(TestValidMap, TestEmptyMap) { - int test_case = 0; - // Assert memory size allocated during serialization is correct. - ASSERT_EQ(correct_size[test_case], size[test_case]); - - // Sanity check of serialized data: - ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure()); - ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty()); - ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size()); - - // Test Iterator. - IteratorTester(test_case); - - // Test lookup operations. - LookupTester(test_case); -} - -TEST_F(TestValidMap, TestSingleElement) { - int test_case = 1; - // Assert memory size allocated during serialization is correct. - ASSERT_EQ(correct_size[test_case], size[test_case]); - - // Sanity check of serialized data: - ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure()); - ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty()); - ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size()); - - // Test Iterator. - IteratorTester(test_case); - - // Test lookup operations. - LookupTester(test_case); -} - -TEST_F(TestValidMap, Test100Elements) { - int test_case = 2; - // Assert memory size allocated during serialization is correct. - ASSERT_EQ(correct_size[test_case], size[test_case]); - - // Sanity check of serialized data: - ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure()); - ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty()); - ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size()); - - // Test Iterator. - IteratorTester(test_case); - - // Test lookup operations. - LookupTester(test_case); -} - -TEST_F(TestValidMap, Test1000RandomElements) { - int test_case = 3; - // Assert memory size allocated during serialization is correct. - ASSERT_EQ(correct_size[test_case], size[test_case]); - - // Sanity check of serialized data: - ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure()); - ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty()); - ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size()); - - // Test Iterator. - IteratorTester(test_case); - - // Test lookup operations. - LookupTester(test_case); -} - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map-inl.h b/toolkit/crashreporter/google-breakpad/src/processor/static_range_map-inl.h deleted file mode 100644 index f6cef1a9e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map-inl.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_range_map-inl.h: StaticRangeMap implementation. -// -// See static_range_map.h for documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_RANGE_MAP_INL_H__ -#define PROCESSOR_STATIC_RANGE_MAP_INL_H__ - -#include "processor/static_range_map.h" -#include "processor/logging.h" - -namespace google_breakpad { - -template -bool StaticRangeMap::RetrieveRange( - const AddressType &address, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) const { - MapConstIterator iterator = map_.lower_bound(address); - if (iterator == map_.end()) - return false; - - // The map is keyed by the high address of each range, so |address| is - // guaranteed to be lower than the range's high address. If |range| is - // not directly preceded by another range, it's possible for address to - // be below the range's low address, though. When that happens, address - // references something not within any range, so return false. - - const Range *range = iterator.GetValuePtr(); - - // Make sure AddressType and EntryType are copyable basic types - // e.g.: integer types, pointers etc - if (address < range->base()) - return false; - - entry = range->entryptr(); - if (entry_base) - *entry_base = range->base(); - if (entry_size) - *entry_size = iterator.GetKey() - range->base() + 1; - - return true; -} - - -template -bool StaticRangeMap::RetrieveNearestRange( - const AddressType &address, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) const { - // If address is within a range, RetrieveRange can handle it. - if (RetrieveRange(address, entry, entry_base, entry_size)) - return true; - - // upper_bound gives the first element whose key is greater than address, - // but we want the first element whose key is less than or equal to address. - // Decrement the iterator to get there, but not if the upper_bound already - // points to the beginning of the map - in that case, address is lower than - // the lowest stored key, so return false. - - MapConstIterator iterator = map_.upper_bound(address); - if (iterator == map_.begin()) - return false; - --iterator; - - const Range *range = iterator.GetValuePtr(); - entry = range->entryptr(); - if (entry_base) - *entry_base = range->base(); - if (entry_size) - *entry_size = iterator.GetKey() - range->base() + 1; - - return true; -} - -template -bool StaticRangeMap::RetrieveRangeAtIndex( - int index, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) const { - - if (index >= GetCount()) { - BPLOG(ERROR) << "Index out of range: " << index << "/" << GetCount(); - return false; - } - - MapConstIterator iterator = map_.IteratorAtIndex(index); - - const Range *range = iterator.GetValuePtr(); - - entry = range->entryptr(); - if (entry_base) - *entry_base = range->base(); - if (entry_size) - *entry_size = iterator.GetKey() - range->base() + 1; - - return true; -} - -} // namespace google_breakpad - - -#endif // PROCESSOR_STATIC_RANGE_MAP_INL_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map.h b/toolkit/crashreporter/google-breakpad/src/processor/static_range_map.h deleted file mode 100644 index 91aabb032..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// static_range_map.h: StaticRangeMap. -// -// StaticRangeMap is similar as RangeMap. However, StaticRangeMap wraps a -// StaticMap instead of std::map, and does not support dynamic operations like -// StoreRange(...). StaticRangeMap provides same Retrieve*() interfaces as -// RangeMap. Please see range_map.h for more documentation. -// -// Author: Siyang Xie (lambxsy@google.com) - -#ifndef PROCESSOR_STATIC_RANGE_MAP_H__ -#define PROCESSOR_STATIC_RANGE_MAP_H__ - - -#include "processor/static_map-inl.h" - -namespace google_breakpad { - -// AddressType is basic type, e.g.: integer types, pointers etc -// EntryType could be a complex type, so we retrieve its pointer instead. -template -class StaticRangeMap { - public: - StaticRangeMap(): map_() { } - explicit StaticRangeMap(const char *memory): map_(memory) { } - - // Locates the range encompassing the supplied address. If there is - // no such range, returns false. entry_base and entry_size, if non-NULL, - // are set to the base and size of the entry's range. - bool RetrieveRange(const AddressType &address, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) const; - - // Locates the range encompassing the supplied address, if one exists. - // If no range encompasses the supplied address, locates the nearest range - // to the supplied address that is lower than the address. Returns false - // if no range meets these criteria. entry_base and entry_size, if - // non-NULL, are set to the base and size of the entry's range. - bool RetrieveNearestRange(const AddressType &address, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) - const; - - // Treating all ranges as a list ordered by the address spaces that they - // occupy, locates the range at the index specified by index. Returns - // false if index is larger than the number of ranges stored. entry_base - // and entry_size, if non-NULL, are set to the base and size of the entry's - // range. - // - // RetrieveRangeAtIndex is not optimized for speedy operation. - bool RetrieveRangeAtIndex(int index, const EntryType *&entry, - AddressType *entry_base, AddressType *entry_size) - const; - - // Returns the number of ranges stored in the RangeMap. - inline int GetCount() const { return map_.size(); } - - private: - friend class ModuleComparer; - class Range { - public: - AddressType base() const { - return *(reinterpret_cast(this)); - } - const EntryType* entryptr() const { - return reinterpret_cast(this + sizeof(AddressType)); - } - }; - - // Convenience types. - typedef StaticRangeMap* SelfPtr; - typedef StaticMap AddressToRangeMap; - typedef typename AddressToRangeMap::const_iterator MapConstIterator; - - AddressToRangeMap map_; -}; - -} // namespace google_breakpad - -#endif // PROCESSOR_STATIC_RANGE_MAP_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/static_range_map_unittest.cc deleted file mode 100644 index 282173622..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/static_range_map_unittest.cc +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// static_range_map_unittest.cc: Unit tests for StaticRangeMap. -// -// Author: Siyang Xie (lambxsy@google.com) - -#include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" -#include "processor/range_map-inl.h" -#include "processor/static_range_map-inl.h" -#include "processor/simple_serializer-inl.h" -#include "processor/map_serializers-inl.h" -#include "processor/logging.h" - - -namespace { -// Types used for testing. -typedef int AddressType; -typedef int EntryType; -typedef google_breakpad::StaticRangeMap< AddressType, EntryType > TestMap; -typedef google_breakpad::RangeMap< AddressType, EntryType > RMap; - -// RangeTest contains data to use for store and retrieve tests. See -// RunTests for descriptions of the tests. -struct RangeTest { - // Base address to use for test - AddressType address; - - // Size of range to use for test - AddressType size; - - // Unique ID of range - unstorable ranges must have unique IDs too - EntryType id; - - // Whether this range is expected to be stored successfully or not - bool expect_storable; -}; - -// A RangeTestSet encompasses multiple RangeTests, which are run in -// sequence on the same RangeMap. -struct RangeTestSet { - // An array of RangeTests - const RangeTest* range_tests; - - // The number of tests in the set - unsigned int range_test_count; -}; - -// These tests will be run sequentially. The first set of tests exercises -// most functions of RangeTest, and verifies all of the bounds-checking. -const RangeTest range_tests_0[] = { - { INT_MIN, 16, 1, true }, // lowest possible range - { -2, 5, 2, true }, // a range through zero - { INT_MAX - 9, 11, 3, false }, // tests anti-overflow - { INT_MAX - 9, 10, 4, true }, // highest possible range - { 5, 0, 5, false }, // tests anti-zero-size - { 5, 1, 6, true }, // smallest possible range - { -20, 15, 7, true }, // entirely negative - - { 10, 10, 10, true }, // causes the following tests to fail - { 9, 10, 11, false }, // one-less base, one-less high - { 9, 11, 12, false }, // one-less base, identical high - { 9, 12, 13, false }, // completely contains existing - { 10, 9, 14, false }, // identical base, one-less high - { 10, 10, 15, false }, // exactly identical to existing range - { 10, 11, 16, false }, // identical base, one-greater high - { 11, 8, 17, false }, // contained completely within - { 11, 9, 18, false }, // one-greater base, identical high - { 11, 10, 19, false }, // one-greater base, one-greater high - { 9, 2, 20, false }, // overlaps bottom by one - { 10, 1, 21, false }, // overlaps bottom by one, contained - { 19, 1, 22, false }, // overlaps top by one, contained - { 19, 2, 23, false }, // overlaps top by one - - { 9, 1, 24, true }, // directly below without overlap - { 20, 1, 25, true }, // directly above without overlap - - { 6, 3, 26, true }, // exactly between two ranges, gapless - { 7, 3, 27, false }, // tries to span two ranges - { 7, 5, 28, false }, // tries to span three ranges - { 4, 20, 29, false }, // tries to contain several ranges - - { 30, 50, 30, true }, - { 90, 25, 31, true }, - { 35, 65, 32, false }, // tries to span two noncontiguous - { 120, 10000, 33, true }, // > 8-bit - { 20000, 20000, 34, true }, // > 8-bit - { 0x10001, 0x10001, 35, true }, // > 16-bit - - { 27, -1, 36, false } // tests high < base -}; - -// Attempt to fill the entire space. The entire space must be filled with -// three stores because AddressType is signed for these tests, so RangeMap -// treats the size as signed and rejects sizes that appear to be negative. -// Even if these tests were run as unsigned, two stores would be needed -// to fill the space because the entire size of the space could only be -// described by using one more bit than would be present in AddressType. -const RangeTest range_tests_1[] = { - { INT_MIN, INT_MAX, 50, true }, // From INT_MIN to -2, inclusive - { -1, 2, 51, true }, // From -1 to 0, inclusive - { 1, INT_MAX, 52, true }, // From 1 to INT_MAX, inclusive - { INT_MIN, INT_MAX, 53, false }, // Can't fill the space twice - { -1, 2, 54, false }, - { 1, INT_MAX, 55, false }, - { -3, 6, 56, false }, // -3 to 2, inclusive - spans 3 ranges -}; - -// A light round of testing to verify that RetrieveRange does the right -// the right thing at the extremities of the range when nothing is stored -// there. Checks are forced without storing anything at the extremities -// by setting size = 0. -const RangeTest range_tests_2[] = { - { INT_MIN, 0, 100, false }, // makes RetrieveRange check low end - { -1, 3, 101, true }, - { INT_MAX, 0, 102, false }, // makes RetrieveRange check high end -}; - -// Similar to the previous test set, but with a couple of ranges closer -// to the extremities. -const RangeTest range_tests_3[] = { - { INT_MIN + 1, 1, 110, true }, - { INT_MAX - 1, 1, 111, true }, - { INT_MIN, 0, 112, false }, // makes RetrieveRange check low end - { INT_MAX, 0, 113, false } // makes RetrieveRange check high end -}; - -// The range map is cleared between sets of tests listed here. -const RangeTestSet range_test_sets[] = { - { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) }, - { range_tests_1, sizeof(range_tests_1) / sizeof(RangeTest) }, - { range_tests_2, sizeof(range_tests_2) / sizeof(RangeTest) }, - { range_tests_3, sizeof(range_tests_3) / sizeof(RangeTest) }, - { range_tests_0, sizeof(range_tests_0) / sizeof(RangeTest) } // Run again -}; - -} // namespace - -namespace google_breakpad { -class TestStaticRangeMap : public ::testing::Test { - protected: - void SetUp() { - kTestCasesCount_ = sizeof(range_test_sets) / sizeof(RangeTestSet); - } - - // StoreTest uses the data in a RangeTest and calls StoreRange on the - // test RangeMap. It returns true if the expected result occurred, and - // false if something else happened. - void StoreTest(RMap* range_map, const RangeTest* range_test); - - // RetrieveTest uses the data in RangeTest and calls RetrieveRange on the - // test RangeMap. If it retrieves the expected value (which can be no - // map entry at the specified range,) it returns true, otherwise, it returns - // false. RetrieveTest will check the values around the base address and - // the high address of a range to guard against off-by-one errors. - void RetrieveTest(TestMap* range_map, const RangeTest* range_test); - - // Test RetrieveRangeAtIndex, which is supposed to return objects in order - // according to their addresses. This test is performed by looping through - // the map, calling RetrieveRangeAtIndex for all possible indices in sequence, - // and verifying that each call returns a different object than the previous - // call, and that ranges are returned with increasing base addresses. Returns - // false if the test fails. - void RetrieveIndexTest(const TestMap* range_map, int set); - - void RunTestCase(int test_case); - - unsigned int kTestCasesCount_; - RangeMapSerializer serializer_; -}; - -void TestStaticRangeMap::StoreTest(RMap* range_map, - const RangeTest* range_test) { - bool stored = range_map->StoreRange(range_test->address, - range_test->size, - range_test->id); - EXPECT_EQ(stored, range_test->expect_storable) - << "StoreRange id " << range_test->id << "FAILED"; -} - -void TestStaticRangeMap::RetrieveTest(TestMap* range_map, - const RangeTest* range_test) { - for (unsigned int side = 0; side <= 1; ++side) { - // When side == 0, check the low side (base address) of each range. - // When side == 1, check the high side (base + size) of each range. - - // Check one-less and one-greater than the target address in addition - // to the target address itself. - - // If the size of the range is only 1, don't check one greater than - // the base or one less than the high - for a successfully stored - // range, these tests would erroneously fail because the range is too - // small. - AddressType low_offset = -1; - AddressType high_offset = 1; - if (range_test->size == 1) { - if (!side) // When checking the low side, - high_offset = 0; // don't check one over the target. - else // When checking the high side, - low_offset = 0; // don't check one under the target. - } - - for (AddressType offset = low_offset; offset <= high_offset; ++offset) { - AddressType address = - offset + - (!side ? range_test->address : - range_test->address + range_test->size - 1); - - bool expected_result = false; // This is correct for tests not stored. - if (range_test->expect_storable) { - if (offset == 0) // When checking the target address, - expected_result = true; // test should always succeed. - else if (offset == -1) // When checking one below the target, - expected_result = side; // should fail low and succeed high. - else // When checking one above the target, - expected_result = !side; // should succeed low and fail high. - } - - const EntryType* id; - AddressType retrieved_base; - AddressType retrieved_size; - bool retrieved = range_map->RetrieveRange(address, id, - &retrieved_base, - &retrieved_size); - - bool observed_result = retrieved && *id == range_test->id; - EXPECT_EQ(observed_result, expected_result) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - - // If a range was successfully retrieved, check that the returned - // bounds match the range as stored. - if (observed_result == true) { - EXPECT_EQ(retrieved_base, range_test->address) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - EXPECT_EQ(retrieved_size, range_test->size) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - } - - // Now, check RetrieveNearestRange. The nearest range is always - // expected to be different from the test range when checking one - // less than the low side. - bool expected_nearest = range_test->expect_storable; - if (!side && offset < 0) - expected_nearest = false; - - AddressType nearest_base; - AddressType nearest_size; - bool retrieved_nearest = range_map->RetrieveNearestRange(address, - id, - &nearest_base, - &nearest_size); - - // When checking one greater than the high side, RetrieveNearestRange - // should usually return the test range. When a different range begins - // at that address, though, then RetrieveNearestRange should return the - // range at the address instead of the test range. - if (side && offset > 0 && nearest_base == address) { - expected_nearest = false; - } - - bool observed_nearest = retrieved_nearest && - *id == range_test->id; - - EXPECT_EQ(observed_nearest, expected_nearest) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - - // If a range was successfully retrieved, check that the returned - // bounds match the range as stored. - if (expected_nearest ==true) { - EXPECT_EQ(nearest_base, range_test->address) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - EXPECT_EQ(nearest_size, range_test->size) - << "RetrieveRange id " << range_test->id - << ", side " << side << ", offset " << offset << " FAILED."; - } - } - } -} - -void TestStaticRangeMap::RetrieveIndexTest(const TestMap* range_map, int set) { - AddressType last_base = 0; - const EntryType* last_entry = 0; - const EntryType* entry; - int object_count = range_map->GetCount(); - for (int object_index = 0; object_index < object_count; ++object_index) { - AddressType base; - ASSERT_TRUE(range_map->RetrieveRangeAtIndex(object_index, - entry, - &base, - NULL)) - << "FAILED: RetrieveRangeAtIndex set " << set - << " index " << object_index; - - ASSERT_TRUE(entry) << "FAILED: RetrieveRangeAtIndex set " << set - << " index " << object_index; - - // It's impossible to do these comparisons unless there's a previous - // object to compare against. - if (last_entry) { - // The object must be different from the last_entry one. - EXPECT_NE(*entry, *last_entry) << "FAILED: RetrieveRangeAtIndex set " - << set << " index " << object_index; - // Each object must have a base greater than the previous object's base. - EXPECT_GT(base, last_base) << "FAILED: RetrieveRangeAtIndex set " << set - << " index " << object_index; - } - last_entry = entry; - last_base = base; - } - - // Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that - // are too high. - ASSERT_FALSE(range_map->RetrieveRangeAtIndex( - object_count, entry, NULL, NULL)) << "FAILED: RetrieveRangeAtIndex set " - << set << " index " << object_count - << " (too large)"; -} - -// RunTests runs a series of test sets. -void TestStaticRangeMap::RunTestCase(int test_case) { - // Maintain the range map in a pointer so that deletion can be meaningfully - // tested. - scoped_ptr rmap(new RMap()); - - const RangeTest* range_tests = range_test_sets[test_case].range_tests; - unsigned int range_test_count = range_test_sets[test_case].range_test_count; - - // Run the StoreRange test, which validates StoreRange and initializes - // the RangeMap with data for the RetrieveRange test. - int stored_count = 0; // The number of ranges successfully stored - for (unsigned int range_test_index = 0; - range_test_index < range_test_count; - ++range_test_index) { - const RangeTest* range_test = &range_tests[range_test_index]; - StoreTest(rmap.get(), range_test); - - if (range_test->expect_storable) - ++stored_count; - } - - scoped_array memaddr(serializer_.Serialize(*rmap, NULL)); - scoped_ptr static_range_map(new TestMap(memaddr.get())); - - // The RangeMap's own count of objects should also match. - EXPECT_EQ(static_range_map->GetCount(), stored_count); - - // Run the RetrieveRange test - for (unsigned int range_test_index = 0; - range_test_index < range_test_count; - ++range_test_index) { - const RangeTest* range_test = &range_tests[range_test_index]; - RetrieveTest(static_range_map.get(), range_test); - } - - RetrieveIndexTest(static_range_map.get(), test_case); -} - -TEST_F(TestStaticRangeMap, TestCase0) { - int test_case = 0; - RunTestCase(test_case); -} - -TEST_F(TestStaticRangeMap, TestCase1) { - int test_case = 1; - RunTestCase(test_case); -} - -TEST_F(TestStaticRangeMap, TestCase2) { - int test_case = 2; - RunTestCase(test_case); -} - -TEST_F(TestStaticRangeMap, TestCase3) { - int test_case = 3; - RunTestCase(test_case); -} - -TEST_F(TestStaticRangeMap, RunTestCase0Again) { - int test_case = 0; - RunTestCase(test_case); -} - -} // namespace google_breakpad - -int main(int argc, char *argv[]) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.cc b/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.cc deleted file mode 100644 index a6ee26a26..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.cc +++ /dev/null @@ -1,6418 +0,0 @@ -// Copyright (c) 2015 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ntstatus_reason_win.h: Windows NTSTATUS code to string. -// -// Provides a means to convert NTSTATUS codes to strings. -// -// Author: Ben Wagner - -#include - -#include "common/stdio_wrapper.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_exception_win32.h" -#include "processor/symbolic_constants_win.h" - -namespace google_breakpad { - -string NTStatusToString(uint32_t ntstatus) { - string reason; - // The content of this switch was created from ntstatus.h in the 8.1 SDK with - // - // egrep '#define [A-Z_0-9]+\s+\(\(NTSTATUS\)0xC[0-9A-F]+L\)' ntstatus.h - // | tr -d '\r' - // | sed -r 's@#define ([A-Z_0-9]+)\s+\(\(NTSTATUS\)(0xC[0-9A-F]+)L\).*@\2 \1@' - // | sort - // | sed -r 's@(0xC[0-9A-F]+) ([A-Z_0-9]+)@ case MD_NTSTATUS_WIN_\2:\n reason = "\2";\n break;@' - // - // With easy copy to clipboard with - // | xclip -selection c # on linux - // | clip # on windows - // | pbcopy # on mac - // - // and then the default case added. - switch (ntstatus) { - case MD_NTSTATUS_WIN_STATUS_UNSUCCESSFUL: - reason = "STATUS_UNSUCCESSFUL"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_IMPLEMENTED: - reason = "STATUS_NOT_IMPLEMENTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_INFO_CLASS: - reason = "STATUS_INVALID_INFO_CLASS"; - break; - case MD_NTSTATUS_WIN_STATUS_INFO_LENGTH_MISMATCH: - reason = "STATUS_INFO_LENGTH_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_VIOLATION: - reason = "STATUS_ACCESS_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_IN_PAGE_ERROR: - reason = "STATUS_IN_PAGE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_PAGEFILE_QUOTA: - reason = "STATUS_PAGEFILE_QUOTA"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_HANDLE: - reason = "STATUS_INVALID_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_INITIAL_STACK: - reason = "STATUS_BAD_INITIAL_STACK"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_INITIAL_PC: - reason = "STATUS_BAD_INITIAL_PC"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_CID: - reason = "STATUS_INVALID_CID"; - break; - case MD_NTSTATUS_WIN_STATUS_TIMER_NOT_CANCELED: - reason = "STATUS_TIMER_NOT_CANCELED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER: - reason = "STATUS_INVALID_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_DEVICE: - reason = "STATUS_NO_SUCH_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_FILE: - reason = "STATUS_NO_SUCH_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_REQUEST: - reason = "STATUS_INVALID_DEVICE_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_END_OF_FILE: - reason = "STATUS_END_OF_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_VOLUME: - reason = "STATUS_WRONG_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_MEDIA_IN_DEVICE: - reason = "STATUS_NO_MEDIA_IN_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_UNRECOGNIZED_MEDIA: - reason = "STATUS_UNRECOGNIZED_MEDIA"; - break; - case MD_NTSTATUS_WIN_STATUS_NONEXISTENT_SECTOR: - reason = "STATUS_NONEXISTENT_SECTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_MORE_PROCESSING_REQUIRED: - reason = "STATUS_MORE_PROCESSING_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_MEMORY: - reason = "STATUS_NO_MEMORY"; - break; - case MD_NTSTATUS_WIN_STATUS_CONFLICTING_ADDRESSES: - reason = "STATUS_CONFLICTING_ADDRESSES"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_MAPPED_VIEW: - reason = "STATUS_NOT_MAPPED_VIEW"; - break; - case MD_NTSTATUS_WIN_STATUS_UNABLE_TO_FREE_VM: - reason = "STATUS_UNABLE_TO_FREE_VM"; - break; - case MD_NTSTATUS_WIN_STATUS_UNABLE_TO_DELETE_SECTION: - reason = "STATUS_UNABLE_TO_DELETE_SECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SYSTEM_SERVICE: - reason = "STATUS_INVALID_SYSTEM_SERVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_INSTRUCTION: - reason = "STATUS_ILLEGAL_INSTRUCTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LOCK_SEQUENCE: - reason = "STATUS_INVALID_LOCK_SEQUENCE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_VIEW_SIZE: - reason = "STATUS_INVALID_VIEW_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_FILE_FOR_SECTION: - reason = "STATUS_INVALID_FILE_FOR_SECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_ALREADY_COMMITTED: - reason = "STATUS_ALREADY_COMMITTED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DENIED: - reason = "STATUS_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_BUFFER_TOO_SMALL: - reason = "STATUS_BUFFER_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_TYPE_MISMATCH: - reason = "STATUS_OBJECT_TYPE_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_NONCONTINUABLE_EXCEPTION: - reason = "STATUS_NONCONTINUABLE_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DISPOSITION: - reason = "STATUS_INVALID_DISPOSITION"; - break; - case MD_NTSTATUS_WIN_STATUS_UNWIND: - reason = "STATUS_UNWIND"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_STACK: - reason = "STATUS_BAD_STACK"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_UNWIND_TARGET: - reason = "STATUS_INVALID_UNWIND_TARGET"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_LOCKED: - reason = "STATUS_NOT_LOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_PARITY_ERROR: - reason = "STATUS_PARITY_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_UNABLE_TO_DECOMMIT_VM: - reason = "STATUS_UNABLE_TO_DECOMMIT_VM"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_COMMITTED: - reason = "STATUS_NOT_COMMITTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PORT_ATTRIBUTES: - reason = "STATUS_INVALID_PORT_ATTRIBUTES"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_MESSAGE_TOO_LONG: - reason = "STATUS_PORT_MESSAGE_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_MIX: - reason = "STATUS_INVALID_PARAMETER_MIX"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_QUOTA_LOWER: - reason = "STATUS_INVALID_QUOTA_LOWER"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_CORRUPT_ERROR: - reason = "STATUS_DISK_CORRUPT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_INVALID: - reason = "STATUS_OBJECT_NAME_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_NOT_FOUND: - reason = "STATUS_OBJECT_NAME_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_NAME_COLLISION: - reason = "STATUS_OBJECT_NAME_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_DISCONNECTED: - reason = "STATUS_PORT_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_ALREADY_ATTACHED: - reason = "STATUS_DEVICE_ALREADY_ATTACHED"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_INVALID: - reason = "STATUS_OBJECT_PATH_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_NOT_FOUND: - reason = "STATUS_OBJECT_PATH_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_PATH_SYNTAX_BAD: - reason = "STATUS_OBJECT_PATH_SYNTAX_BAD"; - break; - case MD_NTSTATUS_WIN_STATUS_DATA_OVERRUN: - reason = "STATUS_DATA_OVERRUN"; - break; - case MD_NTSTATUS_WIN_STATUS_DATA_LATE_ERROR: - reason = "STATUS_DATA_LATE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DATA_ERROR: - reason = "STATUS_DATA_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_CRC_ERROR: - reason = "STATUS_CRC_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SECTION_TOO_BIG: - reason = "STATUS_SECTION_TOO_BIG"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_CONNECTION_REFUSED: - reason = "STATUS_PORT_CONNECTION_REFUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PORT_HANDLE: - reason = "STATUS_INVALID_PORT_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_SHARING_VIOLATION: - reason = "STATUS_SHARING_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_QUOTA_EXCEEDED: - reason = "STATUS_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PAGE_PROTECTION: - reason = "STATUS_INVALID_PAGE_PROTECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_MUTANT_NOT_OWNED: - reason = "STATUS_MUTANT_NOT_OWNED"; - break; - case MD_NTSTATUS_WIN_STATUS_SEMAPHORE_LIMIT_EXCEEDED: - reason = "STATUS_SEMAPHORE_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_ALREADY_SET: - reason = "STATUS_PORT_ALREADY_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_SECTION_NOT_IMAGE: - reason = "STATUS_SECTION_NOT_IMAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_SUSPEND_COUNT_EXCEEDED: - reason = "STATUS_SUSPEND_COUNT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_THREAD_IS_TERMINATING: - reason = "STATUS_THREAD_IS_TERMINATING"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_WORKING_SET_LIMIT: - reason = "STATUS_BAD_WORKING_SET_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_FILE_MAP: - reason = "STATUS_INCOMPATIBLE_FILE_MAP"; - break; - case MD_NTSTATUS_WIN_STATUS_SECTION_PROTECTION: - reason = "STATUS_SECTION_PROTECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_EAS_NOT_SUPPORTED: - reason = "STATUS_EAS_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_EA_TOO_LARGE: - reason = "STATUS_EA_TOO_LARGE"; - break; - case MD_NTSTATUS_WIN_STATUS_NONEXISTENT_EA_ENTRY: - reason = "STATUS_NONEXISTENT_EA_ENTRY"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_EAS_ON_FILE: - reason = "STATUS_NO_EAS_ON_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_EA_CORRUPT_ERROR: - reason = "STATUS_EA_CORRUPT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_LOCK_CONFLICT: - reason = "STATUS_FILE_LOCK_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOCK_NOT_GRANTED: - reason = "STATUS_LOCK_NOT_GRANTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DELETE_PENDING: - reason = "STATUS_DELETE_PENDING"; - break; - case MD_NTSTATUS_WIN_STATUS_CTL_FILE_NOT_SUPPORTED: - reason = "STATUS_CTL_FILE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_UNKNOWN_REVISION: - reason = "STATUS_UNKNOWN_REVISION"; - break; - case MD_NTSTATUS_WIN_STATUS_REVISION_MISMATCH: - reason = "STATUS_REVISION_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_OWNER: - reason = "STATUS_INVALID_OWNER"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PRIMARY_GROUP: - reason = "STATUS_INVALID_PRIMARY_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_IMPERSONATION_TOKEN: - reason = "STATUS_NO_IMPERSONATION_TOKEN"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_DISABLE_MANDATORY: - reason = "STATUS_CANT_DISABLE_MANDATORY"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_LOGON_SERVERS: - reason = "STATUS_NO_LOGON_SERVERS"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_LOGON_SESSION: - reason = "STATUS_NO_SUCH_LOGON_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_PRIVILEGE: - reason = "STATUS_NO_SUCH_PRIVILEGE"; - break; - case MD_NTSTATUS_WIN_STATUS_PRIVILEGE_NOT_HELD: - reason = "STATUS_PRIVILEGE_NOT_HELD"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ACCOUNT_NAME: - reason = "STATUS_INVALID_ACCOUNT_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_USER_EXISTS: - reason = "STATUS_USER_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_USER: - reason = "STATUS_NO_SUCH_USER"; - break; - case MD_NTSTATUS_WIN_STATUS_GROUP_EXISTS: - reason = "STATUS_GROUP_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_GROUP: - reason = "STATUS_NO_SUCH_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMBER_IN_GROUP: - reason = "STATUS_MEMBER_IN_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMBER_NOT_IN_GROUP: - reason = "STATUS_MEMBER_NOT_IN_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_LAST_ADMIN: - reason = "STATUS_LAST_ADMIN"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_PASSWORD: - reason = "STATUS_WRONG_PASSWORD"; - break; - case MD_NTSTATUS_WIN_STATUS_ILL_FORMED_PASSWORD: - reason = "STATUS_ILL_FORMED_PASSWORD"; - break; - case MD_NTSTATUS_WIN_STATUS_PASSWORD_RESTRICTION: - reason = "STATUS_PASSWORD_RESTRICTION"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_FAILURE: - reason = "STATUS_LOGON_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCOUNT_RESTRICTION: - reason = "STATUS_ACCOUNT_RESTRICTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LOGON_HOURS: - reason = "STATUS_INVALID_LOGON_HOURS"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_WORKSTATION: - reason = "STATUS_INVALID_WORKSTATION"; - break; - case MD_NTSTATUS_WIN_STATUS_PASSWORD_EXPIRED: - reason = "STATUS_PASSWORD_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCOUNT_DISABLED: - reason = "STATUS_ACCOUNT_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_NONE_MAPPED: - reason = "STATUS_NONE_MAPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_LUIDS_REQUESTED: - reason = "STATUS_TOO_MANY_LUIDS_REQUESTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LUIDS_EXHAUSTED: - reason = "STATUS_LUIDS_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SUB_AUTHORITY: - reason = "STATUS_INVALID_SUB_AUTHORITY"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ACL: - reason = "STATUS_INVALID_ACL"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SID: - reason = "STATUS_INVALID_SID"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SECURITY_DESCR: - reason = "STATUS_INVALID_SECURITY_DESCR"; - break; - case MD_NTSTATUS_WIN_STATUS_PROCEDURE_NOT_FOUND: - reason = "STATUS_PROCEDURE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_FORMAT: - reason = "STATUS_INVALID_IMAGE_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_TOKEN: - reason = "STATUS_NO_TOKEN"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_INHERITANCE_ACL: - reason = "STATUS_BAD_INHERITANCE_ACL"; - break; - case MD_NTSTATUS_WIN_STATUS_RANGE_NOT_LOCKED: - reason = "STATUS_RANGE_NOT_LOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_FULL: - reason = "STATUS_DISK_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_SERVER_DISABLED: - reason = "STATUS_SERVER_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_SERVER_NOT_DISABLED: - reason = "STATUS_SERVER_NOT_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_GUIDS_REQUESTED: - reason = "STATUS_TOO_MANY_GUIDS_REQUESTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GUIDS_EXHAUSTED: - reason = "STATUS_GUIDS_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ID_AUTHORITY: - reason = "STATUS_INVALID_ID_AUTHORITY"; - break; - case MD_NTSTATUS_WIN_STATUS_AGENTS_EXHAUSTED: - reason = "STATUS_AGENTS_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_VOLUME_LABEL: - reason = "STATUS_INVALID_VOLUME_LABEL"; - break; - case MD_NTSTATUS_WIN_STATUS_SECTION_NOT_EXTENDED: - reason = "STATUS_SECTION_NOT_EXTENDED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_MAPPED_DATA: - reason = "STATUS_NOT_MAPPED_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_DATA_NOT_FOUND: - reason = "STATUS_RESOURCE_DATA_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_TYPE_NOT_FOUND: - reason = "STATUS_RESOURCE_TYPE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_NAME_NOT_FOUND: - reason = "STATUS_RESOURCE_NAME_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_ARRAY_BOUNDS_EXCEEDED: - reason = "STATUS_ARRAY_BOUNDS_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_DENORMAL_OPERAND: - reason = "STATUS_FLOAT_DENORMAL_OPERAND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_DIVIDE_BY_ZERO: - reason = "STATUS_FLOAT_DIVIDE_BY_ZERO"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_INEXACT_RESULT: - reason = "STATUS_FLOAT_INEXACT_RESULT"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_INVALID_OPERATION: - reason = "STATUS_FLOAT_INVALID_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_OVERFLOW: - reason = "STATUS_FLOAT_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_STACK_CHECK: - reason = "STATUS_FLOAT_STACK_CHECK"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_UNDERFLOW: - reason = "STATUS_FLOAT_UNDERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_INTEGER_DIVIDE_BY_ZERO: - reason = "STATUS_INTEGER_DIVIDE_BY_ZERO"; - break; - case MD_NTSTATUS_WIN_STATUS_INTEGER_OVERFLOW: - reason = "STATUS_INTEGER_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_PRIVILEGED_INSTRUCTION: - reason = "STATUS_PRIVILEGED_INSTRUCTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_PAGING_FILES: - reason = "STATUS_TOO_MANY_PAGING_FILES"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_INVALID: - reason = "STATUS_FILE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_ALLOTTED_SPACE_EXCEEDED: - reason = "STATUS_ALLOTTED_SPACE_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_RESOURCES: - reason = "STATUS_INSUFFICIENT_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_DFS_EXIT_PATH_FOUND: - reason = "STATUS_DFS_EXIT_PATH_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_DATA_ERROR: - reason = "STATUS_DEVICE_DATA_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_CONNECTED: - reason = "STATUS_DEVICE_NOT_CONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_POWER_FAILURE: - reason = "STATUS_DEVICE_POWER_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_FREE_VM_NOT_AT_BASE: - reason = "STATUS_FREE_VM_NOT_AT_BASE"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMORY_NOT_ALLOCATED: - reason = "STATUS_MEMORY_NOT_ALLOCATED"; - break; - case MD_NTSTATUS_WIN_STATUS_WORKING_SET_QUOTA: - reason = "STATUS_WORKING_SET_QUOTA"; - break; - case MD_NTSTATUS_WIN_STATUS_MEDIA_WRITE_PROTECTED: - reason = "STATUS_MEDIA_WRITE_PROTECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_READY: - reason = "STATUS_DEVICE_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_GROUP_ATTRIBUTES: - reason = "STATUS_INVALID_GROUP_ATTRIBUTES"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_IMPERSONATION_LEVEL: - reason = "STATUS_BAD_IMPERSONATION_LEVEL"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_OPEN_ANONYMOUS: - reason = "STATUS_CANT_OPEN_ANONYMOUS"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_VALIDATION_CLASS: - reason = "STATUS_BAD_VALIDATION_CLASS"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_TOKEN_TYPE: - reason = "STATUS_BAD_TOKEN_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_MASTER_BOOT_RECORD: - reason = "STATUS_BAD_MASTER_BOOT_RECORD"; - break; - case MD_NTSTATUS_WIN_STATUS_INSTRUCTION_MISALIGNMENT: - reason = "STATUS_INSTRUCTION_MISALIGNMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_INSTANCE_NOT_AVAILABLE: - reason = "STATUS_INSTANCE_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_NOT_AVAILABLE: - reason = "STATUS_PIPE_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PIPE_STATE: - reason = "STATUS_INVALID_PIPE_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_BUSY: - reason = "STATUS_PIPE_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_FUNCTION: - reason = "STATUS_ILLEGAL_FUNCTION"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_DISCONNECTED: - reason = "STATUS_PIPE_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_CLOSING: - reason = "STATUS_PIPE_CLOSING"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_CONNECTED: - reason = "STATUS_PIPE_CONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_LISTENING: - reason = "STATUS_PIPE_LISTENING"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_READ_MODE: - reason = "STATUS_INVALID_READ_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_TIMEOUT: - reason = "STATUS_IO_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_FORCED_CLOSED: - reason = "STATUS_FILE_FORCED_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_PROFILING_NOT_STARTED: - reason = "STATUS_PROFILING_NOT_STARTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PROFILING_NOT_STOPPED: - reason = "STATUS_PROFILING_NOT_STOPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_COULD_NOT_INTERPRET: - reason = "STATUS_COULD_NOT_INTERPRET"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_IS_A_DIRECTORY: - reason = "STATUS_FILE_IS_A_DIRECTORY"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED: - reason = "STATUS_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_NOT_LISTENING: - reason = "STATUS_REMOTE_NOT_LISTENING"; - break; - case MD_NTSTATUS_WIN_STATUS_DUPLICATE_NAME: - reason = "STATUS_DUPLICATE_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_NETWORK_PATH: - reason = "STATUS_BAD_NETWORK_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_BUSY: - reason = "STATUS_NETWORK_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_DOES_NOT_EXIST: - reason = "STATUS_DEVICE_DOES_NOT_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_COMMANDS: - reason = "STATUS_TOO_MANY_COMMANDS"; - break; - case MD_NTSTATUS_WIN_STATUS_ADAPTER_HARDWARE_ERROR: - reason = "STATUS_ADAPTER_HARDWARE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_NETWORK_RESPONSE: - reason = "STATUS_INVALID_NETWORK_RESPONSE"; - break; - case MD_NTSTATUS_WIN_STATUS_UNEXPECTED_NETWORK_ERROR: - reason = "STATUS_UNEXPECTED_NETWORK_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_REMOTE_ADAPTER: - reason = "STATUS_BAD_REMOTE_ADAPTER"; - break; - case MD_NTSTATUS_WIN_STATUS_PRINT_QUEUE_FULL: - reason = "STATUS_PRINT_QUEUE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SPOOL_SPACE: - reason = "STATUS_NO_SPOOL_SPACE"; - break; - case MD_NTSTATUS_WIN_STATUS_PRINT_CANCELLED: - reason = "STATUS_PRINT_CANCELLED"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_NAME_DELETED: - reason = "STATUS_NETWORK_NAME_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_ACCESS_DENIED: - reason = "STATUS_NETWORK_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_DEVICE_TYPE: - reason = "STATUS_BAD_DEVICE_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_NETWORK_NAME: - reason = "STATUS_BAD_NETWORK_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_NAMES: - reason = "STATUS_TOO_MANY_NAMES"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_SESSIONS: - reason = "STATUS_TOO_MANY_SESSIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_SHARING_PAUSED: - reason = "STATUS_SHARING_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_REQUEST_NOT_ACCEPTED: - reason = "STATUS_REQUEST_NOT_ACCEPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_REDIRECTOR_PAUSED: - reason = "STATUS_REDIRECTOR_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_NET_WRITE_FAULT: - reason = "STATUS_NET_WRITE_FAULT"; - break; - case MD_NTSTATUS_WIN_STATUS_PROFILING_AT_LIMIT: - reason = "STATUS_PROFILING_AT_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SAME_DEVICE: - reason = "STATUS_NOT_SAME_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_RENAMED: - reason = "STATUS_FILE_RENAMED"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTUAL_CIRCUIT_CLOSED: - reason = "STATUS_VIRTUAL_CIRCUIT_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SECURITY_ON_OBJECT: - reason = "STATUS_NO_SECURITY_ON_OBJECT"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_WAIT: - reason = "STATUS_CANT_WAIT"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_EMPTY: - reason = "STATUS_PIPE_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_ACCESS_DOMAIN_INFO: - reason = "STATUS_CANT_ACCESS_DOMAIN_INFO"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_TERMINATE_SELF: - reason = "STATUS_CANT_TERMINATE_SELF"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SERVER_STATE: - reason = "STATUS_INVALID_SERVER_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DOMAIN_STATE: - reason = "STATUS_INVALID_DOMAIN_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DOMAIN_ROLE: - reason = "STATUS_INVALID_DOMAIN_ROLE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_DOMAIN: - reason = "STATUS_NO_SUCH_DOMAIN"; - break; - case MD_NTSTATUS_WIN_STATUS_DOMAIN_EXISTS: - reason = "STATUS_DOMAIN_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_DOMAIN_LIMIT_EXCEEDED: - reason = "STATUS_DOMAIN_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_OPLOCK_NOT_GRANTED: - reason = "STATUS_OPLOCK_NOT_GRANTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_OPLOCK_PROTOCOL: - reason = "STATUS_INVALID_OPLOCK_PROTOCOL"; - break; - case MD_NTSTATUS_WIN_STATUS_INTERNAL_DB_CORRUPTION: - reason = "STATUS_INTERNAL_DB_CORRUPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INTERNAL_ERROR: - reason = "STATUS_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_GENERIC_NOT_MAPPED: - reason = "STATUS_GENERIC_NOT_MAPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_DESCRIPTOR_FORMAT: - reason = "STATUS_BAD_DESCRIPTOR_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_USER_BUFFER: - reason = "STATUS_INVALID_USER_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_UNEXPECTED_IO_ERROR: - reason = "STATUS_UNEXPECTED_IO_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_CREATE_ERR: - reason = "STATUS_UNEXPECTED_MM_CREATE_ERR"; - break; - case MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_MAP_ERROR: - reason = "STATUS_UNEXPECTED_MM_MAP_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_UNEXPECTED_MM_EXTEND_ERR: - reason = "STATUS_UNEXPECTED_MM_EXTEND_ERR"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_LOGON_PROCESS: - reason = "STATUS_NOT_LOGON_PROCESS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_SESSION_EXISTS: - reason = "STATUS_LOGON_SESSION_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_1: - reason = "STATUS_INVALID_PARAMETER_1"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_2: - reason = "STATUS_INVALID_PARAMETER_2"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_3: - reason = "STATUS_INVALID_PARAMETER_3"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_4: - reason = "STATUS_INVALID_PARAMETER_4"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_5: - reason = "STATUS_INVALID_PARAMETER_5"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_6: - reason = "STATUS_INVALID_PARAMETER_6"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_7: - reason = "STATUS_INVALID_PARAMETER_7"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_8: - reason = "STATUS_INVALID_PARAMETER_8"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_9: - reason = "STATUS_INVALID_PARAMETER_9"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_10: - reason = "STATUS_INVALID_PARAMETER_10"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_11: - reason = "STATUS_INVALID_PARAMETER_11"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PARAMETER_12: - reason = "STATUS_INVALID_PARAMETER_12"; - break; - case MD_NTSTATUS_WIN_STATUS_REDIRECTOR_NOT_STARTED: - reason = "STATUS_REDIRECTOR_NOT_STARTED"; - break; - case MD_NTSTATUS_WIN_STATUS_REDIRECTOR_STARTED: - reason = "STATUS_REDIRECTOR_STARTED"; - break; - case MD_NTSTATUS_WIN_STATUS_STACK_OVERFLOW: - reason = "STATUS_STACK_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_PACKAGE: - reason = "STATUS_NO_SUCH_PACKAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_FUNCTION_TABLE: - reason = "STATUS_BAD_FUNCTION_TABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VARIABLE_NOT_FOUND: - reason = "STATUS_VARIABLE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_EMPTY: - reason = "STATUS_DIRECTORY_NOT_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_CORRUPT_ERROR: - reason = "STATUS_FILE_CORRUPT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_A_DIRECTORY: - reason = "STATUS_NOT_A_DIRECTORY"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_LOGON_SESSION_STATE: - reason = "STATUS_BAD_LOGON_SESSION_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_SESSION_COLLISION: - reason = "STATUS_LOGON_SESSION_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_NAME_TOO_LONG: - reason = "STATUS_NAME_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_FILES_OPEN: - reason = "STATUS_FILES_OPEN"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_IN_USE: - reason = "STATUS_CONNECTION_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_MESSAGE_NOT_FOUND: - reason = "STATUS_MESSAGE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_PROCESS_IS_TERMINATING: - reason = "STATUS_PROCESS_IS_TERMINATING"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LOGON_TYPE: - reason = "STATUS_INVALID_LOGON_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_GUID_TRANSLATION: - reason = "STATUS_NO_GUID_TRANSLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_IMPERSONATE: - reason = "STATUS_CANNOT_IMPERSONATE"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_ALREADY_LOADED: - reason = "STATUS_IMAGE_ALREADY_LOADED"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_NOT_PRESENT: - reason = "STATUS_ABIOS_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_LID_NOT_EXIST: - reason = "STATUS_ABIOS_LID_NOT_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_LID_ALREADY_OWNED: - reason = "STATUS_ABIOS_LID_ALREADY_OWNED"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_NOT_LID_OWNER: - reason = "STATUS_ABIOS_NOT_LID_OWNER"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_COMMAND: - reason = "STATUS_ABIOS_INVALID_COMMAND"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_LID: - reason = "STATUS_ABIOS_INVALID_LID"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE: - reason = "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_ABIOS_INVALID_SELECTOR: - reason = "STATUS_ABIOS_INVALID_SELECTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_LDT: - reason = "STATUS_NO_LDT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LDT_SIZE: - reason = "STATUS_INVALID_LDT_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LDT_OFFSET: - reason = "STATUS_INVALID_LDT_OFFSET"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LDT_DESCRIPTOR: - reason = "STATUS_INVALID_LDT_DESCRIPTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_NE_FORMAT: - reason = "STATUS_INVALID_IMAGE_NE_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_RXACT_INVALID_STATE: - reason = "STATUS_RXACT_INVALID_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_RXACT_COMMIT_FAILURE: - reason = "STATUS_RXACT_COMMIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_MAPPED_FILE_SIZE_ZERO: - reason = "STATUS_MAPPED_FILE_SIZE_ZERO"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_OPENED_FILES: - reason = "STATUS_TOO_MANY_OPENED_FILES"; - break; - case MD_NTSTATUS_WIN_STATUS_CANCELLED: - reason = "STATUS_CANCELLED"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_DELETE: - reason = "STATUS_CANNOT_DELETE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_COMPUTER_NAME: - reason = "STATUS_INVALID_COMPUTER_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_DELETED: - reason = "STATUS_FILE_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_SPECIAL_ACCOUNT: - reason = "STATUS_SPECIAL_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_SPECIAL_GROUP: - reason = "STATUS_SPECIAL_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_SPECIAL_USER: - reason = "STATUS_SPECIAL_USER"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMBERS_PRIMARY_GROUP: - reason = "STATUS_MEMBERS_PRIMARY_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_CLOSED: - reason = "STATUS_FILE_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_THREADS: - reason = "STATUS_TOO_MANY_THREADS"; - break; - case MD_NTSTATUS_WIN_STATUS_THREAD_NOT_IN_PROCESS: - reason = "STATUS_THREAD_NOT_IN_PROCESS"; - break; - case MD_NTSTATUS_WIN_STATUS_TOKEN_ALREADY_IN_USE: - reason = "STATUS_TOKEN_ALREADY_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_PAGEFILE_QUOTA_EXCEEDED: - reason = "STATUS_PAGEFILE_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_COMMITMENT_LIMIT: - reason = "STATUS_COMMITMENT_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_LE_FORMAT: - reason = "STATUS_INVALID_IMAGE_LE_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_NOT_MZ: - reason = "STATUS_INVALID_IMAGE_NOT_MZ"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_PROTECT: - reason = "STATUS_INVALID_IMAGE_PROTECT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_16: - reason = "STATUS_INVALID_IMAGE_WIN_16"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_SERVER_CONFLICT: - reason = "STATUS_LOGON_SERVER_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_TIME_DIFFERENCE_AT_DC: - reason = "STATUS_TIME_DIFFERENCE_AT_DC"; - break; - case MD_NTSTATUS_WIN_STATUS_SYNCHRONIZATION_REQUIRED: - reason = "STATUS_SYNCHRONIZATION_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_DLL_NOT_FOUND: - reason = "STATUS_DLL_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_OPEN_FAILED: - reason = "STATUS_OPEN_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_PRIVILEGE_FAILED: - reason = "STATUS_IO_PRIVILEGE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_ORDINAL_NOT_FOUND: - reason = "STATUS_ORDINAL_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_ENTRYPOINT_NOT_FOUND: - reason = "STATUS_ENTRYPOINT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CONTROL_C_EXIT: - reason = "STATUS_CONTROL_C_EXIT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOCAL_DISCONNECT: - reason = "STATUS_LOCAL_DISCONNECT"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_DISCONNECT: - reason = "STATUS_REMOTE_DISCONNECT"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_RESOURCES: - reason = "STATUS_REMOTE_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_LINK_FAILED: - reason = "STATUS_LINK_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LINK_TIMEOUT: - reason = "STATUS_LINK_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_CONNECTION: - reason = "STATUS_INVALID_CONNECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS: - reason = "STATUS_INVALID_ADDRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_DLL_INIT_FAILED: - reason = "STATUS_DLL_INIT_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_MISSING_SYSTEMFILE: - reason = "STATUS_MISSING_SYSTEMFILE"; - break; - case MD_NTSTATUS_WIN_STATUS_UNHANDLED_EXCEPTION: - reason = "STATUS_UNHANDLED_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_INIT_FAILURE: - reason = "STATUS_APP_INIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_PAGEFILE_CREATE_FAILED: - reason = "STATUS_PAGEFILE_CREATE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_PAGEFILE: - reason = "STATUS_NO_PAGEFILE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LEVEL: - reason = "STATUS_INVALID_LEVEL"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_PASSWORD_CORE: - reason = "STATUS_WRONG_PASSWORD_CORE"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_FLOAT_CONTEXT: - reason = "STATUS_ILLEGAL_FLOAT_CONTEXT"; - break; - case MD_NTSTATUS_WIN_STATUS_PIPE_BROKEN: - reason = "STATUS_PIPE_BROKEN"; - break; - case MD_NTSTATUS_WIN_STATUS_REGISTRY_CORRUPT: - reason = "STATUS_REGISTRY_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_REGISTRY_IO_FAILED: - reason = "STATUS_REGISTRY_IO_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_EVENT_PAIR: - reason = "STATUS_NO_EVENT_PAIR"; - break; - case MD_NTSTATUS_WIN_STATUS_UNRECOGNIZED_VOLUME: - reason = "STATUS_UNRECOGNIZED_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_SERIAL_NO_DEVICE_INITED: - reason = "STATUS_SERIAL_NO_DEVICE_INITED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_ALIAS: - reason = "STATUS_NO_SUCH_ALIAS"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMBER_NOT_IN_ALIAS: - reason = "STATUS_MEMBER_NOT_IN_ALIAS"; - break; - case MD_NTSTATUS_WIN_STATUS_MEMBER_IN_ALIAS: - reason = "STATUS_MEMBER_IN_ALIAS"; - break; - case MD_NTSTATUS_WIN_STATUS_ALIAS_EXISTS: - reason = "STATUS_ALIAS_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_NOT_GRANTED: - reason = "STATUS_LOGON_NOT_GRANTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_SECRETS: - reason = "STATUS_TOO_MANY_SECRETS"; - break; - case MD_NTSTATUS_WIN_STATUS_SECRET_TOO_LONG: - reason = "STATUS_SECRET_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_INTERNAL_DB_ERROR: - reason = "STATUS_INTERNAL_DB_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FULLSCREEN_MODE: - reason = "STATUS_FULLSCREEN_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_CONTEXT_IDS: - reason = "STATUS_TOO_MANY_CONTEXT_IDS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGON_TYPE_NOT_GRANTED: - reason = "STATUS_LOGON_TYPE_NOT_GRANTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_REGISTRY_FILE: - reason = "STATUS_NOT_REGISTRY_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_NT_CROSS_ENCRYPTION_REQUIRED: - reason = "STATUS_NT_CROSS_ENCRYPTION_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_DOMAIN_CTRLR_CONFIG_ERROR: - reason = "STATUS_DOMAIN_CTRLR_CONFIG_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FT_MISSING_MEMBER: - reason = "STATUS_FT_MISSING_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_ILL_FORMED_SERVICE_ENTRY: - reason = "STATUS_ILL_FORMED_SERVICE_ENTRY"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_CHARACTER: - reason = "STATUS_ILLEGAL_CHARACTER"; - break; - case MD_NTSTATUS_WIN_STATUS_UNMAPPABLE_CHARACTER: - reason = "STATUS_UNMAPPABLE_CHARACTER"; - break; - case MD_NTSTATUS_WIN_STATUS_UNDEFINED_CHARACTER: - reason = "STATUS_UNDEFINED_CHARACTER"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOPPY_VOLUME: - reason = "STATUS_FLOPPY_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOPPY_ID_MARK_NOT_FOUND: - reason = "STATUS_FLOPPY_ID_MARK_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOPPY_WRONG_CYLINDER: - reason = "STATUS_FLOPPY_WRONG_CYLINDER"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOPPY_UNKNOWN_ERROR: - reason = "STATUS_FLOPPY_UNKNOWN_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOPPY_BAD_REGISTERS: - reason = "STATUS_FLOPPY_BAD_REGISTERS"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_RECALIBRATE_FAILED: - reason = "STATUS_DISK_RECALIBRATE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_OPERATION_FAILED: - reason = "STATUS_DISK_OPERATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_RESET_FAILED: - reason = "STATUS_DISK_RESET_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_SHARED_IRQ_BUSY: - reason = "STATUS_SHARED_IRQ_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_FT_ORPHANING: - reason = "STATUS_FT_ORPHANING"; - break; - case MD_NTSTATUS_WIN_STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT: - reason = "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_PARTITION_FAILURE: - reason = "STATUS_PARTITION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_BLOCK_LENGTH: - reason = "STATUS_INVALID_BLOCK_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_NOT_PARTITIONED: - reason = "STATUS_DEVICE_NOT_PARTITIONED"; - break; - case MD_NTSTATUS_WIN_STATUS_UNABLE_TO_LOCK_MEDIA: - reason = "STATUS_UNABLE_TO_LOCK_MEDIA"; - break; - case MD_NTSTATUS_WIN_STATUS_UNABLE_TO_UNLOAD_MEDIA: - reason = "STATUS_UNABLE_TO_UNLOAD_MEDIA"; - break; - case MD_NTSTATUS_WIN_STATUS_EOM_OVERFLOW: - reason = "STATUS_EOM_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_MEDIA: - reason = "STATUS_NO_MEDIA"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SUCH_MEMBER: - reason = "STATUS_NO_SUCH_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_MEMBER: - reason = "STATUS_INVALID_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_KEY_DELETED: - reason = "STATUS_KEY_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_LOG_SPACE: - reason = "STATUS_NO_LOG_SPACE"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_SIDS: - reason = "STATUS_TOO_MANY_SIDS"; - break; - case MD_NTSTATUS_WIN_STATUS_LM_CROSS_ENCRYPTION_REQUIRED: - reason = "STATUS_LM_CROSS_ENCRYPTION_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_KEY_HAS_CHILDREN: - reason = "STATUS_KEY_HAS_CHILDREN"; - break; - case MD_NTSTATUS_WIN_STATUS_CHILD_MUST_BE_VOLATILE: - reason = "STATUS_CHILD_MUST_BE_VOLATILE"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_CONFIGURATION_ERROR: - reason = "STATUS_DEVICE_CONFIGURATION_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_INTERNAL_ERROR: - reason = "STATUS_DRIVER_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_STATE: - reason = "STATUS_INVALID_DEVICE_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_DEVICE_ERROR: - reason = "STATUS_IO_DEVICE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_PROTOCOL_ERROR: - reason = "STATUS_DEVICE_PROTOCOL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_BACKUP_CONTROLLER: - reason = "STATUS_BACKUP_CONTROLLER"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_FILE_FULL: - reason = "STATUS_LOG_FILE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_LATE: - reason = "STATUS_TOO_LATE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_TRUST_LSA_SECRET: - reason = "STATUS_NO_TRUST_LSA_SECRET"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_TRUST_SAM_ACCOUNT: - reason = "STATUS_NO_TRUST_SAM_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_TRUSTED_DOMAIN_FAILURE: - reason = "STATUS_TRUSTED_DOMAIN_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_TRUSTED_RELATIONSHIP_FAILURE: - reason = "STATUS_TRUSTED_RELATIONSHIP_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_EVENTLOG_FILE_CORRUPT: - reason = "STATUS_EVENTLOG_FILE_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_EVENTLOG_CANT_START: - reason = "STATUS_EVENTLOG_CANT_START"; - break; - case MD_NTSTATUS_WIN_STATUS_TRUST_FAILURE: - reason = "STATUS_TRUST_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_MUTANT_LIMIT_EXCEEDED: - reason = "STATUS_MUTANT_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_NETLOGON_NOT_STARTED: - reason = "STATUS_NETLOGON_NOT_STARTED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCOUNT_EXPIRED: - reason = "STATUS_ACCOUNT_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_POSSIBLE_DEADLOCK: - reason = "STATUS_POSSIBLE_DEADLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_CREDENTIAL_CONFLICT: - reason = "STATUS_NETWORK_CREDENTIAL_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_SESSION_LIMIT: - reason = "STATUS_REMOTE_SESSION_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_EVENTLOG_FILE_CHANGED: - reason = "STATUS_EVENTLOG_FILE_CHANGED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: - reason = "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT: - reason = "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT: - reason = "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_DOMAIN_TRUST_INCONSISTENT: - reason = "STATUS_DOMAIN_TRUST_INCONSISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_FS_DRIVER_REQUIRED: - reason = "STATUS_FS_DRIVER_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_ALREADY_LOADED_AS_DLL: - reason = "STATUS_IMAGE_ALREADY_LOADED_AS_DLL"; - break; - case MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING: - reason = "STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING"; - break; - case MD_NTSTATUS_WIN_STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME: - reason = "STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_SECURITY_STREAM_IS_INCONSISTENT: - reason = "STATUS_SECURITY_STREAM_IS_INCONSISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LOCK_RANGE: - reason = "STATUS_INVALID_LOCK_RANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ACE_CONDITION: - reason = "STATUS_INVALID_ACE_CONDITION"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT: - reason = "STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_NOTIFICATION_GUID_ALREADY_DEFINED: - reason = "STATUS_NOTIFICATION_GUID_ALREADY_DEFINED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_EXCEPTION_HANDLER: - reason = "STATUS_INVALID_EXCEPTION_HANDLER"; - break; - case MD_NTSTATUS_WIN_STATUS_DUPLICATE_PRIVILEGES: - reason = "STATUS_DUPLICATE_PRIVILEGES"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_ALLOWED_ON_SYSTEM_FILE: - reason = "STATUS_NOT_ALLOWED_ON_SYSTEM_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_REPAIR_NEEDED: - reason = "STATUS_REPAIR_NEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_QUOTA_NOT_ENABLED: - reason = "STATUS_QUOTA_NOT_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_APPLICATION_PACKAGE: - reason = "STATUS_NO_APPLICATION_PACKAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_OPEN_RESTRICTION: - reason = "STATUS_NETWORK_OPEN_RESTRICTION"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_USER_SESSION_KEY: - reason = "STATUS_NO_USER_SESSION_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_USER_SESSION_DELETED: - reason = "STATUS_USER_SESSION_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_LANG_NOT_FOUND: - reason = "STATUS_RESOURCE_LANG_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFF_SERVER_RESOURCES: - reason = "STATUS_INSUFF_SERVER_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_BUFFER_SIZE: - reason = "STATUS_INVALID_BUFFER_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS_COMPONENT: - reason = "STATUS_INVALID_ADDRESS_COMPONENT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_ADDRESS_WILDCARD: - reason = "STATUS_INVALID_ADDRESS_WILDCARD"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_ADDRESSES: - reason = "STATUS_TOO_MANY_ADDRESSES"; - break; - case MD_NTSTATUS_WIN_STATUS_ADDRESS_ALREADY_EXISTS: - reason = "STATUS_ADDRESS_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_ADDRESS_CLOSED: - reason = "STATUS_ADDRESS_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_DISCONNECTED: - reason = "STATUS_CONNECTION_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_RESET: - reason = "STATUS_CONNECTION_RESET"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_NODES: - reason = "STATUS_TOO_MANY_NODES"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_ABORTED: - reason = "STATUS_TRANSACTION_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_TIMED_OUT: - reason = "STATUS_TRANSACTION_TIMED_OUT"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_RELEASE: - reason = "STATUS_TRANSACTION_NO_RELEASE"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_MATCH: - reason = "STATUS_TRANSACTION_NO_MATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_RESPONDED: - reason = "STATUS_TRANSACTION_RESPONDED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_ID: - reason = "STATUS_TRANSACTION_INVALID_ID"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_TYPE: - reason = "STATUS_TRANSACTION_INVALID_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SERVER_SESSION: - reason = "STATUS_NOT_SERVER_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_CLIENT_SESSION: - reason = "STATUS_NOT_CLIENT_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_LOAD_REGISTRY_FILE: - reason = "STATUS_CANNOT_LOAD_REGISTRY_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_DEBUG_ATTACH_FAILED: - reason = "STATUS_DEBUG_ATTACH_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_PROCESS_TERMINATED: - reason = "STATUS_SYSTEM_PROCESS_TERMINATED"; - break; - case MD_NTSTATUS_WIN_STATUS_DATA_NOT_ACCEPTED: - reason = "STATUS_DATA_NOT_ACCEPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_BROWSER_SERVERS_FOUND: - reason = "STATUS_NO_BROWSER_SERVERS_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_VDM_HARD_ERROR: - reason = "STATUS_VDM_HARD_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_CANCEL_TIMEOUT: - reason = "STATUS_DRIVER_CANCEL_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_REPLY_MESSAGE_MISMATCH: - reason = "STATUS_REPLY_MESSAGE_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_MAPPED_ALIGNMENT: - reason = "STATUS_MAPPED_ALIGNMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_CHECKSUM_MISMATCH: - reason = "STATUS_IMAGE_CHECKSUM_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA: - reason = "STATUS_LOST_WRITEBEHIND_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_CLIENT_SERVER_PARAMETERS_INVALID: - reason = "STATUS_CLIENT_SERVER_PARAMETERS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_PASSWORD_MUST_CHANGE: - reason = "STATUS_PASSWORD_MUST_CHANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_FOUND: - reason = "STATUS_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_TINY_STREAM: - reason = "STATUS_NOT_TINY_STREAM"; - break; - case MD_NTSTATUS_WIN_STATUS_RECOVERY_FAILURE: - reason = "STATUS_RECOVERY_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_STACK_OVERFLOW_READ: - reason = "STATUS_STACK_OVERFLOW_READ"; - break; - case MD_NTSTATUS_WIN_STATUS_FAIL_CHECK: - reason = "STATUS_FAIL_CHECK"; - break; - case MD_NTSTATUS_WIN_STATUS_DUPLICATE_OBJECTID: - reason = "STATUS_DUPLICATE_OBJECTID"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECTID_EXISTS: - reason = "STATUS_OBJECTID_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_CONVERT_TO_LARGE: - reason = "STATUS_CONVERT_TO_LARGE"; - break; - case MD_NTSTATUS_WIN_STATUS_RETRY: - reason = "STATUS_RETRY"; - break; - case MD_NTSTATUS_WIN_STATUS_FOUND_OUT_OF_SCOPE: - reason = "STATUS_FOUND_OUT_OF_SCOPE"; - break; - case MD_NTSTATUS_WIN_STATUS_ALLOCATE_BUCKET: - reason = "STATUS_ALLOCATE_BUCKET"; - break; - case MD_NTSTATUS_WIN_STATUS_PROPSET_NOT_FOUND: - reason = "STATUS_PROPSET_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_MARSHALL_OVERFLOW: - reason = "STATUS_MARSHALL_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_VARIANT: - reason = "STATUS_INVALID_VARIANT"; - break; - case MD_NTSTATUS_WIN_STATUS_DOMAIN_CONTROLLER_NOT_FOUND: - reason = "STATUS_DOMAIN_CONTROLLER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCOUNT_LOCKED_OUT: - reason = "STATUS_ACCOUNT_LOCKED_OUT"; - break; - case MD_NTSTATUS_WIN_STATUS_HANDLE_NOT_CLOSABLE: - reason = "STATUS_HANDLE_NOT_CLOSABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_REFUSED: - reason = "STATUS_CONNECTION_REFUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRACEFUL_DISCONNECT: - reason = "STATUS_GRACEFUL_DISCONNECT"; - break; - case MD_NTSTATUS_WIN_STATUS_ADDRESS_ALREADY_ASSOCIATED: - reason = "STATUS_ADDRESS_ALREADY_ASSOCIATED"; - break; - case MD_NTSTATUS_WIN_STATUS_ADDRESS_NOT_ASSOCIATED: - reason = "STATUS_ADDRESS_NOT_ASSOCIATED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_INVALID: - reason = "STATUS_CONNECTION_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_ACTIVE: - reason = "STATUS_CONNECTION_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_UNREACHABLE: - reason = "STATUS_NETWORK_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_HOST_UNREACHABLE: - reason = "STATUS_HOST_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_PROTOCOL_UNREACHABLE: - reason = "STATUS_PROTOCOL_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_UNREACHABLE: - reason = "STATUS_PORT_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_REQUEST_ABORTED: - reason = "STATUS_REQUEST_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_ABORTED: - reason = "STATUS_CONNECTION_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_COMPRESSION_BUFFER: - reason = "STATUS_BAD_COMPRESSION_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_USER_MAPPED_FILE: - reason = "STATUS_USER_MAPPED_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_AUDIT_FAILED: - reason = "STATUS_AUDIT_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_TIMER_RESOLUTION_NOT_SET: - reason = "STATUS_TIMER_RESOLUTION_NOT_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_CONNECTION_COUNT_LIMIT: - reason = "STATUS_CONNECTION_COUNT_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGIN_TIME_RESTRICTION: - reason = "STATUS_LOGIN_TIME_RESTRICTION"; - break; - case MD_NTSTATUS_WIN_STATUS_LOGIN_WKSTA_RESTRICTION: - reason = "STATUS_LOGIN_WKSTA_RESTRICTION"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_MP_UP_MISMATCH: - reason = "STATUS_IMAGE_MP_UP_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_LOGON_INFO: - reason = "STATUS_INSUFFICIENT_LOGON_INFO"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_DLL_ENTRYPOINT: - reason = "STATUS_BAD_DLL_ENTRYPOINT"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_SERVICE_ENTRYPOINT: - reason = "STATUS_BAD_SERVICE_ENTRYPOINT"; - break; - case MD_NTSTATUS_WIN_STATUS_LPC_REPLY_LOST: - reason = "STATUS_LPC_REPLY_LOST"; - break; - case MD_NTSTATUS_WIN_STATUS_IP_ADDRESS_CONFLICT1: - reason = "STATUS_IP_ADDRESS_CONFLICT1"; - break; - case MD_NTSTATUS_WIN_STATUS_IP_ADDRESS_CONFLICT2: - reason = "STATUS_IP_ADDRESS_CONFLICT2"; - break; - case MD_NTSTATUS_WIN_STATUS_REGISTRY_QUOTA_LIMIT: - reason = "STATUS_REGISTRY_QUOTA_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_PATH_NOT_COVERED: - reason = "STATUS_PATH_NOT_COVERED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_CALLBACK_ACTIVE: - reason = "STATUS_NO_CALLBACK_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_LICENSE_QUOTA_EXCEEDED: - reason = "STATUS_LICENSE_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_PWD_TOO_SHORT: - reason = "STATUS_PWD_TOO_SHORT"; - break; - case MD_NTSTATUS_WIN_STATUS_PWD_TOO_RECENT: - reason = "STATUS_PWD_TOO_RECENT"; - break; - case MD_NTSTATUS_WIN_STATUS_PWD_HISTORY_CONFLICT: - reason = "STATUS_PWD_HISTORY_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_PLUGPLAY_NO_DEVICE: - reason = "STATUS_PLUGPLAY_NO_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_UNSUPPORTED_COMPRESSION: - reason = "STATUS_UNSUPPORTED_COMPRESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_HW_PROFILE: - reason = "STATUS_INVALID_HW_PROFILE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PLUGPLAY_DEVICE_PATH: - reason = "STATUS_INVALID_PLUGPLAY_DEVICE_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_ORDINAL_NOT_FOUND: - reason = "STATUS_DRIVER_ORDINAL_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND: - reason = "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_NOT_OWNED: - reason = "STATUS_RESOURCE_NOT_OWNED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_LINKS: - reason = "STATUS_TOO_MANY_LINKS"; - break; - case MD_NTSTATUS_WIN_STATUS_QUOTA_LIST_INCONSISTENT: - reason = "STATUS_QUOTA_LIST_INCONSISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_IS_OFFLINE: - reason = "STATUS_FILE_IS_OFFLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_EVALUATION_EXPIRATION: - reason = "STATUS_EVALUATION_EXPIRATION"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_DLL_RELOCATION: - reason = "STATUS_ILLEGAL_DLL_RELOCATION"; - break; - case MD_NTSTATUS_WIN_STATUS_LICENSE_VIOLATION: - reason = "STATUS_LICENSE_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_DLL_INIT_FAILED_LOGOFF: - reason = "STATUS_DLL_INIT_FAILED_LOGOFF"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_UNABLE_TO_LOAD: - reason = "STATUS_DRIVER_UNABLE_TO_LOAD"; - break; - case MD_NTSTATUS_WIN_STATUS_DFS_UNAVAILABLE: - reason = "STATUS_DFS_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLUME_DISMOUNTED: - reason = "STATUS_VOLUME_DISMOUNTED"; - break; - case MD_NTSTATUS_WIN_STATUS_WX86_INTERNAL_ERROR: - reason = "STATUS_WX86_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_WX86_FLOAT_STACK_CHECK: - reason = "STATUS_WX86_FLOAT_STACK_CHECK"; - break; - case MD_NTSTATUS_WIN_STATUS_VALIDATE_CONTINUE: - reason = "STATUS_VALIDATE_CONTINUE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_MATCH: - reason = "STATUS_NO_MATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_MORE_MATCHES: - reason = "STATUS_NO_MORE_MATCHES"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_A_REPARSE_POINT: - reason = "STATUS_NOT_A_REPARSE_POINT"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_INVALID: - reason = "STATUS_IO_REPARSE_TAG_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_MISMATCH: - reason = "STATUS_IO_REPARSE_TAG_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_REPARSE_DATA_INVALID: - reason = "STATUS_IO_REPARSE_DATA_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_REPARSE_TAG_NOT_HANDLED: - reason = "STATUS_IO_REPARSE_TAG_NOT_HANDLED"; - break; - case MD_NTSTATUS_WIN_STATUS_PWD_TOO_LONG: - reason = "STATUS_PWD_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_STOWED_EXCEPTION: - reason = "STATUS_STOWED_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_REPARSE_POINT_NOT_RESOLVED: - reason = "STATUS_REPARSE_POINT_NOT_RESOLVED"; - break; - case MD_NTSTATUS_WIN_STATUS_DIRECTORY_IS_A_REPARSE_POINT: - reason = "STATUS_DIRECTORY_IS_A_REPARSE_POINT"; - break; - case MD_NTSTATUS_WIN_STATUS_RANGE_LIST_CONFLICT: - reason = "STATUS_RANGE_LIST_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_SOURCE_ELEMENT_EMPTY: - reason = "STATUS_SOURCE_ELEMENT_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_DESTINATION_ELEMENT_FULL: - reason = "STATUS_DESTINATION_ELEMENT_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_ILLEGAL_ELEMENT_ADDRESS: - reason = "STATUS_ILLEGAL_ELEMENT_ADDRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_MAGAZINE_NOT_PRESENT: - reason = "STATUS_MAGAZINE_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_REINITIALIZATION_NEEDED: - reason = "STATUS_REINITIALIZATION_NEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_ENCRYPTION_FAILED: - reason = "STATUS_ENCRYPTION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_DECRYPTION_FAILED: - reason = "STATUS_DECRYPTION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_RANGE_NOT_FOUND: - reason = "STATUS_RANGE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_RECOVERY_POLICY: - reason = "STATUS_NO_RECOVERY_POLICY"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_EFS: - reason = "STATUS_NO_EFS"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_EFS: - reason = "STATUS_WRONG_EFS"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_USER_KEYS: - reason = "STATUS_NO_USER_KEYS"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_NOT_ENCRYPTED: - reason = "STATUS_FILE_NOT_ENCRYPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_EXPORT_FORMAT: - reason = "STATUS_NOT_EXPORT_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_ENCRYPTED: - reason = "STATUS_FILE_ENCRYPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_GUID_NOT_FOUND: - reason = "STATUS_WMI_GUID_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_INSTANCE_NOT_FOUND: - reason = "STATUS_WMI_INSTANCE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_ITEMID_NOT_FOUND: - reason = "STATUS_WMI_ITEMID_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_TRY_AGAIN: - reason = "STATUS_WMI_TRY_AGAIN"; - break; - case MD_NTSTATUS_WIN_STATUS_SHARED_POLICY: - reason = "STATUS_SHARED_POLICY"; - break; - case MD_NTSTATUS_WIN_STATUS_POLICY_OBJECT_NOT_FOUND: - reason = "STATUS_POLICY_OBJECT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_POLICY_ONLY_IN_DS: - reason = "STATUS_POLICY_ONLY_IN_DS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLUME_NOT_UPGRADED: - reason = "STATUS_VOLUME_NOT_UPGRADED"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_STORAGE_NOT_ACTIVE: - reason = "STATUS_REMOTE_STORAGE_NOT_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_STORAGE_MEDIA_ERROR: - reason = "STATUS_REMOTE_STORAGE_MEDIA_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_TRACKING_SERVICE: - reason = "STATUS_NO_TRACKING_SERVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_SERVER_SID_MISMATCH: - reason = "STATUS_SERVER_SID_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_ATTRIBUTE_OR_VALUE: - reason = "STATUS_DS_NO_ATTRIBUTE_OR_VALUE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_INVALID_ATTRIBUTE_SYNTAX: - reason = "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED: - reason = "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS: - reason = "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_BUSY: - reason = "STATUS_DS_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_UNAVAILABLE: - reason = "STATUS_DS_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_RIDS_ALLOCATED: - reason = "STATUS_DS_NO_RIDS_ALLOCATED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_MORE_RIDS: - reason = "STATUS_DS_NO_MORE_RIDS"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_INCORRECT_ROLE_OWNER: - reason = "STATUS_DS_INCORRECT_ROLE_OWNER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_RIDMGR_INIT_ERROR: - reason = "STATUS_DS_RIDMGR_INIT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_OBJ_CLASS_VIOLATION: - reason = "STATUS_DS_OBJ_CLASS_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CANT_ON_NON_LEAF: - reason = "STATUS_DS_CANT_ON_NON_LEAF"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CANT_ON_RDN: - reason = "STATUS_DS_CANT_ON_RDN"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CANT_MOD_OBJ_CLASS: - reason = "STATUS_DS_CANT_MOD_OBJ_CLASS"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CROSS_DOM_MOVE_FAILED: - reason = "STATUS_DS_CROSS_DOM_MOVE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GC_NOT_AVAILABLE: - reason = "STATUS_DS_GC_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_DIRECTORY_SERVICE_REQUIRED: - reason = "STATUS_DIRECTORY_SERVICE_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_REPARSE_ATTRIBUTE_CONFLICT: - reason = "STATUS_REPARSE_ATTRIBUTE_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_ENABLE_DENY_ONLY: - reason = "STATUS_CANT_ENABLE_DENY_ONLY"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_MULTIPLE_FAULTS: - reason = "STATUS_FLOAT_MULTIPLE_FAULTS"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOAT_MULTIPLE_TRAPS: - reason = "STATUS_FLOAT_MULTIPLE_TRAPS"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_REMOVED: - reason = "STATUS_DEVICE_REMOVED"; - break; - case MD_NTSTATUS_WIN_STATUS_JOURNAL_DELETE_IN_PROGRESS: - reason = "STATUS_JOURNAL_DELETE_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_JOURNAL_NOT_ACTIVE: - reason = "STATUS_JOURNAL_NOT_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_NOINTERFACE: - reason = "STATUS_NOINTERFACE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_RIDMGR_DISABLED: - reason = "STATUS_DS_RIDMGR_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_ADMIN_LIMIT_EXCEEDED: - reason = "STATUS_DS_ADMIN_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_FAILED_SLEEP: - reason = "STATUS_DRIVER_FAILED_SLEEP"; - break; - case MD_NTSTATUS_WIN_STATUS_MUTUAL_AUTHENTICATION_FAILED: - reason = "STATUS_MUTUAL_AUTHENTICATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_SYSTEM_FILE: - reason = "STATUS_CORRUPT_SYSTEM_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_DATATYPE_MISALIGNMENT_ERROR: - reason = "STATUS_DATATYPE_MISALIGNMENT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_READ_ONLY: - reason = "STATUS_WMI_READ_ONLY"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_SET_FAILURE: - reason = "STATUS_WMI_SET_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_COMMITMENT_MINIMUM: - reason = "STATUS_COMMITMENT_MINIMUM"; - break; - case MD_NTSTATUS_WIN_STATUS_REG_NAT_CONSUMPTION: - reason = "STATUS_REG_NAT_CONSUMPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSPORT_FULL: - reason = "STATUS_TRANSPORT_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_SAM_INIT_FAILURE: - reason = "STATUS_DS_SAM_INIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_ONLY_IF_CONNECTED: - reason = "STATUS_ONLY_IF_CONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_SENSITIVE_GROUP_VIOLATION: - reason = "STATUS_DS_SENSITIVE_GROUP_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_RESTART_ENUMERATION: - reason = "STATUS_PNP_RESTART_ENUMERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_JOURNAL_ENTRY_DELETED: - reason = "STATUS_JOURNAL_ENTRY_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CANT_MOD_PRIMARYGROUPID: - reason = "STATUS_DS_CANT_MOD_PRIMARYGROUPID"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_IMAGE_BAD_SIGNATURE: - reason = "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_REBOOT_REQUIRED: - reason = "STATUS_PNP_REBOOT_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_POWER_STATE_INVALID: - reason = "STATUS_POWER_STATE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_INVALID_GROUP_TYPE: - reason = "STATUS_DS_INVALID_GROUP_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: - reason = "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: - reason = "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: - reason = "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: - reason = "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: - reason = "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: - reason = "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: - reason = "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_HAVE_PRIMARY_MEMBERS: - reason = "STATUS_DS_HAVE_PRIMARY_MEMBERS"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_NOT_SUPPORTED: - reason = "STATUS_WMI_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_POWER: - reason = "STATUS_INSUFFICIENT_POWER"; - break; - case MD_NTSTATUS_WIN_STATUS_SAM_NEED_BOOTKEY_PASSWORD: - reason = "STATUS_SAM_NEED_BOOTKEY_PASSWORD"; - break; - case MD_NTSTATUS_WIN_STATUS_SAM_NEED_BOOTKEY_FLOPPY: - reason = "STATUS_SAM_NEED_BOOTKEY_FLOPPY"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_CANT_START: - reason = "STATUS_DS_CANT_START"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_INIT_FAILURE: - reason = "STATUS_DS_INIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_SAM_INIT_FAILURE: - reason = "STATUS_SAM_INIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GC_REQUIRED: - reason = "STATUS_DS_GC_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: - reason = "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS: - reason = "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: - reason = "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_MULTIPLE_FAULT_VIOLATION: - reason = "STATUS_MULTIPLE_FAULT_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_CURRENT_DOMAIN_NOT_ALLOWED: - reason = "STATUS_CURRENT_DOMAIN_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_MAKE: - reason = "STATUS_CANNOT_MAKE"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_SHUTDOWN: - reason = "STATUS_SYSTEM_SHUTDOWN"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_INIT_FAILURE_CONSOLE: - reason = "STATUS_DS_INIT_FAILURE_CONSOLE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_SAM_INIT_FAILURE_CONSOLE: - reason = "STATUS_DS_SAM_INIT_FAILURE_CONSOLE"; - break; - case MD_NTSTATUS_WIN_STATUS_UNFINISHED_CONTEXT_DELETED: - reason = "STATUS_UNFINISHED_CONTEXT_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_TGT_REPLY: - reason = "STATUS_NO_TGT_REPLY"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECTID_NOT_FOUND: - reason = "STATUS_OBJECTID_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_IP_ADDRESSES: - reason = "STATUS_NO_IP_ADDRESSES"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_CREDENTIAL_HANDLE: - reason = "STATUS_WRONG_CREDENTIAL_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CRYPTO_SYSTEM_INVALID: - reason = "STATUS_CRYPTO_SYSTEM_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_MAX_REFERRALS_EXCEEDED: - reason = "STATUS_MAX_REFERRALS_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_MUST_BE_KDC: - reason = "STATUS_MUST_BE_KDC"; - break; - case MD_NTSTATUS_WIN_STATUS_STRONG_CRYPTO_NOT_SUPPORTED: - reason = "STATUS_STRONG_CRYPTO_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_PRINCIPALS: - reason = "STATUS_TOO_MANY_PRINCIPALS"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_PA_DATA: - reason = "STATUS_NO_PA_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_PKINIT_NAME_MISMATCH: - reason = "STATUS_PKINIT_NAME_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_LOGON_REQUIRED: - reason = "STATUS_SMARTCARD_LOGON_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_KDC_INVALID_REQUEST: - reason = "STATUS_KDC_INVALID_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_KDC_UNABLE_TO_REFER: - reason = "STATUS_KDC_UNABLE_TO_REFER"; - break; - case MD_NTSTATUS_WIN_STATUS_KDC_UNKNOWN_ETYPE: - reason = "STATUS_KDC_UNKNOWN_ETYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_SHUTDOWN_IN_PROGRESS: - reason = "STATUS_SHUTDOWN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_SERVER_SHUTDOWN_IN_PROGRESS: - reason = "STATUS_SERVER_SHUTDOWN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED_ON_SBS: - reason = "STATUS_NOT_SUPPORTED_ON_SBS"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_GUID_DISCONNECTED: - reason = "STATUS_WMI_GUID_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_ALREADY_DISABLED: - reason = "STATUS_WMI_ALREADY_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_WMI_ALREADY_ENABLED: - reason = "STATUS_WMI_ALREADY_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_MFT_TOO_FRAGMENTED: - reason = "STATUS_MFT_TOO_FRAGMENTED"; - break; - case MD_NTSTATUS_WIN_STATUS_COPY_PROTECTION_FAILURE: - reason = "STATUS_COPY_PROTECTION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_AUTHENTICATION_FAILURE: - reason = "STATUS_CSS_AUTHENTICATION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_KEY_NOT_PRESENT: - reason = "STATUS_CSS_KEY_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_KEY_NOT_ESTABLISHED: - reason = "STATUS_CSS_KEY_NOT_ESTABLISHED"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_SCRAMBLED_SECTOR: - reason = "STATUS_CSS_SCRAMBLED_SECTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_REGION_MISMATCH: - reason = "STATUS_CSS_REGION_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_CSS_RESETS_EXHAUSTED: - reason = "STATUS_CSS_RESETS_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PASSWORD_CHANGE_REQUIRED: - reason = "STATUS_PASSWORD_CHANGE_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_PKINIT_FAILURE: - reason = "STATUS_PKINIT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_SUBSYSTEM_FAILURE: - reason = "STATUS_SMARTCARD_SUBSYSTEM_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_KERB_KEY: - reason = "STATUS_NO_KERB_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_HOST_DOWN: - reason = "STATUS_HOST_DOWN"; - break; - case MD_NTSTATUS_WIN_STATUS_UNSUPPORTED_PREAUTH: - reason = "STATUS_UNSUPPORTED_PREAUTH"; - break; - case MD_NTSTATUS_WIN_STATUS_EFS_ALG_BLOB_TOO_BIG: - reason = "STATUS_EFS_ALG_BLOB_TOO_BIG"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_NOT_SET: - reason = "STATUS_PORT_NOT_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_DEBUGGER_INACTIVE: - reason = "STATUS_DEBUGGER_INACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_VERSION_CHECK_FAILURE: - reason = "STATUS_DS_VERSION_CHECK_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_AUDITING_DISABLED: - reason = "STATUS_AUDITING_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_PRENT4_MACHINE_ACCOUNT: - reason = "STATUS_PRENT4_MACHINE_ACCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: - reason = "STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_32: - reason = "STATUS_INVALID_IMAGE_WIN_32"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_WIN_64: - reason = "STATUS_INVALID_IMAGE_WIN_64"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_BINDINGS: - reason = "STATUS_BAD_BINDINGS"; - break; - case MD_NTSTATUS_WIN_STATUS_NETWORK_SESSION_EXPIRED: - reason = "STATUS_NETWORK_SESSION_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_APPHELP_BLOCK: - reason = "STATUS_APPHELP_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_ALL_SIDS_FILTERED: - reason = "STATUS_ALL_SIDS_FILTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SAFE_MODE_DRIVER: - reason = "STATUS_NOT_SAFE_MODE_DRIVER"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT: - reason = "STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_PATH: - reason = "STATUS_ACCESS_DISABLED_BY_POLICY_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER: - reason = "STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER: - reason = "STATUS_ACCESS_DISABLED_BY_POLICY_OTHER"; - break; - case MD_NTSTATUS_WIN_STATUS_FAILED_DRIVER_ENTRY: - reason = "STATUS_FAILED_DRIVER_ENTRY"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_ENUMERATION_ERROR: - reason = "STATUS_DEVICE_ENUMERATION_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_MOUNT_POINT_NOT_RESOLVED: - reason = "STATUS_MOUNT_POINT_NOT_RESOLVED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_DEVICE_OBJECT_PARAMETER: - reason = "STATUS_INVALID_DEVICE_OBJECT_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_MCA_OCCURED: - reason = "STATUS_MCA_OCCURED"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_BLOCKED_CRITICAL: - reason = "STATUS_DRIVER_BLOCKED_CRITICAL"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_BLOCKED: - reason = "STATUS_DRIVER_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_DATABASE_ERROR: - reason = "STATUS_DRIVER_DATABASE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_HIVE_TOO_LARGE: - reason = "STATUS_SYSTEM_HIVE_TOO_LARGE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMPORT_OF_NON_DLL: - reason = "STATUS_INVALID_IMPORT_OF_NON_DLL"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SECRETS: - reason = "STATUS_NO_SECRETS"; - break; - case MD_NTSTATUS_WIN_STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY: - reason = "STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY"; - break; - case MD_NTSTATUS_WIN_STATUS_FAILED_STACK_SWITCH: - reason = "STATUS_FAILED_STACK_SWITCH"; - break; - case MD_NTSTATUS_WIN_STATUS_HEAP_CORRUPTION: - reason = "STATUS_HEAP_CORRUPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_WRONG_PIN: - reason = "STATUS_SMARTCARD_WRONG_PIN"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_CARD_BLOCKED: - reason = "STATUS_SMARTCARD_CARD_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED: - reason = "STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_CARD: - reason = "STATUS_SMARTCARD_NO_CARD"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_KEY_CONTAINER: - reason = "STATUS_SMARTCARD_NO_KEY_CONTAINER"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_CERTIFICATE: - reason = "STATUS_SMARTCARD_NO_CERTIFICATE"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_NO_KEYSET: - reason = "STATUS_SMARTCARD_NO_KEYSET"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_IO_ERROR: - reason = "STATUS_SMARTCARD_IO_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_DOWNGRADE_DETECTED: - reason = "STATUS_DOWNGRADE_DETECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_CERT_REVOKED: - reason = "STATUS_SMARTCARD_CERT_REVOKED"; - break; - case MD_NTSTATUS_WIN_STATUS_ISSUING_CA_UNTRUSTED: - reason = "STATUS_ISSUING_CA_UNTRUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_REVOCATION_OFFLINE_C: - reason = "STATUS_REVOCATION_OFFLINE_C"; - break; - case MD_NTSTATUS_WIN_STATUS_PKINIT_CLIENT_FAILURE: - reason = "STATUS_PKINIT_CLIENT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_CERT_EXPIRED: - reason = "STATUS_SMARTCARD_CERT_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_FAILED_PRIOR_UNLOAD: - reason = "STATUS_DRIVER_FAILED_PRIOR_UNLOAD"; - break; - case MD_NTSTATUS_WIN_STATUS_SMARTCARD_SILENT_CONTEXT: - reason = "STATUS_SMARTCARD_SILENT_CONTEXT"; - break; - case MD_NTSTATUS_WIN_STATUS_PER_USER_TRUST_QUOTA_EXCEEDED: - reason = "STATUS_PER_USER_TRUST_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED: - reason = "STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED: - reason = "STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_NAME_NOT_UNIQUE: - reason = "STATUS_DS_NAME_NOT_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_DUPLICATE_ID_FOUND: - reason = "STATUS_DS_DUPLICATE_ID_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_GROUP_CONVERSION_ERROR: - reason = "STATUS_DS_GROUP_CONVERSION_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLSNAP_PREPARE_HIBERNATE: - reason = "STATUS_VOLSNAP_PREPARE_HIBERNATE"; - break; - case MD_NTSTATUS_WIN_STATUS_USER2USER_REQUIRED: - reason = "STATUS_USER2USER_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_STACK_BUFFER_OVERRUN: - reason = "STATUS_STACK_BUFFER_OVERRUN"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_S4U_PROT_SUPPORT: - reason = "STATUS_NO_S4U_PROT_SUPPORT"; - break; - case MD_NTSTATUS_WIN_STATUS_CROSSREALM_DELEGATION_FAILURE: - reason = "STATUS_CROSSREALM_DELEGATION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_REVOCATION_OFFLINE_KDC: - reason = "STATUS_REVOCATION_OFFLINE_KDC"; - break; - case MD_NTSTATUS_WIN_STATUS_ISSUING_CA_UNTRUSTED_KDC: - reason = "STATUS_ISSUING_CA_UNTRUSTED_KDC"; - break; - case MD_NTSTATUS_WIN_STATUS_KDC_CERT_EXPIRED: - reason = "STATUS_KDC_CERT_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_KDC_CERT_REVOKED: - reason = "STATUS_KDC_CERT_REVOKED"; - break; - case MD_NTSTATUS_WIN_STATUS_PARAMETER_QUOTA_EXCEEDED: - reason = "STATUS_PARAMETER_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_HIBERNATION_FAILURE: - reason = "STATUS_HIBERNATION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_DELAY_LOAD_FAILED: - reason = "STATUS_DELAY_LOAD_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_AUTHENTICATION_FIREWALL_FAILED: - reason = "STATUS_AUTHENTICATION_FIREWALL_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VDM_DISALLOWED: - reason = "STATUS_VDM_DISALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_HUNG_DISPLAY_DRIVER_THREAD: - reason = "STATUS_HUNG_DISPLAY_DRIVER_THREAD"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE: - reason = "STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_CRUNTIME_PARAMETER: - reason = "STATUS_INVALID_CRUNTIME_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_NTLM_BLOCKED: - reason = "STATUS_NTLM_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_SRC_SID_EXISTS_IN_FOREST: - reason = "STATUS_DS_SRC_SID_EXISTS_IN_FOREST"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST: - reason = "STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST: - reason = "STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_USER_PRINCIPAL_NAME: - reason = "STATUS_INVALID_USER_PRINCIPAL_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_FATAL_USER_CALLBACK_EXCEPTION: - reason = "STATUS_FATAL_USER_CALLBACK_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_ASSERTION_FAILURE: - reason = "STATUS_ASSERTION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_VERIFIER_STOP: - reason = "STATUS_VERIFIER_STOP"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_POP_STACK: - reason = "STATUS_CALLBACK_POP_STACK"; - break; - case MD_NTSTATUS_WIN_STATUS_INCOMPATIBLE_DRIVER_BLOCKED: - reason = "STATUS_INCOMPATIBLE_DRIVER_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_HIVE_UNLOADED: - reason = "STATUS_HIVE_UNLOADED"; - break; - case MD_NTSTATUS_WIN_STATUS_COMPRESSION_DISABLED: - reason = "STATUS_COMPRESSION_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_SYSTEM_LIMITATION: - reason = "STATUS_FILE_SYSTEM_LIMITATION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IMAGE_HASH: - reason = "STATUS_INVALID_IMAGE_HASH"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_CAPABLE: - reason = "STATUS_NOT_CAPABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_REQUEST_OUT_OF_SEQUENCE: - reason = "STATUS_REQUEST_OUT_OF_SEQUENCE"; - break; - case MD_NTSTATUS_WIN_STATUS_IMPLEMENTATION_LIMIT: - reason = "STATUS_IMPLEMENTATION_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_ELEVATION_REQUIRED: - reason = "STATUS_ELEVATION_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SECURITY_CONTEXT: - reason = "STATUS_NO_SECURITY_CONTEXT"; - break; - case MD_NTSTATUS_WIN_STATUS_PKU2U_CERT_FAILURE: - reason = "STATUS_PKU2U_CERT_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_BEYOND_VDL: - reason = "STATUS_BEYOND_VDL"; - break; - case MD_NTSTATUS_WIN_STATUS_ENCOUNTERED_WRITE_IN_PROGRESS: - reason = "STATUS_ENCOUNTERED_WRITE_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_PTE_CHANGED: - reason = "STATUS_PTE_CHANGED"; - break; - case MD_NTSTATUS_WIN_STATUS_PURGE_FAILED: - reason = "STATUS_PURGE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_CRED_REQUIRES_CONFIRMATION: - reason = "STATUS_CRED_REQUIRES_CONFIRMATION"; - break; - case MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE: - reason = "STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE"; - break; - case MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER: - reason = "STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER"; - break; - case MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE: - reason = "STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE: - reason = "STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_CS_ENCRYPTION_FILE_NOT_CSE: - reason = "STATUS_CS_ENCRYPTION_FILE_NOT_CSE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_LABEL: - reason = "STATUS_INVALID_LABEL"; - break; - case MD_NTSTATUS_WIN_STATUS_DRIVER_PROCESS_TERMINATED: - reason = "STATUS_DRIVER_PROCESS_TERMINATED"; - break; - case MD_NTSTATUS_WIN_STATUS_AMBIGUOUS_SYSTEM_DEVICE: - reason = "STATUS_AMBIGUOUS_SYSTEM_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_DEVICE_NOT_FOUND: - reason = "STATUS_SYSTEM_DEVICE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RESTART_BOOT_APPLICATION: - reason = "STATUS_RESTART_BOOT_APPLICATION"; - break; - case MD_NTSTATUS_WIN_STATUS_INSUFFICIENT_NVRAM_RESOURCES: - reason = "STATUS_INSUFFICIENT_NVRAM_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SESSION: - reason = "STATUS_INVALID_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_THREAD_ALREADY_IN_SESSION: - reason = "STATUS_THREAD_ALREADY_IN_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_THREAD_NOT_IN_SESSION: - reason = "STATUS_THREAD_NOT_IN_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_WEIGHT: - reason = "STATUS_INVALID_WEIGHT"; - break; - case MD_NTSTATUS_WIN_STATUS_REQUEST_PAUSED: - reason = "STATUS_REQUEST_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_RANGES_PROCESSED: - reason = "STATUS_NO_RANGES_PROCESSED"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_RESOURCES_EXHAUSTED: - reason = "STATUS_DISK_RESOURCES_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NEEDS_REMEDIATION: - reason = "STATUS_NEEDS_REMEDIATION"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_FEATURE_NOT_SUPPORTED: - reason = "STATUS_DEVICE_FEATURE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_UNREACHABLE: - reason = "STATUS_DEVICE_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_TOKEN: - reason = "STATUS_INVALID_TOKEN"; - break; - case MD_NTSTATUS_WIN_STATUS_SERVER_UNAVAILABLE: - reason = "STATUS_SERVER_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_NOT_AVAILABLE: - reason = "STATUS_FILE_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_INSUFFICIENT_RESOURCES: - reason = "STATUS_DEVICE_INSUFFICIENT_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_PACKAGE_UPDATING: - reason = "STATUS_PACKAGE_UPDATING"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_READ_FROM_COPY: - reason = "STATUS_NOT_READ_FROM_COPY"; - break; - case MD_NTSTATUS_WIN_STATUS_FT_WRITE_FAILURE: - reason = "STATUS_FT_WRITE_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_FT_DI_SCAN_REQUIRED: - reason = "STATUS_FT_DI_SCAN_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_NOT_EXTERNALLY_BACKED: - reason = "STATUS_OBJECT_NOT_EXTERNALLY_BACKED"; - break; - case MD_NTSTATUS_WIN_STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN: - reason = "STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN"; - break; - case MD_NTSTATUS_WIN_STATUS_DATA_CHECKSUM_ERROR: - reason = "STATUS_DATA_CHECKSUM_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_INTERMIXED_KERNEL_EA_OPERATION: - reason = "STATUS_INTERMIXED_KERNEL_EA_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRIM_READ_ZERO_NOT_SUPPORTED: - reason = "STATUS_TRIM_READ_ZERO_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TOO_MANY_SEGMENT_DESCRIPTORS: - reason = "STATUS_TOO_MANY_SEGMENT_DESCRIPTORS"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_OFFSET_ALIGNMENT: - reason = "STATUS_INVALID_OFFSET_ALIGNMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_FIELD_IN_PARAMETER_LIST: - reason = "STATUS_INVALID_FIELD_IN_PARAMETER_LIST"; - break; - case MD_NTSTATUS_WIN_STATUS_OPERATION_IN_PROGRESS: - reason = "STATUS_OPERATION_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_INITIATOR_TARGET_PATH: - reason = "STATUS_INVALID_INITIATOR_TARGET_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_SCRUB_DATA_DISABLED: - reason = "STATUS_SCRUB_DATA_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_REDUNDANT_STORAGE: - reason = "STATUS_NOT_REDUNDANT_STORAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_RESIDENT_FILE_NOT_SUPPORTED: - reason = "STATUS_RESIDENT_FILE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_COMPRESSED_FILE_NOT_SUPPORTED: - reason = "STATUS_COMPRESSED_FILE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_SUPPORTED: - reason = "STATUS_DIRECTORY_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_OPERATION_TIMEOUT: - reason = "STATUS_IO_OPERATION_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_SYSTEM_NEEDS_REMEDIATION: - reason = "STATUS_SYSTEM_NEEDS_REMEDIATION"; - break; - case MD_NTSTATUS_WIN_STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN: - reason = "STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN"; - break; - case MD_NTSTATUS_WIN_STATUS_SHARE_UNAVAILABLE: - reason = "STATUS_SHARE_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_APISET_NOT_HOSTED: - reason = "STATUS_APISET_NOT_HOSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_APISET_NOT_PRESENT: - reason = "STATUS_APISET_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_DEVICE_HARDWARE_ERROR: - reason = "STATUS_DEVICE_HARDWARE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_TASK_NAME: - reason = "STATUS_INVALID_TASK_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_TASK_INDEX: - reason = "STATUS_INVALID_TASK_INDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_THREAD_ALREADY_IN_TASK: - reason = "STATUS_THREAD_ALREADY_IN_TASK"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_BYPASS: - reason = "STATUS_CALLBACK_BYPASS"; - break; - case MD_NTSTATUS_WIN_STATUS_UNDEFINED_SCOPE: - reason = "STATUS_UNDEFINED_SCOPE"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_CAP: - reason = "STATUS_INVALID_CAP"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_GUI_PROCESS: - reason = "STATUS_NOT_GUI_PROCESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FAIL_FAST_EXCEPTION: - reason = "STATUS_FAIL_FAST_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_IMAGE_CERT_REVOKED: - reason = "STATUS_IMAGE_CERT_REVOKED"; - break; - case MD_NTSTATUS_WIN_STATUS_DYNAMIC_CODE_BLOCKED: - reason = "STATUS_DYNAMIC_CODE_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_CLOSED: - reason = "STATUS_PORT_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_MESSAGE_LOST: - reason = "STATUS_MESSAGE_LOST"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_MESSAGE: - reason = "STATUS_INVALID_MESSAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_REQUEST_CANCELED: - reason = "STATUS_REQUEST_CANCELED"; - break; - case MD_NTSTATUS_WIN_STATUS_RECURSIVE_DISPATCH: - reason = "STATUS_RECURSIVE_DISPATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_LPC_RECEIVE_BUFFER_EXPECTED: - reason = "STATUS_LPC_RECEIVE_BUFFER_EXPECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LPC_INVALID_CONNECTION_USAGE: - reason = "STATUS_LPC_INVALID_CONNECTION_USAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_LPC_REQUESTS_NOT_ALLOWED: - reason = "STATUS_LPC_REQUESTS_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_IN_USE: - reason = "STATUS_RESOURCE_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_HARDWARE_MEMORY_ERROR: - reason = "STATUS_HARDWARE_MEMORY_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_HANDLE_EXCEPTION: - reason = "STATUS_THREADPOOL_HANDLE_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED: - reason = "STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED: - reason = "STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED: - reason = "STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED: - reason = "STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_THREADPOOL_RELEASED_DURING_OPERATION: - reason = "STATUS_THREADPOOL_RELEASED_DURING_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING: - reason = "STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING"; - break; - case MD_NTSTATUS_WIN_STATUS_APC_RETURNED_WHILE_IMPERSONATING: - reason = "STATUS_APC_RETURNED_WHILE_IMPERSONATING"; - break; - case MD_NTSTATUS_WIN_STATUS_PROCESS_IS_PROTECTED: - reason = "STATUS_PROCESS_IS_PROTECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_MCA_EXCEPTION: - reason = "STATUS_MCA_EXCEPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE: - reason = "STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_SYMLINK_CLASS_DISABLED: - reason = "STATUS_SYMLINK_CLASS_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_IDN_NORMALIZATION: - reason = "STATUS_INVALID_IDN_NORMALIZATION"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_UNICODE_TRANSLATION: - reason = "STATUS_NO_UNICODE_TRANSLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_ALREADY_REGISTERED: - reason = "STATUS_ALREADY_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONTEXT_MISMATCH: - reason = "STATUS_CONTEXT_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_PORT_ALREADY_HAS_COMPLETION_LIST: - reason = "STATUS_PORT_ALREADY_HAS_COMPLETION_LIST"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_THREAD_PRIORITY: - reason = "STATUS_CALLBACK_RETURNED_THREAD_PRIORITY"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_THREAD: - reason = "STATUS_INVALID_THREAD"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_TRANSACTION: - reason = "STATUS_CALLBACK_RETURNED_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_LDR_LOCK: - reason = "STATUS_CALLBACK_RETURNED_LDR_LOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_LANG: - reason = "STATUS_CALLBACK_RETURNED_LANG"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_PRI_BACK: - reason = "STATUS_CALLBACK_RETURNED_PRI_BACK"; - break; - case MD_NTSTATUS_WIN_STATUS_CALLBACK_RETURNED_THREAD_AFFINITY: - reason = "STATUS_CALLBACK_RETURNED_THREAD_AFFINITY"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_REPAIR_DISABLED: - reason = "STATUS_DISK_REPAIR_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_DOMAIN_RENAME_IN_PROGRESS: - reason = "STATUS_DS_DOMAIN_RENAME_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_QUOTA_EXCEEDED: - reason = "STATUS_DISK_QUOTA_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_CONTENT_BLOCKED: - reason = "STATUS_CONTENT_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_CLUSTERS: - reason = "STATUS_BAD_CLUSTERS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLUME_DIRTY: - reason = "STATUS_VOLUME_DIRTY"; - break; - case MD_NTSTATUS_WIN_STATUS_DISK_REPAIR_UNSUCCESSFUL: - reason = "STATUS_DISK_REPAIR_UNSUCCESSFUL"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_OVERFULL: - reason = "STATUS_CORRUPT_LOG_OVERFULL"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_CORRUPTED: - reason = "STATUS_CORRUPT_LOG_CORRUPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_UNAVAILABLE: - reason = "STATUS_CORRUPT_LOG_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_DELETED_FULL: - reason = "STATUS_CORRUPT_LOG_DELETED_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_CLEARED: - reason = "STATUS_CORRUPT_LOG_CLEARED"; - break; - case MD_NTSTATUS_WIN_STATUS_ORPHAN_NAME_EXHAUSTED: - reason = "STATUS_ORPHAN_NAME_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PROACTIVE_SCAN_IN_PROGRESS: - reason = "STATUS_PROACTIVE_SCAN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_ENCRYPTED_IO_NOT_POSSIBLE: - reason = "STATUS_ENCRYPTED_IO_NOT_POSSIBLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CORRUPT_LOG_UPLEVEL_RECORDS: - reason = "STATUS_CORRUPT_LOG_UPLEVEL_RECORDS"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_CHECKED_OUT: - reason = "STATUS_FILE_CHECKED_OUT"; - break; - case MD_NTSTATUS_WIN_STATUS_CHECKOUT_REQUIRED: - reason = "STATUS_CHECKOUT_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_FILE_TYPE: - reason = "STATUS_BAD_FILE_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_TOO_LARGE: - reason = "STATUS_FILE_TOO_LARGE"; - break; - case MD_NTSTATUS_WIN_STATUS_FORMS_AUTH_REQUIRED: - reason = "STATUS_FORMS_AUTH_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRUS_INFECTED: - reason = "STATUS_VIRUS_INFECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRUS_DELETED: - reason = "STATUS_VIRUS_DELETED"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_MCFG_TABLE: - reason = "STATUS_BAD_MCFG_TABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_BREAK_OPLOCK: - reason = "STATUS_CANNOT_BREAK_OPLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_KEY: - reason = "STATUS_BAD_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_BAD_DATA: - reason = "STATUS_BAD_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_KEY: - reason = "STATUS_NO_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_HANDLE_REVOKED: - reason = "STATUS_FILE_HANDLE_REVOKED"; - break; - case MD_NTSTATUS_WIN_STATUS_WOW_ASSERTION: - reason = "STATUS_WOW_ASSERTION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_SIGNATURE: - reason = "STATUS_INVALID_SIGNATURE"; - break; - case MD_NTSTATUS_WIN_STATUS_HMAC_NOT_SUPPORTED: - reason = "STATUS_HMAC_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_AUTH_TAG_MISMATCH: - reason = "STATUS_AUTH_TAG_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_STATE_TRANSITION: - reason = "STATUS_INVALID_STATE_TRANSITION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_KERNEL_INFO_VERSION: - reason = "STATUS_INVALID_KERNEL_INFO_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PEP_INFO_VERSION: - reason = "STATUS_INVALID_PEP_INFO_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_QUEUE_OVERFLOW: - reason = "STATUS_IPSEC_QUEUE_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_ND_QUEUE_OVERFLOW: - reason = "STATUS_ND_QUEUE_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_HOPLIMIT_EXCEEDED: - reason = "STATUS_HOPLIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_PROTOCOL_NOT_SUPPORTED: - reason = "STATUS_PROTOCOL_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FASTPATH_REJECTED: - reason = "STATUS_FASTPATH_REJECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED: - reason = "STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR: - reason = "STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR: - reason = "STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_XML_PARSE_ERROR: - reason = "STATUS_XML_PARSE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_XMLDSIG_ERROR: - reason = "STATUS_XMLDSIG_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_WRONG_COMPARTMENT: - reason = "STATUS_WRONG_COMPARTMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_AUTHIP_FAILURE: - reason = "STATUS_AUTHIP_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS: - reason = "STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS"; - break; - case MD_NTSTATUS_WIN_STATUS_DS_OID_NOT_FOUND: - reason = "STATUS_DS_OID_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_INCORRECT_ACCOUNT_TYPE: - reason = "STATUS_INCORRECT_ACCOUNT_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_HASH_NOT_SUPPORTED: - reason = "STATUS_HASH_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_HASH_NOT_PRESENT: - reason = "STATUS_HASH_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_SECONDARY_IC_PROVIDER_NOT_REGISTERED: - reason = "STATUS_SECONDARY_IC_PROVIDER_NOT_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_GPIO_CLIENT_INFORMATION_INVALID: - reason = "STATUS_GPIO_CLIENT_INFORMATION_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_GPIO_VERSION_NOT_SUPPORTED: - reason = "STATUS_GPIO_VERSION_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GPIO_INVALID_REGISTRATION_PACKET: - reason = "STATUS_GPIO_INVALID_REGISTRATION_PACKET"; - break; - case MD_NTSTATUS_WIN_STATUS_GPIO_OPERATION_DENIED: - reason = "STATUS_GPIO_OPERATION_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE: - reason = "STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_SWITCH_RUNLEVEL: - reason = "STATUS_CANNOT_SWITCH_RUNLEVEL"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_RUNLEVEL_SETTING: - reason = "STATUS_INVALID_RUNLEVEL_SETTING"; - break; - case MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_TIMEOUT: - reason = "STATUS_RUNLEVEL_SWITCH_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_AGENT_TIMEOUT: - reason = "STATUS_RUNLEVEL_SWITCH_AGENT_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_RUNLEVEL_SWITCH_IN_PROGRESS: - reason = "STATUS_RUNLEVEL_SWITCH_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_APPCONTAINER: - reason = "STATUS_NOT_APPCONTAINER"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SUPPORTED_IN_APPCONTAINER: - reason = "STATUS_NOT_SUPPORTED_IN_APPCONTAINER"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_PACKAGE_SID_LENGTH: - reason = "STATUS_INVALID_PACKAGE_SID_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_DATA_NOT_FOUND: - reason = "STATUS_APP_DATA_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_DATA_EXPIRED: - reason = "STATUS_APP_DATA_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_DATA_CORRUPT: - reason = "STATUS_APP_DATA_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_DATA_LIMIT_EXCEEDED: - reason = "STATUS_APP_DATA_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_APP_DATA_REBOOT_REQUIRED: - reason = "STATUS_APP_DATA_REBOOT_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_OFFLOAD_READ_FLT_NOT_SUPPORTED: - reason = "STATUS_OFFLOAD_READ_FLT_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_OFFLOAD_WRITE_FLT_NOT_SUPPORTED: - reason = "STATUS_OFFLOAD_WRITE_FLT_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_OFFLOAD_READ_FILE_NOT_SUPPORTED: - reason = "STATUS_OFFLOAD_READ_FILE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED: - reason = "STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_DBG_NO_STATE_CHANGE: - reason = "DBG_NO_STATE_CHANGE"; - break; - case MD_NTSTATUS_WIN_DBG_APP_NOT_IDLE: - reason = "DBG_APP_NOT_IDLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_STRING_BINDING: - reason = "RPC_NT_INVALID_STRING_BINDING"; - break; - case MD_NTSTATUS_WIN_RPC_NT_WRONG_KIND_OF_BINDING: - reason = "RPC_NT_WRONG_KIND_OF_BINDING"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_BINDING: - reason = "RPC_NT_INVALID_BINDING"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PROTSEQ_NOT_SUPPORTED: - reason = "RPC_NT_PROTSEQ_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_RPC_PROTSEQ: - reason = "RPC_NT_INVALID_RPC_PROTSEQ"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_STRING_UUID: - reason = "RPC_NT_INVALID_STRING_UUID"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_ENDPOINT_FORMAT: - reason = "RPC_NT_INVALID_ENDPOINT_FORMAT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_NET_ADDR: - reason = "RPC_NT_INVALID_NET_ADDR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_ENDPOINT_FOUND: - reason = "RPC_NT_NO_ENDPOINT_FOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_TIMEOUT: - reason = "RPC_NT_INVALID_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_OBJECT_NOT_FOUND: - reason = "RPC_NT_OBJECT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ALREADY_REGISTERED: - reason = "RPC_NT_ALREADY_REGISTERED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_TYPE_ALREADY_REGISTERED: - reason = "RPC_NT_TYPE_ALREADY_REGISTERED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ALREADY_LISTENING: - reason = "RPC_NT_ALREADY_LISTENING"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_PROTSEQS_REGISTERED: - reason = "RPC_NT_NO_PROTSEQS_REGISTERED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NOT_LISTENING: - reason = "RPC_NT_NOT_LISTENING"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_MGR_TYPE: - reason = "RPC_NT_UNKNOWN_MGR_TYPE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_IF: - reason = "RPC_NT_UNKNOWN_IF"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_BINDINGS: - reason = "RPC_NT_NO_BINDINGS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_PROTSEQS: - reason = "RPC_NT_NO_PROTSEQS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CANT_CREATE_ENDPOINT: - reason = "RPC_NT_CANT_CREATE_ENDPOINT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_OUT_OF_RESOURCES: - reason = "RPC_NT_OUT_OF_RESOURCES"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SERVER_UNAVAILABLE: - reason = "RPC_NT_SERVER_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SERVER_TOO_BUSY: - reason = "RPC_NT_SERVER_TOO_BUSY"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_NETWORK_OPTIONS: - reason = "RPC_NT_INVALID_NETWORK_OPTIONS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_CALL_ACTIVE: - reason = "RPC_NT_NO_CALL_ACTIVE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CALL_FAILED: - reason = "RPC_NT_CALL_FAILED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CALL_FAILED_DNE: - reason = "RPC_NT_CALL_FAILED_DNE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PROTOCOL_ERROR: - reason = "RPC_NT_PROTOCOL_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_TRANS_SYN: - reason = "RPC_NT_UNSUPPORTED_TRANS_SYN"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_TYPE: - reason = "RPC_NT_UNSUPPORTED_TYPE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_TAG: - reason = "RPC_NT_INVALID_TAG"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_BOUND: - reason = "RPC_NT_INVALID_BOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_ENTRY_NAME: - reason = "RPC_NT_NO_ENTRY_NAME"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_NAME_SYNTAX: - reason = "RPC_NT_INVALID_NAME_SYNTAX"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_NAME_SYNTAX: - reason = "RPC_NT_UNSUPPORTED_NAME_SYNTAX"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UUID_NO_ADDRESS: - reason = "RPC_NT_UUID_NO_ADDRESS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_DUPLICATE_ENDPOINT: - reason = "RPC_NT_DUPLICATE_ENDPOINT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_TYPE: - reason = "RPC_NT_UNKNOWN_AUTHN_TYPE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_MAX_CALLS_TOO_SMALL: - reason = "RPC_NT_MAX_CALLS_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_STRING_TOO_LONG: - reason = "RPC_NT_STRING_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PROTSEQ_NOT_FOUND: - reason = "RPC_NT_PROTSEQ_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PROCNUM_OUT_OF_RANGE: - reason = "RPC_NT_PROCNUM_OUT_OF_RANGE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_BINDING_HAS_NO_AUTH: - reason = "RPC_NT_BINDING_HAS_NO_AUTH"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_SERVICE: - reason = "RPC_NT_UNKNOWN_AUTHN_SERVICE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHN_LEVEL: - reason = "RPC_NT_UNKNOWN_AUTHN_LEVEL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_AUTH_IDENTITY: - reason = "RPC_NT_INVALID_AUTH_IDENTITY"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNKNOWN_AUTHZ_SERVICE: - reason = "RPC_NT_UNKNOWN_AUTHZ_SERVICE"; - break; - case MD_NTSTATUS_WIN_EPT_NT_INVALID_ENTRY: - reason = "EPT_NT_INVALID_ENTRY"; - break; - case MD_NTSTATUS_WIN_EPT_NT_CANT_PERFORM_OP: - reason = "EPT_NT_CANT_PERFORM_OP"; - break; - case MD_NTSTATUS_WIN_EPT_NT_NOT_REGISTERED: - reason = "EPT_NT_NOT_REGISTERED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NOTHING_TO_EXPORT: - reason = "RPC_NT_NOTHING_TO_EXPORT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INCOMPLETE_NAME: - reason = "RPC_NT_INCOMPLETE_NAME"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_VERS_OPTION: - reason = "RPC_NT_INVALID_VERS_OPTION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_MORE_MEMBERS: - reason = "RPC_NT_NO_MORE_MEMBERS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NOT_ALL_OBJS_UNEXPORTED: - reason = "RPC_NT_NOT_ALL_OBJS_UNEXPORTED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INTERFACE_NOT_FOUND: - reason = "RPC_NT_INTERFACE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ENTRY_ALREADY_EXISTS: - reason = "RPC_NT_ENTRY_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ENTRY_NOT_FOUND: - reason = "RPC_NT_ENTRY_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NAME_SERVICE_UNAVAILABLE: - reason = "RPC_NT_NAME_SERVICE_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_NAF_ID: - reason = "RPC_NT_INVALID_NAF_ID"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CANNOT_SUPPORT: - reason = "RPC_NT_CANNOT_SUPPORT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_CONTEXT_AVAILABLE: - reason = "RPC_NT_NO_CONTEXT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INTERNAL_ERROR: - reason = "RPC_NT_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ZERO_DIVIDE: - reason = "RPC_NT_ZERO_DIVIDE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ADDRESS_ERROR: - reason = "RPC_NT_ADDRESS_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_FP_DIV_ZERO: - reason = "RPC_NT_FP_DIV_ZERO"; - break; - case MD_NTSTATUS_WIN_RPC_NT_FP_UNDERFLOW: - reason = "RPC_NT_FP_UNDERFLOW"; - break; - case MD_NTSTATUS_WIN_RPC_NT_FP_OVERFLOW: - reason = "RPC_NT_FP_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CALL_IN_PROGRESS: - reason = "RPC_NT_CALL_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_MORE_BINDINGS: - reason = "RPC_NT_NO_MORE_BINDINGS"; - break; - case MD_NTSTATUS_WIN_RPC_NT_GROUP_MEMBER_NOT_FOUND: - reason = "RPC_NT_GROUP_MEMBER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_EPT_NT_CANT_CREATE: - reason = "EPT_NT_CANT_CREATE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_OBJECT: - reason = "RPC_NT_INVALID_OBJECT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_INTERFACES: - reason = "RPC_NT_NO_INTERFACES"; - break; - case MD_NTSTATUS_WIN_RPC_NT_CALL_CANCELLED: - reason = "RPC_NT_CALL_CANCELLED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_BINDING_INCOMPLETE: - reason = "RPC_NT_BINDING_INCOMPLETE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_COMM_FAILURE: - reason = "RPC_NT_COMM_FAILURE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_UNSUPPORTED_AUTHN_LEVEL: - reason = "RPC_NT_UNSUPPORTED_AUTHN_LEVEL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_PRINC_NAME: - reason = "RPC_NT_NO_PRINC_NAME"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NOT_RPC_ERROR: - reason = "RPC_NT_NOT_RPC_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SEC_PKG_ERROR: - reason = "RPC_NT_SEC_PKG_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NOT_CANCELLED: - reason = "RPC_NT_NOT_CANCELLED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_ASYNC_HANDLE: - reason = "RPC_NT_INVALID_ASYNC_HANDLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_ASYNC_CALL: - reason = "RPC_NT_INVALID_ASYNC_CALL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PROXY_ACCESS_DENIED: - reason = "RPC_NT_PROXY_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_COOKIE_AUTH_FAILED: - reason = "RPC_NT_COOKIE_AUTH_FAILED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NO_MORE_ENTRIES: - reason = "RPC_NT_NO_MORE_ENTRIES"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_CHAR_TRANS_OPEN_FAIL: - reason = "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_CHAR_TRANS_SHORT_FILE: - reason = "RPC_NT_SS_CHAR_TRANS_SHORT_FILE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_IN_NULL_CONTEXT: - reason = "RPC_NT_SS_IN_NULL_CONTEXT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_CONTEXT_MISMATCH: - reason = "RPC_NT_SS_CONTEXT_MISMATCH"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_CONTEXT_DAMAGED: - reason = "RPC_NT_SS_CONTEXT_DAMAGED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_HANDLES_MISMATCH: - reason = "RPC_NT_SS_HANDLES_MISMATCH"; - break; - case MD_NTSTATUS_WIN_RPC_NT_SS_CANNOT_GET_CALL_HANDLE: - reason = "RPC_NT_SS_CANNOT_GET_CALL_HANDLE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_NULL_REF_POINTER: - reason = "RPC_NT_NULL_REF_POINTER"; - break; - case MD_NTSTATUS_WIN_RPC_NT_ENUM_VALUE_OUT_OF_RANGE: - reason = "RPC_NT_ENUM_VALUE_OUT_OF_RANGE"; - break; - case MD_NTSTATUS_WIN_RPC_NT_BYTE_COUNT_TOO_SMALL: - reason = "RPC_NT_BYTE_COUNT_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_RPC_NT_BAD_STUB_DATA: - reason = "RPC_NT_BAD_STUB_DATA"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_ES_ACTION: - reason = "RPC_NT_INVALID_ES_ACTION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_WRONG_ES_VERSION: - reason = "RPC_NT_WRONG_ES_VERSION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_WRONG_STUB_VERSION: - reason = "RPC_NT_WRONG_STUB_VERSION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_PIPE_OBJECT: - reason = "RPC_NT_INVALID_PIPE_OBJECT"; - break; - case MD_NTSTATUS_WIN_RPC_NT_INVALID_PIPE_OPERATION: - reason = "RPC_NT_INVALID_PIPE_OPERATION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_WRONG_PIPE_VERSION: - reason = "RPC_NT_WRONG_PIPE_VERSION"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PIPE_CLOSED: - reason = "RPC_NT_PIPE_CLOSED"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PIPE_DISCIPLINE_ERROR: - reason = "RPC_NT_PIPE_DISCIPLINE_ERROR"; - break; - case MD_NTSTATUS_WIN_RPC_NT_PIPE_EMPTY: - reason = "RPC_NT_PIPE_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_BAD_MPS_TABLE: - reason = "STATUS_PNP_BAD_MPS_TABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_TRANSLATION_FAILED: - reason = "STATUS_PNP_TRANSLATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_IRQ_TRANSLATION_FAILED: - reason = "STATUS_PNP_IRQ_TRANSLATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_PNP_INVALID_ID: - reason = "STATUS_PNP_INVALID_ID"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_REISSUE_AS_CACHED: - reason = "STATUS_IO_REISSUE_AS_CACHED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NAME_INVALID: - reason = "STATUS_CTX_WINSTATION_NAME_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_INVALID_PD: - reason = "STATUS_CTX_INVALID_PD"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_PD_NOT_FOUND: - reason = "STATUS_CTX_PD_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CLOSE_PENDING: - reason = "STATUS_CTX_CLOSE_PENDING"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_NO_OUTBUF: - reason = "STATUS_CTX_NO_OUTBUF"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_INF_NOT_FOUND: - reason = "STATUS_CTX_MODEM_INF_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_INVALID_MODEMNAME: - reason = "STATUS_CTX_INVALID_MODEMNAME"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_RESPONSE_ERROR: - reason = "STATUS_CTX_RESPONSE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_TIMEOUT: - reason = "STATUS_CTX_MODEM_RESPONSE_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_NO_CARRIER: - reason = "STATUS_CTX_MODEM_RESPONSE_NO_CARRIER"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE: - reason = "STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_BUSY: - reason = "STATUS_CTX_MODEM_RESPONSE_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_MODEM_RESPONSE_VOICE: - reason = "STATUS_CTX_MODEM_RESPONSE_VOICE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_TD_ERROR: - reason = "STATUS_CTX_TD_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_CLIENT_INVALID: - reason = "STATUS_CTX_LICENSE_CLIENT_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_NOT_AVAILABLE: - reason = "STATUS_CTX_LICENSE_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_LICENSE_EXPIRED: - reason = "STATUS_CTX_LICENSE_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NOT_FOUND: - reason = "STATUS_CTX_WINSTATION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_NAME_COLLISION: - reason = "STATUS_CTX_WINSTATION_NAME_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_BUSY: - reason = "STATUS_CTX_WINSTATION_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_BAD_VIDEO_MODE: - reason = "STATUS_CTX_BAD_VIDEO_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_GRAPHICS_INVALID: - reason = "STATUS_CTX_GRAPHICS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_NOT_CONSOLE: - reason = "STATUS_CTX_NOT_CONSOLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_QUERY_TIMEOUT: - reason = "STATUS_CTX_CLIENT_QUERY_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CONSOLE_DISCONNECT: - reason = "STATUS_CTX_CONSOLE_DISCONNECT"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CONSOLE_CONNECT: - reason = "STATUS_CTX_CONSOLE_CONNECT"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_DENIED: - reason = "STATUS_CTX_SHADOW_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WINSTATION_ACCESS_DENIED: - reason = "STATUS_CTX_WINSTATION_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_INVALID_WD: - reason = "STATUS_CTX_INVALID_WD"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_WD_NOT_FOUND: - reason = "STATUS_CTX_WD_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_INVALID: - reason = "STATUS_CTX_SHADOW_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_DISABLED: - reason = "STATUS_CTX_SHADOW_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_RDP_PROTOCOL_ERROR: - reason = "STATUS_RDP_PROTOCOL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_LICENSE_NOT_SET: - reason = "STATUS_CTX_CLIENT_LICENSE_NOT_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_CLIENT_LICENSE_IN_USE: - reason = "STATUS_CTX_CLIENT_LICENSE_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE: - reason = "STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SHADOW_NOT_RUNNING: - reason = "STATUS_CTX_SHADOW_NOT_RUNNING"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_LOGON_DISABLED: - reason = "STATUS_CTX_LOGON_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTX_SECURITY_LAYER_ERROR: - reason = "STATUS_CTX_SECURITY_LAYER_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_TS_INCOMPATIBLE_SESSIONS: - reason = "STATUS_TS_INCOMPATIBLE_SESSIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_TS_VIDEO_SUBSYSTEM_ERROR: - reason = "STATUS_TS_VIDEO_SUBSYSTEM_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_FILE_NOT_FOUND: - reason = "STATUS_MUI_FILE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_INVALID_FILE: - reason = "STATUS_MUI_INVALID_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_INVALID_RC_CONFIG: - reason = "STATUS_MUI_INVALID_RC_CONFIG"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_INVALID_LOCALE_NAME: - reason = "STATUS_MUI_INVALID_LOCALE_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME: - reason = "STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_MUI_FILE_NOT_LOADED: - reason = "STATUS_MUI_FILE_NOT_LOADED"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCE_ENUM_USER_STOP: - reason = "STATUS_RESOURCE_ENUM_USER_STOP"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NODE: - reason = "STATUS_CLUSTER_INVALID_NODE"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_EXISTS: - reason = "STATUS_CLUSTER_NODE_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_JOIN_IN_PROGRESS: - reason = "STATUS_CLUSTER_JOIN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_FOUND: - reason = "STATUS_CLUSTER_NODE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND: - reason = "STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_EXISTS: - reason = "STATUS_CLUSTER_NETWORK_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_NOT_FOUND: - reason = "STATUS_CLUSTER_NETWORK_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NETINTERFACE_EXISTS: - reason = "STATUS_CLUSTER_NETINTERFACE_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NETINTERFACE_NOT_FOUND: - reason = "STATUS_CLUSTER_NETINTERFACE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_REQUEST: - reason = "STATUS_CLUSTER_INVALID_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NETWORK_PROVIDER: - reason = "STATUS_CLUSTER_INVALID_NETWORK_PROVIDER"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_DOWN: - reason = "STATUS_CLUSTER_NODE_DOWN"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_UNREACHABLE: - reason = "STATUS_CLUSTER_NODE_UNREACHABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_MEMBER: - reason = "STATUS_CLUSTER_NODE_NOT_MEMBER"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS: - reason = "STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_INVALID_NETWORK: - reason = "STATUS_CLUSTER_INVALID_NETWORK"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NO_NET_ADAPTERS: - reason = "STATUS_CLUSTER_NO_NET_ADAPTERS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_UP: - reason = "STATUS_CLUSTER_NODE_UP"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_PAUSED: - reason = "STATUS_CLUSTER_NODE_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NODE_NOT_PAUSED: - reason = "STATUS_CLUSTER_NODE_NOT_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NO_SECURITY_CONTEXT: - reason = "STATUS_CLUSTER_NO_SECURITY_CONTEXT"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NETWORK_NOT_INTERNAL: - reason = "STATUS_CLUSTER_NETWORK_NOT_INTERNAL"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_POISONED: - reason = "STATUS_CLUSTER_POISONED"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_NON_CSV_PATH: - reason = "STATUS_CLUSTER_NON_CSV_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL: - reason = "STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS: - reason = "STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR: - reason = "STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_REDIRECTED: - reason = "STATUS_CLUSTER_CSV_REDIRECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_NOT_REDIRECTED: - reason = "STATUS_CLUSTER_CSV_NOT_REDIRECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_DRAINING: - reason = "STATUS_CLUSTER_CSV_VOLUME_DRAINING"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS: - reason = "STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL: - reason = "STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_OPCODE: - reason = "STATUS_ACPI_INVALID_OPCODE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_STACK_OVERFLOW: - reason = "STATUS_ACPI_STACK_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_ASSERT_FAILED: - reason = "STATUS_ACPI_ASSERT_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_INDEX: - reason = "STATUS_ACPI_INVALID_INDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ARGUMENT: - reason = "STATUS_ACPI_INVALID_ARGUMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_FATAL: - reason = "STATUS_ACPI_FATAL"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_SUPERNAME: - reason = "STATUS_ACPI_INVALID_SUPERNAME"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ARGTYPE: - reason = "STATUS_ACPI_INVALID_ARGTYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_OBJTYPE: - reason = "STATUS_ACPI_INVALID_OBJTYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_TARGETTYPE: - reason = "STATUS_ACPI_INVALID_TARGETTYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INCORRECT_ARGUMENT_COUNT: - reason = "STATUS_ACPI_INCORRECT_ARGUMENT_COUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_ADDRESS_NOT_MAPPED: - reason = "STATUS_ACPI_ADDRESS_NOT_MAPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_EVENTTYPE: - reason = "STATUS_ACPI_INVALID_EVENTTYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_HANDLER_COLLISION: - reason = "STATUS_ACPI_HANDLER_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_DATA: - reason = "STATUS_ACPI_INVALID_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_REGION: - reason = "STATUS_ACPI_INVALID_REGION"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_ACCESS_SIZE: - reason = "STATUS_ACPI_INVALID_ACCESS_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_ACQUIRE_GLOBAL_LOCK: - reason = "STATUS_ACPI_ACQUIRE_GLOBAL_LOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_ALREADY_INITIALIZED: - reason = "STATUS_ACPI_ALREADY_INITIALIZED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_NOT_INITIALIZED: - reason = "STATUS_ACPI_NOT_INITIALIZED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_MUTEX_LEVEL: - reason = "STATUS_ACPI_INVALID_MUTEX_LEVEL"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_MUTEX_NOT_OWNED: - reason = "STATUS_ACPI_MUTEX_NOT_OWNED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_MUTEX_NOT_OWNER: - reason = "STATUS_ACPI_MUTEX_NOT_OWNER"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_RS_ACCESS: - reason = "STATUS_ACPI_RS_ACCESS"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_INVALID_TABLE: - reason = "STATUS_ACPI_INVALID_TABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_REG_HANDLER_FAILED: - reason = "STATUS_ACPI_REG_HANDLER_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_ACPI_POWER_REQUEST_FAILED: - reason = "STATUS_ACPI_POWER_REQUEST_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_SECTION_NOT_FOUND: - reason = "STATUS_SXS_SECTION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_CANT_GEN_ACTCTX: - reason = "STATUS_SXS_CANT_GEN_ACTCTX"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_INVALID_ACTCTXDATA_FORMAT: - reason = "STATUS_SXS_INVALID_ACTCTXDATA_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_NOT_FOUND: - reason = "STATUS_SXS_ASSEMBLY_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_FORMAT_ERROR: - reason = "STATUS_SXS_MANIFEST_FORMAT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_PARSE_ERROR: - reason = "STATUS_SXS_MANIFEST_PARSE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_ACTIVATION_CONTEXT_DISABLED: - reason = "STATUS_SXS_ACTIVATION_CONTEXT_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_KEY_NOT_FOUND: - reason = "STATUS_SXS_KEY_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_VERSION_CONFLICT: - reason = "STATUS_SXS_VERSION_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_WRONG_SECTION_TYPE: - reason = "STATUS_SXS_WRONG_SECTION_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_THREAD_QUERIES_DISABLED: - reason = "STATUS_SXS_THREAD_QUERIES_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_MISSING: - reason = "STATUS_SXS_ASSEMBLY_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET: - reason = "STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_EARLY_DEACTIVATION: - reason = "STATUS_SXS_EARLY_DEACTIVATION"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_INVALID_DEACTIVATION: - reason = "STATUS_SXS_INVALID_DEACTIVATION"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_MULTIPLE_DEACTIVATION: - reason = "STATUS_SXS_MULTIPLE_DEACTIVATION"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY: - reason = "STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_PROCESS_TERMINATION_REQUESTED: - reason = "STATUS_SXS_PROCESS_TERMINATION_REQUESTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_CORRUPT_ACTIVATION_STACK: - reason = "STATUS_SXS_CORRUPT_ACTIVATION_STACK"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_CORRUPTION: - reason = "STATUS_SXS_CORRUPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE: - reason = "STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME: - reason = "STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE: - reason = "STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_IDENTITY_PARSE_ERROR: - reason = "STATUS_SXS_IDENTITY_PARSE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_COMPONENT_STORE_CORRUPT: - reason = "STATUS_SXS_COMPONENT_STORE_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_FILE_HASH_MISMATCH: - reason = "STATUS_SXS_FILE_HASH_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT: - reason = "STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_IDENTITIES_DIFFERENT: - reason = "STATUS_SXS_IDENTITIES_DIFFERENT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT: - reason = "STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY: - reason = "STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY"; - break; - case MD_NTSTATUS_WIN_STATUS_ADVANCED_INSTALLER_FAILED: - reason = "STATUS_ADVANCED_INSTALLER_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_XML_ENCODING_MISMATCH: - reason = "STATUS_XML_ENCODING_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_MANIFEST_TOO_BIG: - reason = "STATUS_SXS_MANIFEST_TOO_BIG"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_SETTING_NOT_REGISTERED: - reason = "STATUS_SXS_SETTING_NOT_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE: - reason = "STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE"; - break; - case MD_NTSTATUS_WIN_STATUS_SMI_PRIMITIVE_INSTALLER_FAILED: - reason = "STATUS_SMI_PRIMITIVE_INSTALLER_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_GENERIC_COMMAND_FAILED: - reason = "STATUS_GENERIC_COMMAND_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_SXS_FILE_HASH_MISSING: - reason = "STATUS_SXS_FILE_HASH_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONAL_CONFLICT: - reason = "STATUS_TRANSACTIONAL_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_INVALID_TRANSACTION: - reason = "STATUS_INVALID_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ACTIVE: - reason = "STATUS_TRANSACTION_NOT_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_TM_INITIALIZATION_FAILED: - reason = "STATUS_TM_INITIALIZATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_RM_NOT_ACTIVE: - reason = "STATUS_RM_NOT_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_RM_METADATA_CORRUPT: - reason = "STATUS_RM_METADATA_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_JOINED: - reason = "STATUS_TRANSACTION_NOT_JOINED"; - break; - case MD_NTSTATUS_WIN_STATUS_DIRECTORY_NOT_RM: - reason = "STATUS_DIRECTORY_NOT_RM"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE: - reason = "STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_RESIZE_INVALID_SIZE: - reason = "STATUS_LOG_RESIZE_INVALID_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_REMOTE_FILE_VERSION_MISMATCH: - reason = "STATUS_REMOTE_FILE_VERSION_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_CRM_PROTOCOL_ALREADY_EXISTS: - reason = "STATUS_CRM_PROTOCOL_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_PROPAGATION_FAILED: - reason = "STATUS_TRANSACTION_PROPAGATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_CRM_PROTOCOL_NOT_FOUND: - reason = "STATUS_CRM_PROTOCOL_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_SUPERIOR_EXISTS: - reason = "STATUS_TRANSACTION_SUPERIOR_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_REQUEST_NOT_VALID: - reason = "STATUS_TRANSACTION_REQUEST_NOT_VALID"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_REQUESTED: - reason = "STATUS_TRANSACTION_NOT_REQUESTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_ALREADY_ABORTED: - reason = "STATUS_TRANSACTION_ALREADY_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_ALREADY_COMMITTED: - reason = "STATUS_TRANSACTION_ALREADY_COMMITTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER: - reason = "STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_CURRENT_TRANSACTION_NOT_VALID: - reason = "STATUS_CURRENT_TRANSACTION_NOT_VALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_GROWTH_FAILED: - reason = "STATUS_LOG_GROWTH_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_OBJECT_NO_LONGER_EXISTS: - reason = "STATUS_OBJECT_NO_LONGER_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_STREAM_MINIVERSION_NOT_FOUND: - reason = "STATUS_STREAM_MINIVERSION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_STREAM_MINIVERSION_NOT_VALID: - reason = "STATUS_STREAM_MINIVERSION_NOT_VALID"; - break; - case MD_NTSTATUS_WIN_STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION: - reason = "STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT: - reason = "STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS: - reason = "STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_HANDLE_NO_LONGER_VALID: - reason = "STATUS_HANDLE_NO_LONGER_VALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CORRUPTION_DETECTED: - reason = "STATUS_LOG_CORRUPTION_DETECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_RM_DISCONNECTED: - reason = "STATUS_RM_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_ENLISTMENT_NOT_SUPERIOR: - reason = "STATUS_ENLISTMENT_NOT_SUPERIOR"; - break; - case MD_NTSTATUS_WIN_STATUS_FILE_IDENTITY_NOT_PERSISTENT: - reason = "STATUS_FILE_IDENTITY_NOT_PERSISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY: - reason = "STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY"; - break; - case MD_NTSTATUS_WIN_STATUS_CANT_CROSS_RM_BOUNDARY: - reason = "STATUS_CANT_CROSS_RM_BOUNDARY"; - break; - case MD_NTSTATUS_WIN_STATUS_TXF_DIR_NOT_EMPTY: - reason = "STATUS_TXF_DIR_NOT_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_INDOUBT_TRANSACTIONS_EXIST: - reason = "STATUS_INDOUBT_TRANSACTIONS_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_TM_VOLATILE: - reason = "STATUS_TM_VOLATILE"; - break; - case MD_NTSTATUS_WIN_STATUS_ROLLBACK_TIMER_EXPIRED: - reason = "STATUS_ROLLBACK_TIMER_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_TXF_ATTRIBUTE_CORRUPT: - reason = "STATUS_TXF_ATTRIBUTE_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION: - reason = "STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED: - reason = "STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE: - reason = "STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_REQUIRED_PROMOTION: - reason = "STATUS_TRANSACTION_REQUIRED_PROMOTION"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION: - reason = "STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONS_NOT_FROZEN: - reason = "STATUS_TRANSACTIONS_NOT_FROZEN"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_FREEZE_IN_PROGRESS: - reason = "STATUS_TRANSACTION_FREEZE_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_NOT_SNAPSHOT_VOLUME: - reason = "STATUS_NOT_SNAPSHOT_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_SAVEPOINT_WITH_OPEN_FILES: - reason = "STATUS_NO_SAVEPOINT_WITH_OPEN_FILES"; - break; - case MD_NTSTATUS_WIN_STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION: - reason = "STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TM_IDENTITY_MISMATCH: - reason = "STATUS_TM_IDENTITY_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FLOATED_SECTION: - reason = "STATUS_FLOATED_SECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_ACCEPT_TRANSACTED_WORK: - reason = "STATUS_CANNOT_ACCEPT_TRANSACTED_WORK"; - break; - case MD_NTSTATUS_WIN_STATUS_CANNOT_ABORT_TRANSACTIONS: - reason = "STATUS_CANNOT_ABORT_TRANSACTIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_FOUND: - reason = "STATUS_TRANSACTION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RESOURCEMANAGER_NOT_FOUND: - reason = "STATUS_RESOURCEMANAGER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_ENLISTMENT_NOT_FOUND: - reason = "STATUS_ENLISTMENT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_NOT_FOUND: - reason = "STATUS_TRANSACTIONMANAGER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_NOT_ONLINE: - reason = "STATUS_TRANSACTIONMANAGER_NOT_ONLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION: - reason = "STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ROOT: - reason = "STATUS_TRANSACTION_NOT_ROOT"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_OBJECT_EXPIRED: - reason = "STATUS_TRANSACTION_OBJECT_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION: - reason = "STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED: - reason = "STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_RECORD_TOO_LONG: - reason = "STATUS_TRANSACTION_RECORD_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_NO_LINK_TRACKING_IN_TRANSACTION: - reason = "STATUS_NO_LINK_TRACKING_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION: - reason = "STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_INTEGRITY_VIOLATED: - reason = "STATUS_TRANSACTION_INTEGRITY_VIOLATED"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH: - reason = "STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT: - reason = "STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_MUST_WRITETHROUGH: - reason = "STATUS_TRANSACTION_MUST_WRITETHROUGH"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NO_SUPERIOR: - reason = "STATUS_TRANSACTION_NO_SUPERIOR"; - break; - case MD_NTSTATUS_WIN_STATUS_EXPIRED_HANDLE: - reason = "STATUS_EXPIRED_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TRANSACTION_NOT_ENLISTED: - reason = "STATUS_TRANSACTION_NOT_ENLISTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_INVALID: - reason = "STATUS_LOG_SECTOR_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_PARITY_INVALID: - reason = "STATUS_LOG_SECTOR_PARITY_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_SECTOR_REMAPPED: - reason = "STATUS_LOG_SECTOR_REMAPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_INCOMPLETE: - reason = "STATUS_LOG_BLOCK_INCOMPLETE"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_INVALID_RANGE: - reason = "STATUS_LOG_INVALID_RANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_BLOCKS_EXHAUSTED: - reason = "STATUS_LOG_BLOCKS_EXHAUSTED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_READ_CONTEXT_INVALID: - reason = "STATUS_LOG_READ_CONTEXT_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_RESTART_INVALID: - reason = "STATUS_LOG_RESTART_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_VERSION: - reason = "STATUS_LOG_BLOCK_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_BLOCK_INVALID: - reason = "STATUS_LOG_BLOCK_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_READ_MODE_INVALID: - reason = "STATUS_LOG_READ_MODE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_METADATA_CORRUPT: - reason = "STATUS_LOG_METADATA_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_METADATA_INVALID: - reason = "STATUS_LOG_METADATA_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_METADATA_INCONSISTENT: - reason = "STATUS_LOG_METADATA_INCONSISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_RESERVATION_INVALID: - reason = "STATUS_LOG_RESERVATION_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CANT_DELETE: - reason = "STATUS_LOG_CANT_DELETE"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_LIMIT_EXCEEDED: - reason = "STATUS_LOG_CONTAINER_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_START_OF_LOG: - reason = "STATUS_LOG_START_OF_LOG"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_POLICY_ALREADY_INSTALLED: - reason = "STATUS_LOG_POLICY_ALREADY_INSTALLED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_POLICY_NOT_INSTALLED: - reason = "STATUS_LOG_POLICY_NOT_INSTALLED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_POLICY_INVALID: - reason = "STATUS_LOG_POLICY_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_POLICY_CONFLICT: - reason = "STATUS_LOG_POLICY_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_PINNED_ARCHIVE_TAIL: - reason = "STATUS_LOG_PINNED_ARCHIVE_TAIL"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_RECORD_NONEXISTENT: - reason = "STATUS_LOG_RECORD_NONEXISTENT"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_RECORDS_RESERVED_INVALID: - reason = "STATUS_LOG_RECORDS_RESERVED_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_SPACE_RESERVED_INVALID: - reason = "STATUS_LOG_SPACE_RESERVED_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_TAIL_INVALID: - reason = "STATUS_LOG_TAIL_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_FULL: - reason = "STATUS_LOG_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_MULTIPLEXED: - reason = "STATUS_LOG_MULTIPLEXED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_DEDICATED: - reason = "STATUS_LOG_DEDICATED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS: - reason = "STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_ARCHIVE_IN_PROGRESS: - reason = "STATUS_LOG_ARCHIVE_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_EPHEMERAL: - reason = "STATUS_LOG_EPHEMERAL"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_NOT_ENOUGH_CONTAINERS: - reason = "STATUS_LOG_NOT_ENOUGH_CONTAINERS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CLIENT_ALREADY_REGISTERED: - reason = "STATUS_LOG_CLIENT_ALREADY_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CLIENT_NOT_REGISTERED: - reason = "STATUS_LOG_CLIENT_NOT_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_FULL_HANDLER_IN_PROGRESS: - reason = "STATUS_LOG_FULL_HANDLER_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_READ_FAILED: - reason = "STATUS_LOG_CONTAINER_READ_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_WRITE_FAILED: - reason = "STATUS_LOG_CONTAINER_WRITE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_OPEN_FAILED: - reason = "STATUS_LOG_CONTAINER_OPEN_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_CONTAINER_STATE_INVALID: - reason = "STATUS_LOG_CONTAINER_STATE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_STATE_INVALID: - reason = "STATUS_LOG_STATE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_PINNED: - reason = "STATUS_LOG_PINNED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_METADATA_FLUSH_FAILED: - reason = "STATUS_LOG_METADATA_FLUSH_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_INCONSISTENT_SECURITY: - reason = "STATUS_LOG_INCONSISTENT_SECURITY"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_APPENDED_FLUSH_FAILED: - reason = "STATUS_LOG_APPENDED_FLUSH_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_LOG_PINNED_RESERVATION: - reason = "STATUS_LOG_PINNED_RESERVATION"; - break; - case MD_NTSTATUS_WIN_STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD: - reason = "STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NO_HANDLER_DEFINED: - reason = "STATUS_FLT_NO_HANDLER_DEFINED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALREADY_DEFINED: - reason = "STATUS_FLT_CONTEXT_ALREADY_DEFINED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST: - reason = "STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_DISALLOW_FAST_IO: - reason = "STATUS_FLT_DISALLOW_FAST_IO"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INVALID_NAME_REQUEST: - reason = "STATUS_FLT_INVALID_NAME_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NOT_SAFE_TO_POST_OPERATION: - reason = "STATUS_FLT_NOT_SAFE_TO_POST_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NOT_INITIALIZED: - reason = "STATUS_FLT_NOT_INITIALIZED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_FILTER_NOT_READY: - reason = "STATUS_FLT_FILTER_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_POST_OPERATION_CLEANUP: - reason = "STATUS_FLT_POST_OPERATION_CLEANUP"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INTERNAL_ERROR: - reason = "STATUS_FLT_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_DELETING_OBJECT: - reason = "STATUS_FLT_DELETING_OBJECT"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_MUST_BE_NONPAGED_POOL: - reason = "STATUS_FLT_MUST_BE_NONPAGED_POOL"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_DUPLICATE_ENTRY: - reason = "STATUS_FLT_DUPLICATE_ENTRY"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_CBDQ_DISABLED: - reason = "STATUS_FLT_CBDQ_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_DO_NOT_ATTACH: - reason = "STATUS_FLT_DO_NOT_ATTACH"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_DO_NOT_DETACH: - reason = "STATUS_FLT_DO_NOT_DETACH"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_ALTITUDE_COLLISION: - reason = "STATUS_FLT_INSTANCE_ALTITUDE_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_NAME_COLLISION: - reason = "STATUS_FLT_INSTANCE_NAME_COLLISION"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_FILTER_NOT_FOUND: - reason = "STATUS_FLT_FILTER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_VOLUME_NOT_FOUND: - reason = "STATUS_FLT_VOLUME_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INSTANCE_NOT_FOUND: - reason = "STATUS_FLT_INSTANCE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND: - reason = "STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_INVALID_CONTEXT_REGISTRATION: - reason = "STATUS_FLT_INVALID_CONTEXT_REGISTRATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NAME_CACHE_MISS: - reason = "STATUS_FLT_NAME_CACHE_MISS"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NO_DEVICE_OBJECT: - reason = "STATUS_FLT_NO_DEVICE_OBJECT"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_VOLUME_ALREADY_MOUNTED: - reason = "STATUS_FLT_VOLUME_ALREADY_MOUNTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_ALREADY_ENLISTED: - reason = "STATUS_FLT_ALREADY_ENLISTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_CONTEXT_ALREADY_LINKED: - reason = "STATUS_FLT_CONTEXT_ALREADY_LINKED"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_NO_WAITER_FOR_REPLY: - reason = "STATUS_FLT_NO_WAITER_FOR_REPLY"; - break; - case MD_NTSTATUS_WIN_STATUS_FLT_REGISTRATION_BUSY: - reason = "STATUS_FLT_REGISTRATION_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_NO_DESCRIPTOR: - reason = "STATUS_MONITOR_NO_DESCRIPTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT: - reason = "STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM: - reason = "STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK: - reason = "STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED: - reason = "STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK: - reason = "STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK: - reason = "STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA: - reason = "STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK: - reason = "STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_MONITOR_INVALID_MANUFACTURE_DATE: - reason = "STATUS_MONITOR_INVALID_MANUFACTURE_DATE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER: - reason = "STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: - reason = "STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER: - reason = "STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_WAS_RESET: - reason = "STATUS_GRAPHICS_ADAPTER_WAS_RESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_DRIVER_MODEL: - reason = "STATUS_GRAPHICS_INVALID_DRIVER_MODEL"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_MODE_CHANGED: - reason = "STATUS_GRAPHICS_PRESENT_MODE_CHANGED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_OCCLUDED: - reason = "STATUS_GRAPHICS_PRESENT_OCCLUDED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_DENIED: - reason = "STATUS_GRAPHICS_PRESENT_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANNOTCOLORCONVERT: - reason = "STATUS_GRAPHICS_CANNOTCOLORCONVERT"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DRIVER_MISMATCH: - reason = "STATUS_GRAPHICS_DRIVER_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED: - reason = "STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PRESENT_UNOCCLUDED: - reason = "STATUS_GRAPHICS_PRESENT_UNOCCLUDED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_WINDOWDC_NOT_AVAILABLE: - reason = "STATUS_GRAPHICS_WINDOWDC_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_WINDOWLESS_PRESENT_DISABLED: - reason = "STATUS_GRAPHICS_WINDOWLESS_PRESENT_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_VIDEO_MEMORY: - reason = "STATUS_GRAPHICS_NO_VIDEO_MEMORY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_LOCK_MEMORY: - reason = "STATUS_GRAPHICS_CANT_LOCK_MEMORY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_BUSY: - reason = "STATUS_GRAPHICS_ALLOCATION_BUSY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TOO_MANY_REFERENCES: - reason = "STATUS_GRAPHICS_TOO_MANY_REFERENCES"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TRY_AGAIN_LATER: - reason = "STATUS_GRAPHICS_TRY_AGAIN_LATER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TRY_AGAIN_NOW: - reason = "STATUS_GRAPHICS_TRY_AGAIN_NOW"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_INVALID: - reason = "STATUS_GRAPHICS_ALLOCATION_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE: - reason = "STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED: - reason = "STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION: - reason = "STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE: - reason = "STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION: - reason = "STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_CLOSED: - reason = "STATUS_GRAPHICS_ALLOCATION_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE: - reason = "STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE: - reason = "STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE: - reason = "STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST: - reason = "STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE: - reason = "STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN: - reason = "STATUS_GRAPHICS_INVALID_VIDPN"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE: - reason = "STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET: - reason = "STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_FREQUENCY: - reason = "STATUS_GRAPHICS_INVALID_FREQUENCY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_ACTIVE_REGION: - reason = "STATUS_GRAPHICS_INVALID_ACTIVE_REGION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_TOTAL_REGION: - reason = "STATUS_GRAPHICS_INVALID_TOTAL_REGION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE: - reason = "STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE: - reason = "STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET: - reason = "STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY: - reason = "STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET: - reason = "STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET: - reason = "STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET: - reason = "STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET: - reason = "STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_ALREADY_IN_SET: - reason = "STATUS_GRAPHICS_TARGET_ALREADY_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY: - reason = "STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET: - reason = "STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET: - reason = "STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_STALE_MODESET: - reason = "STATUS_GRAPHICS_STALE_MODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN: - reason = "STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE: - reason = "STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION: - reason = "STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES: - reason = "STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY: - reason = "STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE: - reason = "STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET: - reason = "STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET: - reason = "STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR: - reason = "STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET: - reason = "STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET: - reason = "STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE: - reason = "STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_RESOURCES_NOT_RELATED: - reason = "STATUS_GRAPHICS_RESOURCES_NOT_RELATED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE: - reason = "STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE: - reason = "STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET: - reason = "STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER: - reason = "STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_VIDPNMGR: - reason = "STATUS_GRAPHICS_NO_VIDPNMGR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_ACTIVE_VIDPN: - reason = "STATUS_GRAPHICS_NO_ACTIVE_VIDPN"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY: - reason = "STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_NOT_CONNECTED: - reason = "STATUS_GRAPHICS_MONITOR_NOT_CONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY: - reason = "STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE: - reason = "STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE: - reason = "STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_STRIDE: - reason = "STATUS_GRAPHICS_INVALID_STRIDE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PIXELFORMAT: - reason = "STATUS_GRAPHICS_INVALID_PIXELFORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_COLORBASIS: - reason = "STATUS_GRAPHICS_INVALID_COLORBASIS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE: - reason = "STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY: - reason = "STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT: - reason = "STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE: - reason = "STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN: - reason = "STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL: - reason = "STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION: - reason = "STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_GAMMA_RAMP: - reason = "STATUS_GRAPHICS_INVALID_GAMMA_RAMP"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MODE_NOT_IN_MODESET: - reason = "STATUS_GRAPHICS_MODE_NOT_IN_MODESET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON: - reason = "STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE: - reason = "STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE: - reason = "STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS: - reason = "STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING: - reason = "STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED: - reason = "STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS: - reason = "STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT: - reason = "STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM: - reason = "STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT: - reason = "STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED: - reason = "STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION: - reason = "STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_CLIENT_TYPE: - reason = "STATUS_GRAPHICS_INVALID_CLIENT_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET: - reason = "STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED: - reason = "STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER: - reason = "STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED: - reason = "STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED: - reason = "STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY: - reason = "STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED: - reason = "STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON: - reason = "STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE: - reason = "STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER: - reason = "STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED: - reason = "STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_OPM_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_COPP_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_COPP_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_UAB_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_UAB_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS: - reason = "STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST: - reason = "STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INTERNAL_ERROR: - reason = "STATUS_GRAPHICS_OPM_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_HANDLE: - reason = "STATUS_GRAPHICS_OPM_INVALID_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH: - reason = "STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED: - reason = "STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED: - reason = "STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PVP_HFS_FAILED: - reason = "STATUS_GRAPHICS_PVP_HFS_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_SRM: - reason = "STATUS_GRAPHICS_OPM_INVALID_SRM"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP: - reason = "STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP: - reason = "STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA: - reason = "STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET: - reason = "STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH: - reason = "STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE: - reason = "STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS: - reason = "STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS: - reason = "STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST: - reason = "STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR: - reason = "STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS: - reason = "STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST: - reason = "STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_I2C_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST: - reason = "STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA: - reason = "STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA: - reason = "STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_DATA: - reason = "STATUS_GRAPHICS_DDCCI_INVALID_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE: - reason = "STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING: - reason = "STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MCA_INTERNAL_ERROR: - reason = "STATUS_GRAPHICS_MCA_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND: - reason = "STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH: - reason = "STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM: - reason = "STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE: - reason = "STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS: - reason = "STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED: - reason = "STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME: - reason = "STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP: - reason = "STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED: - reason = "STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INVALID_POINTER: - reason = "STATUS_GRAPHICS_INVALID_POINTER"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE: - reason = "STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL: - reason = "STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_INTERNAL_ERROR: - reason = "STATUS_GRAPHICS_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS: - reason = "STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_LOCKED_VOLUME: - reason = "STATUS_FVE_LOCKED_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_ENCRYPTED: - reason = "STATUS_FVE_NOT_ENCRYPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_BAD_INFORMATION: - reason = "STATUS_FVE_BAD_INFORMATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_TOO_SMALL: - reason = "STATUS_FVE_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FAILED_WRONG_FS: - reason = "STATUS_FVE_FAILED_WRONG_FS"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_BAD_PARTITION_SIZE: - reason = "STATUS_FVE_BAD_PARTITION_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FS_NOT_EXTENDED: - reason = "STATUS_FVE_FS_NOT_EXTENDED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FS_MOUNTED: - reason = "STATUS_FVE_FS_MOUNTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NO_LICENSE: - reason = "STATUS_FVE_NO_LICENSE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_ACTION_NOT_ALLOWED: - reason = "STATUS_FVE_ACTION_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_BAD_DATA: - reason = "STATUS_FVE_BAD_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_NOT_BOUND: - reason = "STATUS_FVE_VOLUME_NOT_BOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_DATA_VOLUME: - reason = "STATUS_FVE_NOT_DATA_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_CONV_READ_ERROR: - reason = "STATUS_FVE_CONV_READ_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_CONV_WRITE_ERROR: - reason = "STATUS_FVE_CONV_WRITE_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_OVERLAPPED_UPDATE: - reason = "STATUS_FVE_OVERLAPPED_UPDATE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FAILED_SECTOR_SIZE: - reason = "STATUS_FVE_FAILED_SECTOR_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FAILED_AUTHENTICATION: - reason = "STATUS_FVE_FAILED_AUTHENTICATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_OS_VOLUME: - reason = "STATUS_FVE_NOT_OS_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_NOT_FOUND: - reason = "STATUS_FVE_KEYFILE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_INVALID: - reason = "STATUS_FVE_KEYFILE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_KEYFILE_NO_VMK: - reason = "STATUS_FVE_KEYFILE_NO_VMK"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_TPM_DISABLED: - reason = "STATUS_FVE_TPM_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO: - reason = "STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_TPM_INVALID_PCR: - reason = "STATUS_FVE_TPM_INVALID_PCR"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_TPM_NO_VMK: - reason = "STATUS_FVE_TPM_NO_VMK"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_PIN_INVALID: - reason = "STATUS_FVE_PIN_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_AUTH_INVALID_APPLICATION: - reason = "STATUS_FVE_AUTH_INVALID_APPLICATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_AUTH_INVALID_CONFIG: - reason = "STATUS_FVE_AUTH_INVALID_CONFIG"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_DEBUGGER_ENABLED: - reason = "STATUS_FVE_DEBUGGER_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_DRY_RUN_FAILED: - reason = "STATUS_FVE_DRY_RUN_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_BAD_METADATA_POINTER: - reason = "STATUS_FVE_BAD_METADATA_POINTER"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_OLD_METADATA_COPY: - reason = "STATUS_FVE_OLD_METADATA_COPY"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_REBOOT_REQUIRED: - reason = "STATUS_FVE_REBOOT_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_RAW_ACCESS: - reason = "STATUS_FVE_RAW_ACCESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_RAW_BLOCKED: - reason = "STATUS_FVE_RAW_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY: - reason = "STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_MOR_FAILED: - reason = "STATUS_FVE_MOR_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NO_FEATURE_LICENSE: - reason = "STATUS_FVE_NO_FEATURE_LICENSE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED: - reason = "STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_CONV_RECOVERY_FAILED: - reason = "STATUS_FVE_CONV_RECOVERY_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG: - reason = "STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_INVALID_DATUM_TYPE: - reason = "STATUS_FVE_INVALID_DATUM_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_TOO_SMALL: - reason = "STATUS_FVE_VOLUME_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_ENH_PIN_INVALID: - reason = "STATUS_FVE_ENH_PIN_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE: - reason = "STATUS_FVE_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_WIPE_NOT_ALLOWED_ON_TP_STORAGE: - reason = "STATUS_FVE_WIPE_NOT_ALLOWED_ON_TP_STORAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_ON_CSV_STACK: - reason = "STATUS_FVE_NOT_ALLOWED_ON_CSV_STACK"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_ON_CLUSTER: - reason = "STATUS_FVE_NOT_ALLOWED_ON_CLUSTER"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING: - reason = "STATUS_FVE_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_WIPE_CANCEL_NOT_APPLICABLE: - reason = "STATUS_FVE_WIPE_CANCEL_NOT_APPLICABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_EDRIVE_DRY_RUN_FAILED: - reason = "STATUS_FVE_EDRIVE_DRY_RUN_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_SECUREBOOT_DISABLED: - reason = "STATUS_FVE_SECUREBOOT_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_SECUREBOOT_CONFIG_CHANGE: - reason = "STATUS_FVE_SECUREBOOT_CONFIG_CHANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_DEVICE_LOCKEDOUT: - reason = "STATUS_FVE_DEVICE_LOCKEDOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT: - reason = "STATUS_FVE_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_NOT_DE_VOLUME: - reason = "STATUS_FVE_NOT_DE_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_PROTECTION_DISABLED: - reason = "STATUS_FVE_PROTECTION_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FVE_PROTECTION_CANNOT_BE_DISABLED: - reason = "STATUS_FVE_PROTECTION_CANNOT_BE_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CALLOUT_NOT_FOUND: - reason = "STATUS_FWP_CALLOUT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CONDITION_NOT_FOUND: - reason = "STATUS_FWP_CONDITION_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_FILTER_NOT_FOUND: - reason = "STATUS_FWP_FILTER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_LAYER_NOT_FOUND: - reason = "STATUS_FWP_LAYER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_NOT_FOUND: - reason = "STATUS_FWP_PROVIDER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND: - reason = "STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_SUBLAYER_NOT_FOUND: - reason = "STATUS_FWP_SUBLAYER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NOT_FOUND: - reason = "STATUS_FWP_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_ALREADY_EXISTS: - reason = "STATUS_FWP_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_IN_USE: - reason = "STATUS_FWP_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS: - reason = "STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_WRONG_SESSION: - reason = "STATUS_FWP_WRONG_SESSION"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NO_TXN_IN_PROGRESS: - reason = "STATUS_FWP_NO_TXN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TXN_IN_PROGRESS: - reason = "STATUS_FWP_TXN_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TXN_ABORTED: - reason = "STATUS_FWP_TXN_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_SESSION_ABORTED: - reason = "STATUS_FWP_SESSION_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_TXN: - reason = "STATUS_FWP_INCOMPATIBLE_TXN"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TIMEOUT: - reason = "STATUS_FWP_TIMEOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NET_EVENTS_DISABLED: - reason = "STATUS_FWP_NET_EVENTS_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_LAYER: - reason = "STATUS_FWP_INCOMPATIBLE_LAYER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_KM_CLIENTS_ONLY: - reason = "STATUS_FWP_KM_CLIENTS_ONLY"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_LIFETIME_MISMATCH: - reason = "STATUS_FWP_LIFETIME_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_BUILTIN_OBJECT: - reason = "STATUS_FWP_BUILTIN_OBJECT"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TOO_MANY_CALLOUTS: - reason = "STATUS_FWP_TOO_MANY_CALLOUTS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NOTIFICATION_DROPPED: - reason = "STATUS_FWP_NOTIFICATION_DROPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TRAFFIC_MISMATCH: - reason = "STATUS_FWP_TRAFFIC_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_SA_STATE: - reason = "STATUS_FWP_INCOMPATIBLE_SA_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NULL_POINTER: - reason = "STATUS_FWP_NULL_POINTER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_ENUMERATOR: - reason = "STATUS_FWP_INVALID_ENUMERATOR"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_FLAGS: - reason = "STATUS_FWP_INVALID_FLAGS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_NET_MASK: - reason = "STATUS_FWP_INVALID_NET_MASK"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_RANGE: - reason = "STATUS_FWP_INVALID_RANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_INTERVAL: - reason = "STATUS_FWP_INVALID_INTERVAL"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_ZERO_LENGTH_ARRAY: - reason = "STATUS_FWP_ZERO_LENGTH_ARRAY"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NULL_DISPLAY_NAME: - reason = "STATUS_FWP_NULL_DISPLAY_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_ACTION_TYPE: - reason = "STATUS_FWP_INVALID_ACTION_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_WEIGHT: - reason = "STATUS_FWP_INVALID_WEIGHT"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_MATCH_TYPE_MISMATCH: - reason = "STATUS_FWP_MATCH_TYPE_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TYPE_MISMATCH: - reason = "STATUS_FWP_TYPE_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_OUT_OF_BOUNDS: - reason = "STATUS_FWP_OUT_OF_BOUNDS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_RESERVED: - reason = "STATUS_FWP_RESERVED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_CONDITION: - reason = "STATUS_FWP_DUPLICATE_CONDITION"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_KEYMOD: - reason = "STATUS_FWP_DUPLICATE_KEYMOD"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER: - reason = "STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER: - reason = "STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER: - reason = "STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT: - reason = "STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_AUTH_METHOD: - reason = "STATUS_FWP_INCOMPATIBLE_AUTH_METHOD"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_DH_GROUP: - reason = "STATUS_FWP_INCOMPATIBLE_DH_GROUP"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_EM_NOT_SUPPORTED: - reason = "STATUS_FWP_EM_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_NEVER_MATCH: - reason = "STATUS_FWP_NEVER_MATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_PROVIDER_CONTEXT_MISMATCH: - reason = "STATUS_FWP_PROVIDER_CONTEXT_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_PARAMETER: - reason = "STATUS_FWP_INVALID_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TOO_MANY_SUBLAYERS: - reason = "STATUS_FWP_TOO_MANY_SUBLAYERS"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CALLOUT_NOTIFICATION_FAILED: - reason = "STATUS_FWP_CALLOUT_NOTIFICATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_AUTH_TRANSFORM: - reason = "STATUS_FWP_INVALID_AUTH_TRANSFORM"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_CIPHER_TRANSFORM: - reason = "STATUS_FWP_INVALID_CIPHER_TRANSFORM"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM: - reason = "STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_TRANSFORM_COMBINATION: - reason = "STATUS_FWP_INVALID_TRANSFORM_COMBINATION"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_DUPLICATE_AUTH_METHOD: - reason = "STATUS_FWP_DUPLICATE_AUTH_METHOD"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_TUNNEL_ENDPOINT: - reason = "STATUS_FWP_INVALID_TUNNEL_ENDPOINT"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_L2_DRIVER_NOT_READY: - reason = "STATUS_FWP_L2_DRIVER_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_KEY_DICTATOR_ALREADY_REGISTERED: - reason = "STATUS_FWP_KEY_DICTATOR_ALREADY_REGISTERED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_KEY_DICTATION_INVALID_KEYING_MATERIAL: - reason = "STATUS_FWP_KEY_DICTATION_INVALID_KEYING_MATERIAL"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CONNECTIONS_DISABLED: - reason = "STATUS_FWP_CONNECTIONS_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INVALID_DNS_NAME: - reason = "STATUS_FWP_INVALID_DNS_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_STILL_ON: - reason = "STATUS_FWP_STILL_ON"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_IKEEXT_NOT_RUNNING: - reason = "STATUS_FWP_IKEEXT_NOT_RUNNING"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_TCPIP_NOT_READY: - reason = "STATUS_FWP_TCPIP_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INJECT_HANDLE_CLOSING: - reason = "STATUS_FWP_INJECT_HANDLE_CLOSING"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_INJECT_HANDLE_STALE: - reason = "STATUS_FWP_INJECT_HANDLE_STALE"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_CANNOT_PEND: - reason = "STATUS_FWP_CANNOT_PEND"; - break; - case MD_NTSTATUS_WIN_STATUS_FWP_DROP_NOICMP: - reason = "STATUS_FWP_DROP_NOICMP"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_CLOSING: - reason = "STATUS_NDIS_CLOSING"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_BAD_VERSION: - reason = "STATUS_NDIS_BAD_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_BAD_CHARACTERISTICS: - reason = "STATUS_NDIS_BAD_CHARACTERISTICS"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_NOT_FOUND: - reason = "STATUS_NDIS_ADAPTER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_OPEN_FAILED: - reason = "STATUS_NDIS_OPEN_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_DEVICE_FAILED: - reason = "STATUS_NDIS_DEVICE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_FULL: - reason = "STATUS_NDIS_MULTICAST_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_EXISTS: - reason = "STATUS_NDIS_MULTICAST_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_MULTICAST_NOT_FOUND: - reason = "STATUS_NDIS_MULTICAST_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_REQUEST_ABORTED: - reason = "STATUS_NDIS_REQUEST_ABORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_RESET_IN_PROGRESS: - reason = "STATUS_NDIS_RESET_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PACKET: - reason = "STATUS_NDIS_INVALID_PACKET"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_DEVICE_REQUEST: - reason = "STATUS_NDIS_INVALID_DEVICE_REQUEST"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_NOT_READY: - reason = "STATUS_NDIS_ADAPTER_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_LENGTH: - reason = "STATUS_NDIS_INVALID_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_DATA: - reason = "STATUS_NDIS_INVALID_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_BUFFER_TOO_SHORT: - reason = "STATUS_NDIS_BUFFER_TOO_SHORT"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_OID: - reason = "STATUS_NDIS_INVALID_OID"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_ADAPTER_REMOVED: - reason = "STATUS_NDIS_ADAPTER_REMOVED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_UNSUPPORTED_MEDIA: - reason = "STATUS_NDIS_UNSUPPORTED_MEDIA"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_GROUP_ADDRESS_IN_USE: - reason = "STATUS_NDIS_GROUP_ADDRESS_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_FILE_NOT_FOUND: - reason = "STATUS_NDIS_FILE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_ERROR_READING_FILE: - reason = "STATUS_NDIS_ERROR_READING_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_ALREADY_MAPPED: - reason = "STATUS_NDIS_ALREADY_MAPPED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_RESOURCE_CONFLICT: - reason = "STATUS_NDIS_RESOURCE_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_MEDIA_DISCONNECTED: - reason = "STATUS_NDIS_MEDIA_DISCONNECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_ADDRESS: - reason = "STATUS_NDIS_INVALID_ADDRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_PAUSED: - reason = "STATUS_NDIS_PAUSED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INTERFACE_NOT_FOUND: - reason = "STATUS_NDIS_INTERFACE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_UNSUPPORTED_REVISION: - reason = "STATUS_NDIS_UNSUPPORTED_REVISION"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PORT: - reason = "STATUS_NDIS_INVALID_PORT"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_INVALID_PORT_STATE: - reason = "STATUS_NDIS_INVALID_PORT_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_LOW_POWER_STATE: - reason = "STATUS_NDIS_LOW_POWER_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_REINIT_REQUIRED: - reason = "STATUS_NDIS_REINIT_REQUIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_NOT_SUPPORTED: - reason = "STATUS_NDIS_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_POLICY: - reason = "STATUS_NDIS_OFFLOAD_POLICY"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED: - reason = "STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_OFFLOAD_PATH_REJECTED: - reason = "STATUS_NDIS_OFFLOAD_PATH_REJECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED: - reason = "STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_MEDIA_IN_USE: - reason = "STATUS_NDIS_DOT11_MEDIA_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_DOT11_POWER_STATE_INVALID: - reason = "STATUS_NDIS_DOT11_POWER_STATE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL: - reason = "STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL: - reason = "STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_ERROR_MASK: - reason = "STATUS_TPM_ERROR_MASK"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUTHFAIL: - reason = "STATUS_TPM_AUTHFAIL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BADINDEX: - reason = "STATUS_TPM_BADINDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_PARAMETER: - reason = "STATUS_TPM_BAD_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAILURE: - reason = "STATUS_TPM_AUDITFAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_CLEAR_DISABLED: - reason = "STATUS_TPM_CLEAR_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DEACTIVATED: - reason = "STATUS_TPM_DEACTIVATED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DISABLED: - reason = "STATUS_TPM_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DISABLED_CMD: - reason = "STATUS_TPM_DISABLED_CMD"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_FAIL: - reason = "STATUS_TPM_FAIL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_ORDINAL: - reason = "STATUS_TPM_BAD_ORDINAL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INSTALL_DISABLED: - reason = "STATUS_TPM_INSTALL_DISABLED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_KEYHANDLE: - reason = "STATUS_TPM_INVALID_KEYHANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_KEYNOTFOUND: - reason = "STATUS_TPM_KEYNOTFOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INAPPROPRIATE_ENC: - reason = "STATUS_TPM_INAPPROPRIATE_ENC"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MIGRATEFAIL: - reason = "STATUS_TPM_MIGRATEFAIL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_PCR_INFO: - reason = "STATUS_TPM_INVALID_PCR_INFO"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOSPACE: - reason = "STATUS_TPM_NOSPACE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOSRK: - reason = "STATUS_TPM_NOSRK"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOTSEALED_BLOB: - reason = "STATUS_TPM_NOTSEALED_BLOB"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_OWNER_SET: - reason = "STATUS_TPM_OWNER_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_RESOURCES: - reason = "STATUS_TPM_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_SHORTRANDOM: - reason = "STATUS_TPM_SHORTRANDOM"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_SIZE: - reason = "STATUS_TPM_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_WRONGPCRVAL: - reason = "STATUS_TPM_WRONGPCRVAL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_PARAM_SIZE: - reason = "STATUS_TPM_BAD_PARAM_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_SHA_THREAD: - reason = "STATUS_TPM_SHA_THREAD"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_SHA_ERROR: - reason = "STATUS_TPM_SHA_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_FAILEDSELFTEST: - reason = "STATUS_TPM_FAILEDSELFTEST"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUTH2FAIL: - reason = "STATUS_TPM_AUTH2FAIL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BADTAG: - reason = "STATUS_TPM_BADTAG"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_IOERROR: - reason = "STATUS_TPM_IOERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_ENCRYPT_ERROR: - reason = "STATUS_TPM_ENCRYPT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DECRYPT_ERROR: - reason = "STATUS_TPM_DECRYPT_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_AUTHHANDLE: - reason = "STATUS_TPM_INVALID_AUTHHANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NO_ENDORSEMENT: - reason = "STATUS_TPM_NO_ENDORSEMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_KEYUSAGE: - reason = "STATUS_TPM_INVALID_KEYUSAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_WRONG_ENTITYTYPE: - reason = "STATUS_TPM_WRONG_ENTITYTYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_POSTINIT: - reason = "STATUS_TPM_INVALID_POSTINIT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INAPPROPRIATE_SIG: - reason = "STATUS_TPM_INAPPROPRIATE_SIG"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_KEY_PROPERTY: - reason = "STATUS_TPM_BAD_KEY_PROPERTY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_MIGRATION: - reason = "STATUS_TPM_BAD_MIGRATION"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_SCHEME: - reason = "STATUS_TPM_BAD_SCHEME"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_DATASIZE: - reason = "STATUS_TPM_BAD_DATASIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_MODE: - reason = "STATUS_TPM_BAD_MODE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_PRESENCE: - reason = "STATUS_TPM_BAD_PRESENCE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_VERSION: - reason = "STATUS_TPM_BAD_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NO_WRAP_TRANSPORT: - reason = "STATUS_TPM_NO_WRAP_TRANSPORT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAIL_UNSUCCESSFUL: - reason = "STATUS_TPM_AUDITFAIL_UNSUCCESSFUL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUDITFAIL_SUCCESSFUL: - reason = "STATUS_TPM_AUDITFAIL_SUCCESSFUL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOTRESETABLE: - reason = "STATUS_TPM_NOTRESETABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOTLOCAL: - reason = "STATUS_TPM_NOTLOCAL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_TYPE: - reason = "STATUS_TPM_BAD_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_RESOURCE: - reason = "STATUS_TPM_INVALID_RESOURCE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOTFIPS: - reason = "STATUS_TPM_NOTFIPS"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_FAMILY: - reason = "STATUS_TPM_INVALID_FAMILY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NO_NV_PERMISSION: - reason = "STATUS_TPM_NO_NV_PERMISSION"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_REQUIRES_SIGN: - reason = "STATUS_TPM_REQUIRES_SIGN"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_KEY_NOTSUPPORTED: - reason = "STATUS_TPM_KEY_NOTSUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AUTH_CONFLICT: - reason = "STATUS_TPM_AUTH_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_AREA_LOCKED: - reason = "STATUS_TPM_AREA_LOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_LOCALITY: - reason = "STATUS_TPM_BAD_LOCALITY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_READ_ONLY: - reason = "STATUS_TPM_READ_ONLY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_PER_NOWRITE: - reason = "STATUS_TPM_PER_NOWRITE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_FAMILYCOUNT: - reason = "STATUS_TPM_FAMILYCOUNT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_WRITE_LOCKED: - reason = "STATUS_TPM_WRITE_LOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_ATTRIBUTES: - reason = "STATUS_TPM_BAD_ATTRIBUTES"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_STRUCTURE: - reason = "STATUS_TPM_INVALID_STRUCTURE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_KEY_OWNER_CONTROL: - reason = "STATUS_TPM_KEY_OWNER_CONTROL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_COUNTER: - reason = "STATUS_TPM_BAD_COUNTER"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOT_FULLWRITE: - reason = "STATUS_TPM_NOT_FULLWRITE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_CONTEXT_GAP: - reason = "STATUS_TPM_CONTEXT_GAP"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MAXNVWRITES: - reason = "STATUS_TPM_MAXNVWRITES"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOOPERATOR: - reason = "STATUS_TPM_NOOPERATOR"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_RESOURCEMISSING: - reason = "STATUS_TPM_RESOURCEMISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_LOCK: - reason = "STATUS_TPM_DELEGATE_LOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_FAMILY: - reason = "STATUS_TPM_DELEGATE_FAMILY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DELEGATE_ADMIN: - reason = "STATUS_TPM_DELEGATE_ADMIN"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_TRANSPORT_NOTEXCLUSIVE: - reason = "STATUS_TPM_TRANSPORT_NOTEXCLUSIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_OWNER_CONTROL: - reason = "STATUS_TPM_OWNER_CONTROL"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_RESOURCES: - reason = "STATUS_TPM_DAA_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_INPUT_DATA0: - reason = "STATUS_TPM_DAA_INPUT_DATA0"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_INPUT_DATA1: - reason = "STATUS_TPM_DAA_INPUT_DATA1"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_ISSUER_SETTINGS: - reason = "STATUS_TPM_DAA_ISSUER_SETTINGS"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_TPM_SETTINGS: - reason = "STATUS_TPM_DAA_TPM_SETTINGS"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_STAGE: - reason = "STATUS_TPM_DAA_STAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_ISSUER_VALIDITY: - reason = "STATUS_TPM_DAA_ISSUER_VALIDITY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DAA_WRONG_W: - reason = "STATUS_TPM_DAA_WRONG_W"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_HANDLE: - reason = "STATUS_TPM_BAD_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_DELEGATE: - reason = "STATUS_TPM_BAD_DELEGATE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BADCONTEXT: - reason = "STATUS_TPM_BADCONTEXT"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_TOOMANYCONTEXTS: - reason = "STATUS_TPM_TOOMANYCONTEXTS"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MA_TICKET_SIGNATURE: - reason = "STATUS_TPM_MA_TICKET_SIGNATURE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MA_DESTINATION: - reason = "STATUS_TPM_MA_DESTINATION"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MA_SOURCE: - reason = "STATUS_TPM_MA_SOURCE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_MA_AUTHORITY: - reason = "STATUS_TPM_MA_AUTHORITY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_PERMANENTEK: - reason = "STATUS_TPM_PERMANENTEK"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_BAD_SIGNATURE: - reason = "STATUS_TPM_BAD_SIGNATURE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOCONTEXTSPACE: - reason = "STATUS_TPM_NOCONTEXTSPACE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_COMMAND_BLOCKED: - reason = "STATUS_TPM_COMMAND_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INVALID_HANDLE: - reason = "STATUS_TPM_INVALID_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DUPLICATE_VHANDLE: - reason = "STATUS_TPM_DUPLICATE_VHANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_EMBEDDED_COMMAND_BLOCKED: - reason = "STATUS_TPM_EMBEDDED_COMMAND_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_EMBEDDED_COMMAND_UNSUPPORTED: - reason = "STATUS_TPM_EMBEDDED_COMMAND_UNSUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_RETRY: - reason = "STATUS_TPM_RETRY"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NEEDS_SELFTEST: - reason = "STATUS_TPM_NEEDS_SELFTEST"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DOING_SELFTEST: - reason = "STATUS_TPM_DOING_SELFTEST"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_DEFEND_LOCK_RUNNING: - reason = "STATUS_TPM_DEFEND_LOCK_RUNNING"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_COMMAND_CANCELED: - reason = "STATUS_TPM_COMMAND_CANCELED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_TOO_MANY_CONTEXTS: - reason = "STATUS_TPM_TOO_MANY_CONTEXTS"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_NOT_FOUND: - reason = "STATUS_TPM_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_ACCESS_DENIED: - reason = "STATUS_TPM_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_INSUFFICIENT_BUFFER: - reason = "STATUS_TPM_INSUFFICIENT_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_TPM_PPI_FUNCTION_UNSUPPORTED: - reason = "STATUS_TPM_PPI_FUNCTION_UNSUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_ERROR_MASK: - reason = "STATUS_PCP_ERROR_MASK"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_DEVICE_NOT_READY: - reason = "STATUS_PCP_DEVICE_NOT_READY"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_INVALID_HANDLE: - reason = "STATUS_PCP_INVALID_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_INVALID_PARAMETER: - reason = "STATUS_PCP_INVALID_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_FLAG_NOT_SUPPORTED: - reason = "STATUS_PCP_FLAG_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_NOT_SUPPORTED: - reason = "STATUS_PCP_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_BUFFER_TOO_SMALL: - reason = "STATUS_PCP_BUFFER_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_INTERNAL_ERROR: - reason = "STATUS_PCP_INTERNAL_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_AUTHENTICATION_FAILED: - reason = "STATUS_PCP_AUTHENTICATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_AUTHENTICATION_IGNORED: - reason = "STATUS_PCP_AUTHENTICATION_IGNORED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_POLICY_NOT_FOUND: - reason = "STATUS_PCP_POLICY_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_PROFILE_NOT_FOUND: - reason = "STATUS_PCP_PROFILE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_VALIDATION_FAILED: - reason = "STATUS_PCP_VALIDATION_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_PCP_DEVICE_NOT_FOUND: - reason = "STATUS_PCP_DEVICE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_HYPERCALL_CODE: - reason = "STATUS_HV_INVALID_HYPERCALL_CODE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_HYPERCALL_INPUT: - reason = "STATUS_HV_INVALID_HYPERCALL_INPUT"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_ALIGNMENT: - reason = "STATUS_HV_INVALID_ALIGNMENT"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARAMETER: - reason = "STATUS_HV_INVALID_PARAMETER"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_ACCESS_DENIED: - reason = "STATUS_HV_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARTITION_STATE: - reason = "STATUS_HV_INVALID_PARTITION_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_OPERATION_DENIED: - reason = "STATUS_HV_OPERATION_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_UNKNOWN_PROPERTY: - reason = "STATUS_HV_UNKNOWN_PROPERTY"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE: - reason = "STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_MEMORY: - reason = "STATUS_HV_INSUFFICIENT_MEMORY"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_PARTITION_TOO_DEEP: - reason = "STATUS_HV_PARTITION_TOO_DEEP"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_PARTITION_ID: - reason = "STATUS_HV_INVALID_PARTITION_ID"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_VP_INDEX: - reason = "STATUS_HV_INVALID_VP_INDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_PORT_ID: - reason = "STATUS_HV_INVALID_PORT_ID"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_CONNECTION_ID: - reason = "STATUS_HV_INVALID_CONNECTION_ID"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_BUFFERS: - reason = "STATUS_HV_INSUFFICIENT_BUFFERS"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_NOT_ACKNOWLEDGED: - reason = "STATUS_HV_NOT_ACKNOWLEDGED"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_ACKNOWLEDGED: - reason = "STATUS_HV_ACKNOWLEDGED"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_SAVE_RESTORE_STATE: - reason = "STATUS_HV_INVALID_SAVE_RESTORE_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_SYNIC_STATE: - reason = "STATUS_HV_INVALID_SYNIC_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_OBJECT_IN_USE: - reason = "STATUS_HV_OBJECT_IN_USE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO: - reason = "STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_NO_DATA: - reason = "STATUS_HV_NO_DATA"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INACTIVE: - reason = "STATUS_HV_INACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_NO_RESOURCES: - reason = "STATUS_HV_NO_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_FEATURE_UNAVAILABLE: - reason = "STATUS_HV_FEATURE_UNAVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_BUFFER: - reason = "STATUS_HV_INSUFFICIENT_BUFFER"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INSUFFICIENT_DEVICE_DOMAINS: - reason = "STATUS_HV_INSUFFICIENT_DEVICE_DOMAINS"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_INVALID_LP_INDEX: - reason = "STATUS_HV_INVALID_LP_INDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_HV_NOT_PRESENT: - reason = "STATUS_HV_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_BAD_SPI: - reason = "STATUS_IPSEC_BAD_SPI"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_SA_LIFETIME_EXPIRED: - reason = "STATUS_IPSEC_SA_LIFETIME_EXPIRED"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_WRONG_SA: - reason = "STATUS_IPSEC_WRONG_SA"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_REPLAY_CHECK_FAILED: - reason = "STATUS_IPSEC_REPLAY_CHECK_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_INVALID_PACKET: - reason = "STATUS_IPSEC_INVALID_PACKET"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_INTEGRITY_CHECK_FAILED: - reason = "STATUS_IPSEC_INTEGRITY_CHECK_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_CLEAR_TEXT_DROP: - reason = "STATUS_IPSEC_CLEAR_TEXT_DROP"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_AUTH_FIREWALL_DROP: - reason = "STATUS_IPSEC_AUTH_FIREWALL_DROP"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_THROTTLE_DROP: - reason = "STATUS_IPSEC_THROTTLE_DROP"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_BLOCK: - reason = "STATUS_IPSEC_DOSP_BLOCK"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_RECEIVED_MULTICAST: - reason = "STATUS_IPSEC_DOSP_RECEIVED_MULTICAST"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_INVALID_PACKET: - reason = "STATUS_IPSEC_DOSP_INVALID_PACKET"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED: - reason = "STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_MAX_ENTRIES: - reason = "STATUS_IPSEC_DOSP_MAX_ENTRIES"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED: - reason = "STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED"; - break; - case MD_NTSTATUS_WIN_STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES: - reason = "STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_DUPLICATE_HANDLER: - reason = "STATUS_VID_DUPLICATE_HANDLER"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_TOO_MANY_HANDLERS: - reason = "STATUS_VID_TOO_MANY_HANDLERS"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_QUEUE_FULL: - reason = "STATUS_VID_QUEUE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_HANDLER_NOT_PRESENT: - reason = "STATUS_VID_HANDLER_NOT_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_OBJECT_NAME: - reason = "STATUS_VID_INVALID_OBJECT_NAME"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_PARTITION_NAME_TOO_LONG: - reason = "STATUS_VID_PARTITION_NAME_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG: - reason = "STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_PARTITION_ALREADY_EXISTS: - reason = "STATUS_VID_PARTITION_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_PARTITION_DOES_NOT_EXIST: - reason = "STATUS_VID_PARTITION_DOES_NOT_EXIST"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_PARTITION_NAME_NOT_FOUND: - reason = "STATUS_VID_PARTITION_NAME_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS: - reason = "STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT: - reason = "STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MB_STILL_REFERENCED: - reason = "STATUS_VID_MB_STILL_REFERENCED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED: - reason = "STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_NUMA_SETTINGS: - reason = "STATUS_VID_INVALID_NUMA_SETTINGS"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_NUMA_NODE_INDEX: - reason = "STATUS_VID_INVALID_NUMA_NODE_INDEX"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED: - reason = "STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE: - reason = "STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_PAGE_RANGE_OVERFLOW: - reason = "STATUS_VID_PAGE_RANGE_OVERFLOW"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE: - reason = "STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_GPA_RANGE_HANDLE: - reason = "STATUS_VID_INVALID_GPA_RANGE_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE: - reason = "STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED: - reason = "STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_PPM_HANDLE: - reason = "STATUS_VID_INVALID_PPM_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MBPS_ARE_LOCKED: - reason = "STATUS_VID_MBPS_ARE_LOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MESSAGE_QUEUE_CLOSED: - reason = "STATUS_VID_MESSAGE_QUEUE_CLOSED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED: - reason = "STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_STOP_PENDING: - reason = "STATUS_VID_STOP_PENDING"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_PROCESSOR_STATE: - reason = "STATUS_VID_INVALID_PROCESSOR_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT: - reason = "STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED: - reason = "STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET: - reason = "STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MMIO_RANGE_DESTROYED: - reason = "STATUS_VID_MMIO_RANGE_DESTROYED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_INVALID_CHILD_GPA_PAGE_SET: - reason = "STATUS_VID_INVALID_CHILD_GPA_PAGE_SET"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED: - reason = "STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL: - reason = "STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE: - reason = "STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT: - reason = "STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_CORRUPT: - reason = "STATUS_VID_SAVED_STATE_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM: - reason = "STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM"; - break; - case MD_NTSTATUS_WIN_STATUS_VID_SAVED_STATE_INCOMPATIBLE: - reason = "STATUS_VID_SAVED_STATE_INCOMPATIBLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DATABASE_FULL: - reason = "STATUS_VOLMGR_DATABASE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED: - reason = "STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC: - reason = "STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED: - reason = "STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME: - reason = "STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_DUPLICATE: - reason = "STATUS_VOLMGR_DISK_DUPLICATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_DYNAMIC: - reason = "STATUS_VOLMGR_DISK_DYNAMIC"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_ID_INVALID: - reason = "STATUS_VOLMGR_DISK_ID_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_INVALID: - reason = "STATUS_VOLMGR_DISK_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAST_VOTER: - reason = "STATUS_VOLMGR_DISK_LAST_VOTER"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_INVALID: - reason = "STATUS_VOLMGR_DISK_LAYOUT_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS: - reason = "STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED: - reason = "STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL: - reason = "STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS: - reason = "STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS: - reason = "STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_MISSING: - reason = "STATUS_VOLMGR_DISK_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_NOT_EMPTY: - reason = "STATUS_VOLMGR_DISK_NOT_EMPTY"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE: - reason = "STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_REVECTORING_FAILED: - reason = "STATUS_VOLMGR_DISK_REVECTORING_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID: - reason = "STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_SET_NOT_CONTAINED: - reason = "STATUS_VOLMGR_DISK_SET_NOT_CONTAINED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS: - reason = "STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES: - reason = "STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED: - reason = "STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_ALREADY_USED: - reason = "STATUS_VOLMGR_EXTENT_ALREADY_USED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS: - reason = "STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION: - reason = "STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED: - reason = "STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION: - reason = "STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH: - reason = "STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED: - reason = "STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID: - reason = "STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS: - reason = "STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_IN_SYNC: - reason = "STATUS_VOLMGR_MEMBER_IN_SYNC"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE: - reason = "STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_INDEX_INVALID: - reason = "STATUS_VOLMGR_MEMBER_INDEX_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_MISSING: - reason = "STATUS_VOLMGR_MEMBER_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_NOT_DETACHED: - reason = "STATUS_VOLMGR_MEMBER_NOT_DETACHED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MEMBER_REGENERATING: - reason = "STATUS_VOLMGR_MEMBER_REGENERATING"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_ALL_DISKS_FAILED: - reason = "STATUS_VOLMGR_ALL_DISKS_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_REGISTERED_USERS: - reason = "STATUS_VOLMGR_NO_REGISTERED_USERS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_SUCH_USER: - reason = "STATUS_VOLMGR_NO_SUCH_USER"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NOTIFICATION_RESET: - reason = "STATUS_VOLMGR_NOTIFICATION_RESET"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_DUPLICATE: - reason = "STATUS_VOLMGR_PACK_DUPLICATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_ID_INVALID: - reason = "STATUS_VOLMGR_PACK_ID_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_INVALID: - reason = "STATUS_VOLMGR_PACK_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_NAME_INVALID: - reason = "STATUS_VOLMGR_PACK_NAME_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_OFFLINE: - reason = "STATUS_VOLMGR_PACK_OFFLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_HAS_QUORUM: - reason = "STATUS_VOLMGR_PACK_HAS_QUORUM"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_WITHOUT_QUORUM: - reason = "STATUS_VOLMGR_PACK_WITHOUT_QUORUM"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PARTITION_STYLE_INVALID: - reason = "STATUS_VOLMGR_PARTITION_STYLE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PARTITION_UPDATE_FAILED: - reason = "STATUS_VOLMGR_PARTITION_UPDATE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_IN_SYNC: - reason = "STATUS_VOLMGR_PLEX_IN_SYNC"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_INDEX_DUPLICATE: - reason = "STATUS_VOLMGR_PLEX_INDEX_DUPLICATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_INDEX_INVALID: - reason = "STATUS_VOLMGR_PLEX_INDEX_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_LAST_ACTIVE: - reason = "STATUS_VOLMGR_PLEX_LAST_ACTIVE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_MISSING: - reason = "STATUS_VOLMGR_PLEX_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_REGENERATING: - reason = "STATUS_VOLMGR_PLEX_REGENERATING"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_TYPE_INVALID: - reason = "STATUS_VOLMGR_PLEX_TYPE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_RAID5: - reason = "STATUS_VOLMGR_PLEX_NOT_RAID5"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_SIMPLE: - reason = "STATUS_VOLMGR_PLEX_NOT_SIMPLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_STRUCTURE_SIZE_INVALID: - reason = "STATUS_VOLMGR_STRUCTURE_SIZE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS: - reason = "STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_TRANSACTION_IN_PROGRESS: - reason = "STATUS_VOLMGR_TRANSACTION_IN_PROGRESS"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE: - reason = "STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK: - reason = "STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_ID_INVALID: - reason = "STATUS_VOLMGR_VOLUME_ID_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_LENGTH_INVALID: - reason = "STATUS_VOLMGR_VOLUME_LENGTH_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE: - reason = "STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_NOT_MIRRORED: - reason = "STATUS_VOLMGR_VOLUME_NOT_MIRRORED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_NOT_RETAINED: - reason = "STATUS_VOLMGR_VOLUME_NOT_RETAINED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_OFFLINE: - reason = "STATUS_VOLMGR_VOLUME_OFFLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_RETAINED: - reason = "STATUS_VOLMGR_VOLUME_RETAINED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE: - reason = "STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_BAD_BOOT_DISK: - reason = "STATUS_VOLMGR_BAD_BOOT_DISK"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_OFFLINE: - reason = "STATUS_VOLMGR_PACK_CONFIG_OFFLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_CONFIG_ONLINE: - reason = "STATUS_VOLMGR_PACK_CONFIG_ONLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NOT_PRIMARY_PACK: - reason = "STATUS_VOLMGR_NOT_PRIMARY_PACK"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED: - reason = "STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_VOLUME_MIRRORED: - reason = "STATUS_VOLMGR_VOLUME_MIRRORED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED: - reason = "STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NO_VALID_LOG_COPIES: - reason = "STATUS_VOLMGR_NO_VALID_LOG_COPIES"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_PRIMARY_PACK_PRESENT: - reason = "STATUS_VOLMGR_PRIMARY_PACK_PRESENT"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID: - reason = "STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_MIRROR_NOT_SUPPORTED: - reason = "STATUS_VOLMGR_MIRROR_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLMGR_RAID5_NOT_SUPPORTED: - reason = "STATUS_VOLMGR_RAID5_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_BCD_TOO_MANY_ELEMENTS: - reason = "STATUS_BCD_TOO_MANY_ELEMENTS"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_MISSING: - reason = "STATUS_VHD_DRIVE_FOOTER_MISSING"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH: - reason = "STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_DRIVE_FOOTER_CORRUPT: - reason = "STATUS_VHD_DRIVE_FOOTER_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_FORMAT_UNKNOWN: - reason = "STATUS_VHD_FORMAT_UNKNOWN"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_FORMAT_UNSUPPORTED_VERSION: - reason = "STATUS_VHD_FORMAT_UNSUPPORTED_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH: - reason = "STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION: - reason = "STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_SPARSE_HEADER_CORRUPT: - reason = "STATUS_VHD_SPARSE_HEADER_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_BLOCK_ALLOCATION_FAILURE: - reason = "STATUS_VHD_BLOCK_ALLOCATION_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT: - reason = "STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_INVALID_BLOCK_SIZE: - reason = "STATUS_VHD_INVALID_BLOCK_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_BITMAP_MISMATCH: - reason = "STATUS_VHD_BITMAP_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_PARENT_VHD_NOT_FOUND: - reason = "STATUS_VHD_PARENT_VHD_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_ID_MISMATCH: - reason = "STATUS_VHD_CHILD_PARENT_ID_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH: - reason = "STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_METADATA_READ_FAILURE: - reason = "STATUS_VHD_METADATA_READ_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_METADATA_WRITE_FAILURE: - reason = "STATUS_VHD_METADATA_WRITE_FAILURE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_INVALID_SIZE: - reason = "STATUS_VHD_INVALID_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_INVALID_FILE_SIZE: - reason = "STATUS_VHD_INVALID_FILE_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTDISK_PROVIDER_NOT_FOUND: - reason = "STATUS_VIRTDISK_PROVIDER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTDISK_NOT_VIRTUAL_DISK: - reason = "STATUS_VIRTDISK_NOT_VIRTUAL_DISK"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_PARENT_VHD_ACCESS_DENIED: - reason = "STATUS_VHD_PARENT_VHD_ACCESS_DENIED"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH: - reason = "STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED: - reason = "STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT: - reason = "STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTUAL_DISK_LIMITATION: - reason = "STATUS_VIRTUAL_DISK_LIMITATION"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_INVALID_TYPE: - reason = "STATUS_VHD_INVALID_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_INVALID_STATE: - reason = "STATUS_VHD_INVALID_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE: - reason = "STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTDISK_DISK_ALREADY_OWNED: - reason = "STATUS_VIRTDISK_DISK_ALREADY_OWNED"; - break; - case MD_NTSTATUS_WIN_STATUS_VIRTDISK_DISK_ONLINE_AND_WRITABLE: - reason = "STATUS_VIRTDISK_DISK_ONLINE_AND_WRITABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTLOG_TRACKING_NOT_INITIALIZED: - reason = "STATUS_CTLOG_TRACKING_NOT_INITIALIZED"; - break; - case MD_NTSTATUS_WIN_STATUS_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE: - reason = "STATUS_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTLOG_VHD_CHANGED_OFFLINE: - reason = "STATUS_CTLOG_VHD_CHANGED_OFFLINE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTLOG_INVALID_TRACKING_STATE: - reason = "STATUS_CTLOG_INVALID_TRACKING_STATE"; - break; - case MD_NTSTATUS_WIN_STATUS_CTLOG_INCONSISTENT_TRACKING_FILE: - reason = "STATUS_CTLOG_INCONSISTENT_TRACKING_FILE"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_METADATA_FULL: - reason = "STATUS_VHD_METADATA_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_KEY_NOT_FOUND: - reason = "STATUS_RKF_KEY_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_DUPLICATE_KEY: - reason = "STATUS_RKF_DUPLICATE_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_BLOB_FULL: - reason = "STATUS_RKF_BLOB_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_STORE_FULL: - reason = "STATUS_RKF_STORE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_FILE_BLOCKED: - reason = "STATUS_RKF_FILE_BLOCKED"; - break; - case MD_NTSTATUS_WIN_STATUS_RKF_ACTIVE_KEY: - reason = "STATUS_RKF_ACTIVE_KEY"; - break; - case MD_NTSTATUS_WIN_STATUS_RDBSS_RESTART_OPERATION: - reason = "STATUS_RDBSS_RESTART_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_RDBSS_CONTINUE_OPERATION: - reason = "STATUS_RDBSS_CONTINUE_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_RDBSS_POST_OPERATION: - reason = "STATUS_RDBSS_POST_OPERATION"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_HANDLE: - reason = "STATUS_BTH_ATT_INVALID_HANDLE"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_READ_NOT_PERMITTED: - reason = "STATUS_BTH_ATT_READ_NOT_PERMITTED"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_WRITE_NOT_PERMITTED: - reason = "STATUS_BTH_ATT_WRITE_NOT_PERMITTED"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_PDU: - reason = "STATUS_BTH_ATT_INVALID_PDU"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_AUTHENTICATION: - reason = "STATUS_BTH_ATT_INSUFFICIENT_AUTHENTICATION"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_REQUEST_NOT_SUPPORTED: - reason = "STATUS_BTH_ATT_REQUEST_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_OFFSET: - reason = "STATUS_BTH_ATT_INVALID_OFFSET"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_AUTHORIZATION: - reason = "STATUS_BTH_ATT_INSUFFICIENT_AUTHORIZATION"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_PREPARE_QUEUE_FULL: - reason = "STATUS_BTH_ATT_PREPARE_QUEUE_FULL"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_ATTRIBUTE_NOT_FOUND: - reason = "STATUS_BTH_ATT_ATTRIBUTE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_ATTRIBUTE_NOT_LONG: - reason = "STATUS_BTH_ATT_ATTRIBUTE_NOT_LONG"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE: - reason = "STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: - reason = "STATUS_BTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNLIKELY: - reason = "STATUS_BTH_ATT_UNLIKELY"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION: - reason = "STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNSUPPORTED_GROUP_TYPE: - reason = "STATUS_BTH_ATT_UNSUPPORTED_GROUP_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_INSUFFICIENT_RESOURCES: - reason = "STATUS_BTH_ATT_INSUFFICIENT_RESOURCES"; - break; - case MD_NTSTATUS_WIN_STATUS_BTH_ATT_UNKNOWN_ERROR: - reason = "STATUS_BTH_ATT_UNKNOWN_ERROR"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_ROLLBACK_DETECTED: - reason = "STATUS_SECUREBOOT_ROLLBACK_DETECTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_VIOLATION: - reason = "STATUS_SECUREBOOT_POLICY_VIOLATION"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_INVALID_POLICY: - reason = "STATUS_SECUREBOOT_INVALID_POLICY"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND: - reason = "STATUS_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_POLICY_NOT_SIGNED: - reason = "STATUS_SECUREBOOT_POLICY_NOT_SIGNED"; - break; - case MD_NTSTATUS_WIN_STATUS_SECUREBOOT_FILE_REPLACED: - reason = "STATUS_SECUREBOOT_FILE_REPLACED"; - break; - case MD_NTSTATUS_WIN_STATUS_AUDIO_ENGINE_NODE_NOT_FOUND: - reason = "STATUS_AUDIO_ENGINE_NODE_NOT_FOUND"; - break; - case MD_NTSTATUS_WIN_STATUS_HDAUDIO_EMPTY_CONNECTION_LIST: - reason = "STATUS_HDAUDIO_EMPTY_CONNECTION_LIST"; - break; - case MD_NTSTATUS_WIN_STATUS_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED: - reason = "STATUS_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED"; - break; - case MD_NTSTATUS_WIN_STATUS_HDAUDIO_NO_LOGICAL_DEVICES_CREATED: - reason = "STATUS_HDAUDIO_NO_LOGICAL_DEVICES_CREATED"; - break; - case MD_NTSTATUS_WIN_STATUS_HDAUDIO_NULL_LINKED_LIST_ENTRY: - reason = "STATUS_HDAUDIO_NULL_LINKED_LIST_ENTRY"; - break; - case MD_NTSTATUS_WIN_STATUS_VOLSNAP_BOOTFILE_NOT_VALID: - reason = "STATUS_VOLSNAP_BOOTFILE_NOT_VALID"; - break; - case MD_NTSTATUS_WIN_STATUS_IO_PREEMPTED: - reason = "STATUS_IO_PREEMPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_ERROR_STORED: - reason = "STATUS_SVHDX_ERROR_STORED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_ERROR_NOT_AVAILABLE: - reason = "STATUS_SVHDX_ERROR_NOT_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_AVAILABLE: - reason = "STATUS_SVHDX_UNIT_ATTENTION_AVAILABLE"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED: - reason = "STATUS_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED: - reason = "STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED: - reason = "STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED: - reason = "STATUS_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED: - reason = "STATUS_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_RESERVATION_CONFLICT: - reason = "STATUS_SVHDX_RESERVATION_CONFLICT"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_WRONG_FILE_TYPE: - reason = "STATUS_SVHDX_WRONG_FILE_TYPE"; - break; - case MD_NTSTATUS_WIN_STATUS_SVHDX_VERSION_MISMATCH: - reason = "STATUS_SVHDX_VERSION_MISMATCH"; - break; - case MD_NTSTATUS_WIN_STATUS_VHD_SHARED: - reason = "STATUS_VHD_SHARED"; - break; - case MD_NTSTATUS_WIN_STATUS_SPACES_RESILIENCY_TYPE_INVALID: - reason = "STATUS_SPACES_RESILIENCY_TYPE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_SPACES_DRIVE_SECTOR_SIZE_INVALID: - reason = "STATUS_SPACES_DRIVE_SECTOR_SIZE_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_SPACES_INTERLEAVE_LENGTH_INVALID: - reason = "STATUS_SPACES_INTERLEAVE_LENGTH_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_SPACES_NUMBER_OF_COLUMNS_INVALID: - reason = "STATUS_SPACES_NUMBER_OF_COLUMNS_INVALID"; - break; - case MD_NTSTATUS_WIN_STATUS_SPACES_NOT_ENOUGH_DRIVES: - reason = "STATUS_SPACES_NOT_ENOUGH_DRIVES"; - break; - default: { - char reason_string[11]; - snprintf(reason_string, sizeof(reason_string), "0x%08x", ntstatus); - reason = reason_string; - break; - } - } - return reason; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.h b/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.h deleted file mode 100644 index c05c91698..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2015 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ntstatus_reason_win.h: Windows NTSTATUS code to string. -// -// Provides a means to convert NTSTATUS codes to strings. -// -// Author: Ben Wagner - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_SYMBOLIC_CONSTANTS_WIN_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_SYMBOLIC_CONSTANTS_WIN_H_ - -#include - -#include "google_breakpad/common/breakpad_types.h" - -namespace google_breakpad { - -/* Converts a NTSTATUS code to a reason string. */ -std::string NTStatusToString(uint32_t ntstatus); - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_SYMBOLIC_CONSTANTS_WIN_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc deleted file mode 100644 index 2cfbb0888..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// synth_minidump.cc: Implementation of SynthMinidump. See synth_minidump.h - -#include "processor/synth_minidump.h" - -namespace google_breakpad { - -namespace SynthMinidump { - -Section::Section(const Dump &dump) - : test_assembler::Section(dump.endianness()) { } - -void Section::CiteLocationIn(test_assembler::Section *section) const { - if (this) - (*section).D32(size_).D32(file_offset_); - else - (*section).D32(0).D32(0); -} - -void Stream::CiteStreamIn(test_assembler::Section *section) const { - section->D32(type_); - CiteLocationIn(section); -} - -SystemInfo::SystemInfo(const Dump &dump, - const MDRawSystemInfo &system_info, - const String &csd_version) - : Stream(dump, MD_SYSTEM_INFO_STREAM) { - D16(system_info.processor_architecture); - D16(system_info.processor_level); - D16(system_info.processor_revision); - D8(system_info.number_of_processors); - D8(system_info.product_type); - D32(system_info.major_version); - D32(system_info.minor_version); - D32(system_info.build_number); - D32(system_info.platform_id); - csd_version.CiteStringIn(this); - D16(system_info.suite_mask); - D16(system_info.reserved2); // Well, why not? - - // MDCPUInformation cpu; - if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_X86) { - D32(system_info.cpu.x86_cpu_info.vendor_id[0]); - D32(system_info.cpu.x86_cpu_info.vendor_id[1]); - D32(system_info.cpu.x86_cpu_info.vendor_id[2]); - D32(system_info.cpu.x86_cpu_info.version_information); - D32(system_info.cpu.x86_cpu_info.feature_information); - D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features); - } else if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_ARM) { - D32(system_info.cpu.arm_cpu_info.cpuid); - D32(system_info.cpu.arm_cpu_info.elf_hwcaps); - } else { - D64(system_info.cpu.other_cpu_info.processor_features[0]); - D64(system_info.cpu.other_cpu_info.processor_features[1]); - } -} - -const MDRawSystemInfo SystemInfo::windows_x86 = { - MD_CPU_ARCHITECTURE_X86, // processor_architecture - 6, // processor_level - 0xd08, // processor_revision - 1, // number_of_processors - 1, // product_type - 5, // major_version - 1, // minor_version - 2600, // build_number - 2, // platform_id - 0xdeadbeef, // csd_version_rva - 0x100, // suite_mask - 0, // reserved2 - { // cpu - { // x86_cpu_info - { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id - 0x6d8, // version_information - 0xafe9fbff, // feature_information - 0xffffffff // amd_extended_cpu_features - } - } -}; - -const string SystemInfo::windows_x86_csd_version = "Service Pack 2"; - -String::String(const Dump &dump, const string &contents) : Section(dump) { - D32(contents.size() * 2); - for (string::const_iterator i = contents.begin(); i != contents.end(); i++) - D16(*i); -} - -void String::CiteStringIn(test_assembler::Section *section) const { - section->D32(file_offset_); -} - -void Memory::CiteMemoryIn(test_assembler::Section *section) const { - section->D64(address_); - CiteLocationIn(section); -} - -Context::Context(const Dump &dump, const MDRawContextX86 &context) - : Section(dump) { - // The caller should have properly set the CPU type flag. - // The high 24 bits identify the CPU. Note that context records with no CPU - // type information can be valid (e.g. produced by ::RtlCaptureContext). - assert(((context.context_flags & MD_CONTEXT_CPU_MASK) == 0) || - (context.context_flags & MD_CONTEXT_X86)); - // It doesn't make sense to store x86 registers in big-endian form. - assert(dump.endianness() == kLittleEndian); - D32(context.context_flags); - D32(context.dr0); - D32(context.dr1); - D32(context.dr2); - D32(context.dr3); - D32(context.dr6); - D32(context.dr7); - D32(context.float_save.control_word); - D32(context.float_save.status_word); - D32(context.float_save.tag_word); - D32(context.float_save.error_offset); - D32(context.float_save.error_selector); - D32(context.float_save.data_offset); - D32(context.float_save.data_selector); - // context.float_save.register_area[] contains 8-bit quantities and - // does not need to be swapped. - Append(context.float_save.register_area, - sizeof(context.float_save.register_area)); - D32(context.float_save.cr0_npx_state); - D32(context.gs); - D32(context.fs); - D32(context.es); - D32(context.ds); - D32(context.edi); - D32(context.esi); - D32(context.ebx); - D32(context.edx); - D32(context.ecx); - D32(context.eax); - D32(context.ebp); - D32(context.eip); - D32(context.cs); - D32(context.eflags); - D32(context.esp); - D32(context.ss); - // context.extended_registers[] contains 8-bit quantities and does - // not need to be swapped. - Append(context.extended_registers, sizeof(context.extended_registers)); - assert(Size() == sizeof(MDRawContextX86)); -} - -Context::Context(const Dump &dump, const MDRawContextARM &context) - : Section(dump) { - // The caller should have properly set the CPU type flag. - assert((context.context_flags & MD_CONTEXT_ARM) || - (context.context_flags & MD_CONTEXT_ARM_OLD)); - // It doesn't make sense to store ARM registers in big-endian form. - assert(dump.endianness() == kLittleEndian); - D32(context.context_flags); - for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i) - D32(context.iregs[i]); - D32(context.cpsr); - D64(context.float_save.fpscr); - for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; ++i) - D64(context.float_save.regs[i]); - for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; ++i) - D32(context.float_save.extra[i]); - assert(Size() == sizeof(MDRawContextARM)); -} - -Context::Context(const Dump &dump, const MDRawContextMIPS &context) - : Section(dump) { - // The caller should have properly set the CPU type flag. - assert(context.context_flags & MD_CONTEXT_MIPS); - D32(context.context_flags); - D32(context._pad0); - - for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i) - D64(context.iregs[i]); - - D64(context.mdhi); - D64(context.mdlo); - - for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i) - D32(context.hi[i]); - - for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i) - D32(context.lo[i]); - - D32(context.dsp_control); - D32(context._pad1); - - D64(context.epc); - D64(context.badvaddr); - D32(context.status); - D32(context.cause); - - for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) - D64(context.float_save.regs[i]); - - D32(context.float_save.fpcsr); - D32(context.float_save.fir); - - assert(Size() == sizeof(MDRawContextMIPS)); -} - -Thread::Thread(const Dump &dump, - uint32_t thread_id, const Memory &stack, const Context &context, - uint32_t suspend_count, uint32_t priority_class, - uint32_t priority, uint64_t teb) : Section(dump) { - D32(thread_id); - D32(suspend_count); - D32(priority_class); - D32(priority); - D64(teb); - stack.CiteMemoryIn(this); - context.CiteLocationIn(this); - assert(Size() == sizeof(MDRawThread)); -} - -Module::Module(const Dump &dump, - uint64_t base_of_image, - uint32_t size_of_image, - const String &name, - uint32_t time_date_stamp, - uint32_t checksum, - const MDVSFixedFileInfo &version_info, - const Section *cv_record, - const Section *misc_record) : Section(dump) { - D64(base_of_image); - D32(size_of_image); - D32(checksum); - D32(time_date_stamp); - name.CiteStringIn(this); - D32(version_info.signature); - D32(version_info.struct_version); - D32(version_info.file_version_hi); - D32(version_info.file_version_lo); - D32(version_info.product_version_hi); - D32(version_info.product_version_lo); - D32(version_info.file_flags_mask); - D32(version_info.file_flags); - D32(version_info.file_os); - D32(version_info.file_type); - D32(version_info.file_subtype); - D32(version_info.file_date_hi); - D32(version_info.file_date_lo); - cv_record->CiteLocationIn(this); - misc_record->CiteLocationIn(this); - D64(0).D64(0); -} - -const MDVSFixedFileInfo Module::stock_version_info = { - MD_VSFIXEDFILEINFO_SIGNATURE, // signature - MD_VSFIXEDFILEINFO_VERSION, // struct_version - 0x11111111, // file_version_hi - 0x22222222, // file_version_lo - 0x33333333, // product_version_hi - 0x44444444, // product_version_lo - MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags_mask - MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags - MD_VSFIXEDFILEINFO_FILE_OS_NT | MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32, - // file_os - MD_VSFIXEDFILEINFO_FILE_TYPE_APP, // file_type - MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype - 0, // file_date_hi - 0 // file_date_lo -}; - -Exception::Exception(const Dump &dump, - const Context &context, - uint32_t thread_id, - uint32_t exception_code, - uint32_t exception_flags, - uint64_t exception_address) - : Stream(dump, MD_EXCEPTION_STREAM) { - D32(thread_id); - D32(0); // __align - D32(exception_code); - D32(exception_flags); - D64(0); // exception_record - D64(exception_address); - D32(0); // number_parameters - D32(0); // __align - for (int i = 0; i < MD_EXCEPTION_MAXIMUM_PARAMETERS; ++i) - D64(0); // exception_information - context.CiteLocationIn(this); - assert(Size() == sizeof(MDRawExceptionStream)); -} - -Dump::Dump(uint64_t flags, - Endianness endianness, - uint32_t version, - uint32_t date_time_stamp) - : test_assembler::Section(endianness), - file_start_(0), - stream_directory_(*this), - stream_count_(0), - thread_list_(*this, MD_THREAD_LIST_STREAM), - module_list_(*this, MD_MODULE_LIST_STREAM), - memory_list_(*this, MD_MEMORY_LIST_STREAM) - { - D32(MD_HEADER_SIGNATURE); - D32(version); - D32(stream_count_label_); - D32(stream_directory_rva_); - D32(0); - D32(date_time_stamp); - D64(flags); - assert(Size() == sizeof(MDRawHeader)); -} - -Dump &Dump::Add(SynthMinidump::Section *section) { - section->Finish(file_start_ + Size()); - Append(*section); - return *this; -} - -Dump &Dump::Add(Stream *stream) { - Add(static_cast(stream)); - stream->CiteStreamIn(&stream_directory_); - stream_count_++; - return *this; -} - -Dump &Dump::Add(Memory *memory) { - // Add the memory contents themselves to the file. - Add(static_cast(memory)); - - // The memory list is a list of MDMemoryDescriptors, not of actual - // memory elements. Produce a descriptor, and add that to the list. - SynthMinidump::Section descriptor(*this); - memory->CiteMemoryIn(&descriptor); - memory_list_.Add(&descriptor); - return *this; -} - -Dump &Dump::Add(Thread *thread) { - thread_list_.Add(thread); - return *this; -} - -Dump &Dump::Add(Module *module) { - module_list_.Add(module); - return *this; -} - -void Dump::Finish() { - if (!thread_list_.Empty()) Add(&thread_list_); - if (!module_list_.Empty()) Add(&module_list_); - if (!memory_list_.Empty()) Add(&memory_list_); - - // Create the stream directory. We don't use - // stream_directory_.Finish here, because the stream directory isn't - // cited using a location descriptor; rather, the Minidump header - // has the stream count and MDRVA. - stream_count_label_ = stream_count_; - stream_directory_rva_ = file_start_ + Size(); - Append(static_cast(stream_directory_)); -} - -} // namespace SynthMinidump - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h deleted file mode 100644 index 8dac8784e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h +++ /dev/null @@ -1,372 +0,0 @@ -// -*- mode: C++ -*- - -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// synth_minidump.h: Interface to SynthMinidump: fake minidump generator. -// -// We treat a minidump file as the concatenation of a bunch of -// test_assembler::Sections. The file header, stream directory, -// streams, memory regions, strings, and so on --- each is a Section -// that eventually gets appended to the minidump. Dump, Memory, -// Context, Thread, and so on all inherit from test_assembler::Section. -// For example: -// -// using google_breakpad::test_assembler::kLittleEndian; -// using google_breakpad::SynthMinidump::Context; -// using google_breakpad::SynthMinidump::Dump; -// using google_breakpad::SynthMinidump::Memory; -// using google_breakpad::SynthMinidump::Thread; -// -// Dump minidump(MD_NORMAL, kLittleEndian); -// -// Memory stack1(minidump, 0x569eb0a9); -// ... build contents of stack1 with test_assembler::Section functions ... -// -// MDRawContextX86 x86_context1; -// x86_context1.context_flags = MD_CONTEXT_X86; -// x86_context1.eip = 0x7c90eb94; -// x86_context1.esp = 0x569eb0a9; -// x86_context1.ebp = x86_context1.esp + something appropriate; -// Context context1(minidump, x86_context1); -// -// Thread thread1(minidump, 0xe4a4821d, stack1, context1); -// -// minidump.Add(&stack1); -// minidump.Add(&context1); -// minidump.Add(&thread1); -// minidump.Finish(); -// -// string contents; -// EXPECT_TRUE(minidump.GetContents(&contents)); -// // contents now holds the bytes of a minidump file -// -// Because the test_assembler classes let us write Label references to -// sections before the Labels' values are known, this gives us -// flexibility in how we put the dump together: minidump pieces can -// hold the file offsets of other minidump pieces before the -// referents' positions have been decided. As long as everything has -// been placed by the time we call dump.GetContents to obtain the -// bytes, all the Labels' values will be known, and everything will -// get patched up appropriately. -// -// The dump.Add(thing) functions append THINGS's contents to the -// minidump, but they also do two other things: -// -// - dump.Add(thing) invokes thing->Finish, which tells *thing the -// offset within the file at which it was placed, and allows *thing -// to do any final content generation. -// -// - If THING is something which should receive an entry in some sort -// of list or directory, then dump.Add(THING) automatically creates -// the appropriate directory or list entry. Streams must appear in -// the stream directory; memory ranges should be listed in the -// memory list; threads should be placed in the thread list; and so -// on. -// -// By convention, Section subclass constructors that take references -// to other Sections do not take care of 'Add'ing their arguments to -// the dump. For example, although the Thread constructor takes -// references to a Memory and a Context, it does not add them to the -// dump on the caller's behalf. Rather, the caller is responsible for -// 'Add'ing every section they create. This allows Sections to be -// cited from more than one place; for example, Memory ranges are -// cited both from Thread objects (as their stack contents) and by the -// memory list stream. -// -// If you forget to Add some Section, the Dump::GetContents call will -// fail, as the test_assembler::Labels used to cite the Section's -// contents from elsewhere will still be undefined. -#ifndef PROCESSOR_SYNTH_MINIDUMP_H_ -#define PROCESSOR_SYNTH_MINIDUMP_H_ - -#include - -#include -#include - -#include "common/test_assembler.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -namespace SynthMinidump { - -using test_assembler::Endianness; -using test_assembler::kBigEndian; -using test_assembler::kLittleEndian; -using test_assembler::kUnsetEndian; -using test_assembler::Label; - -class Dump; -class Memory; -class String; - -// A test_assembler::Section which will be appended to a minidump. -class Section: public test_assembler::Section { - public: - explicit Section(const Dump &dump); - - // Append an MDLocationDescriptor referring to this section to SECTION. - // If 'this' is NULL, append a descriptor with a zero length and MDRVA. - // - // (I couldn't find the language in the C++ standard that says that - // invoking member functions of a NULL pointer to a class type is - // bad, if such language exists. Having this function handle NULL - // 'this' is convenient, but if it causes trouble, it's not hard to - // do differently.) - void CiteLocationIn(test_assembler::Section *section) const; - - // Note that this section's contents are complete, and that it has - // been placed in the minidump file at OFFSET. The 'Add' member - // functions call the Finish member function of the object being - // added for you; if you are 'Add'ing this section, you needn't Finish it. - virtual void Finish(const Label &offset) { - file_offset_ = offset; size_ = Size(); - } - - protected: - // This section's size and offset within the minidump file. - Label file_offset_, size_; -}; - -// A stream within a minidump file. 'Add'ing a stream to a minidump -// creates an entry for it in the minidump's stream directory. -class Stream: public Section { - public: - // Create a stream of type TYPE. You can append whatever contents - // you like to this stream using the test_assembler::Section methods. - Stream(const Dump &dump, uint32_t type) : Section(dump), type_(type) { } - - // Append an MDRawDirectory referring to this stream to SECTION. - void CiteStreamIn(test_assembler::Section *section) const; - - private: - // The type of this stream. - uint32_t type_; -}; - -class SystemInfo: public Stream { - public: - // Create an MD_SYSTEM_INFO_STREAM stream belonging to DUMP holding - // an MDRawSystem info structure initialized with the values from - // SYSTEM_INFO, except that the csd_version field is replaced with - // the file offset of the string CSD_VERSION, which can be 'Add'ed - // to the dump at the desired location. - // - // Remember that you are still responsible for 'Add'ing CSD_VERSION - // to the dump yourself. - SystemInfo(const Dump &dump, - const MDRawSystemInfo &system_info, - const String &csd_version); - - // Stock MDRawSystemInfo information and associated strings, for - // writing tests. - static const MDRawSystemInfo windows_x86; - static const string windows_x86_csd_version; -}; - -// An MDString: a string preceded by a 32-bit length. -class String: public Section { - public: - String(const Dump &dump, const string &value); - - // Append an MDRVA referring to this string to SECTION. - void CiteStringIn(test_assembler::Section *section) const; -}; - -// A range of memory contents. 'Add'ing a memory range to a minidump -// creates n entry for it in the minidump's memory list. By -// convention, the 'start', 'Here', and 'Mark' member functions refer -// to memory addresses. -class Memory: public Section { - public: - Memory(const Dump &dump, uint64_t address) - : Section(dump), address_(address) { start() = address; } - - // Append an MDMemoryDescriptor referring to this memory range to SECTION. - void CiteMemoryIn(test_assembler::Section *section) const; - - private: - // The process address from which these memory contents were taken. - // Shouldn't this be a Label? - uint64_t address_; -}; - -class Context: public Section { - public: - // Create a context belonging to DUMP whose contents are a copy of CONTEXT. - Context(const Dump &dump, const MDRawContextX86 &context); - Context(const Dump &dump, const MDRawContextARM &context); - Context(const Dump &dump, const MDRawContextMIPS &context); - // Add an empty context to the dump. - Context(const Dump &dump) : Section(dump) {} - // Add constructors for other architectures here. Remember to byteswap. -}; - -class Thread: public Section { - public: - // Create a thread belonging to DUMP with the given values, citing - // STACK and CONTEXT (which you must Add to the dump separately). - Thread(const Dump &dump, - uint32_t thread_id, - const Memory &stack, - const Context &context, - uint32_t suspend_count = 0, - uint32_t priority_class = 0, - uint32_t priority = 0, - uint64_t teb = 0); -}; - -class Module: public Section { - public: - // Create a module with the given values. Note that CV_RECORD and - // MISC_RECORD can be NULL, in which case the corresponding location - // descriptior in the minidump will have a length of zero. - Module(const Dump &dump, - uint64_t base_of_image, - uint32_t size_of_image, - const String &name, - uint32_t time_date_stamp = 1262805309, - uint32_t checksum = 0, - const MDVSFixedFileInfo &version_info = Module::stock_version_info, - const Section *cv_record = NULL, - const Section *misc_record = NULL); - - private: - // A standard MDVSFixedFileInfo structure to use as a default for - // minidumps. There's no reason to make users write out all this crap - // over and over. - static const MDVSFixedFileInfo stock_version_info; -}; - -class Exception : public Stream { -public: - Exception(const Dump &dump, - const Context &context, - uint32_t thread_id = 0, - uint32_t exception_code = 0, - uint32_t exception_flags = 0, - uint64_t exception_address = 0); -}; - -// A list of entries starting with a 32-bit count, like a memory list -// or a thread list. -template -class List: public Stream { - public: - List(const Dump &dump, uint32_t type) : Stream(dump, type), count_(0) { - D32(count_label_); - } - - // Add ELEMENT to this list. - void Add(Element *element) { - element->Finish(file_offset_ + Size()); - Append(*element); - count_++; - } - - // Return true if this List is empty, false otherwise. - bool Empty() { return count_ == 0; } - - // Finish up the contents of this section, mark it as having been - // placed at OFFSET. - virtual void Finish(const Label &offset) { - Stream::Finish(offset); - count_label_ = count_; - } - - private: - size_t count_; - Label count_label_; -}; - -class Dump: public test_assembler::Section { - public: - - // Create a test_assembler::Section containing a minidump file whose - // header uses the given values. ENDIANNESS determines the - // endianness of the signature; we set this section's default - // endianness by this. - Dump(uint64_t flags, - Endianness endianness = kLittleEndian, - uint32_t version = MD_HEADER_VERSION, - uint32_t date_time_stamp = 1262805309); - - // The following functions call OBJECT->Finish(), and append the - // contents of OBJECT to this minidump. They also record OBJECT in - // whatever directory or list is appropriate for its type. The - // stream directory, memory list, thread list, and module list are - // accumulated this way. - Dump &Add(SynthMinidump::Section *object); // simply append data - Dump &Add(Stream *object); // append, record in stream directory - Dump &Add(Memory *object); // append, record in memory list - Dump &Add(Thread *object); // append, record in thread list - Dump &Add(Module *object); // append, record in module list - - // Complete the construction of the minidump, given the Add calls - // we've seen up to this point. After this call, this Dump's - // contents are complete, all labels should be defined if everything - // Cited has been Added, and you may call GetContents on it. - void Finish(); - - private: - // A label representing the start of the minidump file. - Label file_start_; - - // The stream directory. We construct this incrementally from - // Add(Stream *) calls. - SynthMinidump::Section stream_directory_; // The directory's contents. - size_t stream_count_; // The number of streams so far. - Label stream_count_label_; // Cited in file header. - Label stream_directory_rva_; // The directory's file offset. - - // This minidump's thread list. We construct this incrementally from - // Add(Thread *) calls. - List thread_list_; - - // This minidump's module list. We construct this incrementally from - // Add(Module *) calls. - List module_list_; - - // This minidump's memory list. We construct this incrementally from - // Add(Memory *) calls. This is actually a list of MDMemoryDescriptors, - // not memory ranges --- thus the odd type. - List memory_list_; -}; - -} // namespace SynthMinidump - -} // namespace google_breakpad - -#endif // PROCESSOR_SYNTH_MINIDUMP_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc deleted file mode 100644 index 8835b4493..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump -// classes. - -#include -#include - -#include "breakpad_googletest_includes.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/minidump_format.h" -#include "processor/synth_minidump.h" -#include "processor/synth_minidump_unittest_data.h" - -using google_breakpad::SynthMinidump::Context; -using google_breakpad::SynthMinidump::Dump; -using google_breakpad::SynthMinidump::Exception; -using google_breakpad::SynthMinidump::List; -using google_breakpad::SynthMinidump::Memory; -using google_breakpad::SynthMinidump::Module; -using google_breakpad::SynthMinidump::Section; -using google_breakpad::SynthMinidump::Stream; -using google_breakpad::SynthMinidump::String; -using google_breakpad::SynthMinidump::SystemInfo; -using google_breakpad::test_assembler::kBigEndian; -using google_breakpad::test_assembler::kLittleEndian; -using google_breakpad::test_assembler::Label; - -TEST(Section, Simple) { - Dump dump(0); - Section section(dump); - section.L32(0x12345678); - section.Finish(0); - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("\x78\x56\x34\x12", 4), contents); -} - -TEST(Section, CiteLocationIn) { - Dump dump(0, kBigEndian); - Section section1(dump), section2(dump); - section1.Append("order"); - section2.Append("mayhem"); - section2.Finish(0x32287ec2); - section2.CiteLocationIn(§ion1); - string contents; - ASSERT_TRUE(section1.GetContents(&contents)); - string expected("order\0\0\0\x06\x32\x28\x7e\xc2", 13); - EXPECT_EQ(expected, contents); -} - -TEST(Stream, CiteStreamIn) { - Dump dump(0, kLittleEndian); - Stream stream(dump, 0x40cae2b3); - Section section(dump); - stream.Append("stream contents"); - section.Append("section contents"); - stream.Finish(0x41424344); - stream.CiteStreamIn(§ion); - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - string expected("section contents" - "\xb3\xe2\xca\x40" - "\x0f\0\0\0" - "\x44\x43\x42\x41", - 16 + 4 + 4 + 4); - EXPECT_EQ(expected, contents); -} - -TEST(Memory, CiteMemoryIn) { - Dump dump(0, kBigEndian); - Memory memory(dump, 0x76d010874ab019f9ULL); - Section section(dump); - memory.Append("memory contents"); - section.Append("section contents"); - memory.Finish(0x51525354); - memory.CiteMemoryIn(§ion); - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - string expected("section contents" - "\x76\xd0\x10\x87\x4a\xb0\x19\xf9" - "\0\0\0\x0f" - "\x51\x52\x53\x54", - 16 + 8 + 4 + 4); - EXPECT_EQ(contents, expected); -} - -TEST(Memory, Here) { - Dump dump(0, kBigEndian); - Memory memory(dump, 0x89979731eb060ed4ULL); - memory.Append(1729, 42); - Label l = memory.Here(); - ASSERT_EQ(0x89979731eb060ed4ULL + 1729, l.Value()); -} - -TEST(Context, X86) { - Dump dump(0, kLittleEndian); - assert(x86_raw_context.context_flags & MD_CONTEXT_X86); - Context context(dump, x86_raw_context); - string contents; - ASSERT_TRUE(context.GetContents(&contents)); - EXPECT_EQ(sizeof(x86_expected_contents), contents.size()); - EXPECT_TRUE(memcmp(contents.data(), x86_expected_contents, contents.size()) - == 0); -} - -TEST(Context, ARM) { - Dump dump(0, kLittleEndian); - assert(arm_raw_context.context_flags & MD_CONTEXT_ARM); - Context context(dump, arm_raw_context); - string contents; - ASSERT_TRUE(context.GetContents(&contents)); - EXPECT_EQ(sizeof(arm_expected_contents), contents.size()); - EXPECT_TRUE(memcmp(contents.data(), arm_expected_contents, contents.size()) - == 0); -} - -TEST(ContextDeathTest, X86BadFlags) { - Dump dump(0, kLittleEndian); - MDRawContextX86 raw; - raw.context_flags = MD_CONTEXT_AMD64; - ASSERT_DEATH(Context context(dump, raw);, - "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)"); -} - -TEST(ContextDeathTest, X86BadEndianness) { - Dump dump(0, kBigEndian); - MDRawContextX86 raw; - raw.context_flags = MD_CONTEXT_X86; - ASSERT_DEATH(Context context(dump, raw);, - "dump\\.endianness\\(\\) == kLittleEndian"); -} - -TEST(Thread, Simple) { - Dump dump(0, kLittleEndian); - Context context(dump, x86_raw_context); - context.Finish(0x8665da0c); - Memory stack(dump, 0xaad55a93cc3c0efcULL); - stack.Append("stack contents"); - stack.Finish(0xe08cdbd1); - google_breakpad::SynthMinidump::Thread thread( - dump, 0x3d7ec360, stack, context, - 0x3593f44d, // suspend count - 0xab352b82, // priority class - 0x2753d838, // priority - 0xeb2de4be3f29e3e9ULL); // thread environment block - string contents; - ASSERT_TRUE(thread.GetContents(&contents)); - static const uint8_t expected_bytes[] = { - 0x60, 0xc3, 0x7e, 0x3d, // thread id - 0x4d, 0xf4, 0x93, 0x35, // suspend count - 0x82, 0x2b, 0x35, 0xab, // priority class - 0x38, 0xd8, 0x53, 0x27, // priority - 0xe9, 0xe3, 0x29, 0x3f, 0xbe, 0xe4, 0x2d, 0xeb, // thread environment block - 0xfc, 0x0e, 0x3c, 0xcc, 0x93, 0x5a, 0xd5, 0xaa, // stack address - 0x0e, 0x00, 0x00, 0x00, // stack size - 0xd1, 0xdb, 0x8c, 0xe0, // stack MDRVA - 0xcc, 0x02, 0x00, 0x00, // context size - 0x0c, 0xda, 0x65, 0x86 // context MDRVA - }; - EXPECT_EQ(sizeof(expected_bytes), contents.size()); - EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); -} - -TEST(Exception, Simple) { - Dump dump(0, kLittleEndian); - Context context(dump, x86_raw_context); - context.Finish(0x8665da0c); - - Exception exception(dump, context, - 0x1234abcd, // thread id - 0xdcba4321, // exception code - 0xf0e0d0c0, // exception flags - 0x0919a9b9c9d9e9f9ULL); // exception address - string contents; - ASSERT_TRUE(exception.GetContents(&contents)); - static const uint8_t expected_bytes[] = { - 0xcd, 0xab, 0x34, 0x12, // thread id - 0x00, 0x00, 0x00, 0x00, // __align - 0x21, 0x43, 0xba, 0xdc, // exception code - 0xc0, 0xd0, 0xe0, 0xf0, // exception flags - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception record - 0xf9, 0xe9, 0xd9, 0xc9, 0xb9, 0xa9, 0x19, 0x09, // exception address - 0x00, 0x00, 0x00, 0x00, // number parameters - 0x00, 0x00, 0x00, 0x00, // __align - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information - 0xcc, 0x02, 0x00, 0x00, // context size - 0x0c, 0xda, 0x65, 0x86 // context MDRVA - }; - EXPECT_EQ(sizeof(expected_bytes), contents.size()); - EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); -} - -TEST(String, Simple) { - Dump dump(0, kBigEndian); - String s(dump, "All mimsy were the borogoves"); - string contents; - ASSERT_TRUE(s.GetContents(&contents)); - static const char expected[] = - "\x00\x00\x00\x38\0A\0l\0l\0 \0m\0i\0m\0s\0y\0 \0w\0e\0r\0e" - "\0 \0t\0h\0e\0 \0b\0o\0r\0o\0g\0o\0v\0e\0s"; - string expected_string(expected, sizeof(expected) - 1); - EXPECT_EQ(expected_string, contents); -} - -TEST(String, CiteStringIn) { - Dump dump(0, kLittleEndian); - String s(dump, "and the mome wraths outgrabe"); - Section section(dump); - section.Append("initial"); - s.CiteStringIn(§ion); - s.Finish(0xdc2bb469); - string contents; - ASSERT_TRUE(section.GetContents(&contents)); - EXPECT_EQ(string("initial\x69\xb4\x2b\xdc", 7 + 4), contents); -} - -TEST(List, Empty) { - Dump dump(0, kBigEndian); - List
list(dump, 0x2442779c); - EXPECT_TRUE(list.Empty()); - list.Finish(0x84e09808); - string contents; - ASSERT_TRUE(list.GetContents(&contents)); - EXPECT_EQ(string("\0\0\0\0", 4), contents); -} - -TEST(List, Two) { - Dump dump(0, kBigEndian); - List
list(dump, 0x26c9f498); - Section section1(dump); - section1.Append("section one contents"); - EXPECT_TRUE(list.Empty()); - list.Add(§ion1); - EXPECT_FALSE(list.Empty()); - Section section2(dump); - section2.Append("section two contents"); - list.Add(§ion2); - list.Finish(0x1e5bb60e); - string contents; - ASSERT_TRUE(list.GetContents(&contents)); - EXPECT_EQ(string("\0\0\0\x02section one contentssection two contents", 44), - contents); -} - -TEST(Dump, Header) { - Dump dump(0x9f738b33685cc84cULL, kLittleEndian, 0xb3817faf, 0x2c741c0a); - dump.Finish(); - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - ASSERT_EQ(string("\x4d\x44\x4d\x50" // signature - "\xaf\x7f\x81\xb3" // version - "\0\0\0\0" // stream count - "\x20\0\0\0" // directory RVA (could be anything) - "\0\0\0\0" // checksum - "\x0a\x1c\x74\x2c" // time_date_stamp - "\x4c\xc8\x5c\x68\x33\x8b\x73\x9f", // flags - 32), - contents); -} - -TEST(Dump, HeaderBigEndian) { - Dump dump(0x206ce3cc6fb8e0f0ULL, kBigEndian, 0x161693e2, 0x35667744); - dump.Finish(); - string contents; - ASSERT_TRUE(dump.GetContents(&contents)); - ASSERT_EQ(string("\x50\x4d\x44\x4d" // signature - "\x16\x16\x93\xe2" // version - "\0\0\0\0" // stream count - "\0\0\0\x20" // directory RVA (could be anything) - "\0\0\0\0" // checksum - "\x35\x66\x77\x44" // time_date_stamp - "\x20\x6c\xe3\xcc\x6f\xb8\xe0\xf0", // flags - 32), - contents); -} - -TEST(Dump, OneSection) { - Dump dump(0, kLittleEndian); - Section section(dump); - section.Append("section contents"); - dump.Add(§ion); - dump.Finish(); - string dump_contents; - // Just check for undefined labels; don't worry about the contents. - ASSERT_TRUE(dump.GetContents(&dump_contents)); - - Section referencing_section(dump); - section.CiteLocationIn(&referencing_section); - string contents; - ASSERT_TRUE(referencing_section.GetContents(&contents)); - ASSERT_EQ(string("\x10\0\0\0\x20\0\0\0", 8), contents); -} diff --git a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h deleted file mode 100644 index 3403372e6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h +++ /dev/null @@ -1,418 +0,0 @@ -// -*- mode: C++ -*- - -// Not copyrightable: random test data. -// synth_minidump_unittest_data.h: verbose test data for SynthMinidump tests. - -#ifndef PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_ -#define PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_ - -#include "google_breakpad/common/minidump_format.h" - -static const MDRawContextX86 x86_raw_context = { - 0xded5d71b, // context_flags - 0x9fdb432e, // dr0 - 0x26b7a81a, // dr1 - 0xcac7e348, // dr2 - 0xcf99ec09, // dr3 - 0x7dc8c2cd, // dr6 - 0x21deb880, // dr7 - - // float_save - { - 0x8a5d2bb0, // control_word - 0x0286c4c9, // status_word - 0xf1feea21, // tag_word - 0xb2d40576, // error_offset - 0x48146cde, // error_selector - 0x983f9b21, // data_offset - 0x475be12c, // data_selector - - // register_area - { - 0xd9, 0x04, 0x20, 0x6b, 0x88, 0x3a, 0x3f, 0xd5, - 0x59, 0x7a, 0xa9, 0xeb, 0xd0, 0x5c, 0xdf, 0xfe, - 0xad, 0xdd, 0x4a, 0x8b, 0x10, 0xcc, 0x9a, 0x33, - 0xcb, 0xb6, 0xf7, 0x86, 0xcd, 0x69, 0x25, 0xae, - 0x25, 0xe5, 0x7a, 0xa1, 0x8f, 0xb2, 0x84, 0xd9, - 0xf7, 0x2d, 0x8a, 0xa1, 0x80, 0x81, 0x7f, 0x67, - 0x07, 0xa8, 0x23, 0xf1, 0x8c, 0xdc, 0xd8, 0x04, - 0x8b, 0x9d, 0xb1, 0xcd, 0x61, 0x0c, 0x9c, 0x69, - 0xc7, 0x8d, 0x17, 0xb6, 0xe5, 0x0b, 0x94, 0xf7, - 0x78, 0x9b, 0x63, 0x49, 0xba, 0xfc, 0x08, 0x4d - }, - - 0x84c53a90, // cr0_npx_state - }, - - 0x79f71e76, // gs - 0x8107bd25, // fs - 0x452d2921, // es - 0x87ec2875, // ds - 0xf8bb73f5, // edi - 0xa63ebb88, // esi - 0x95d35ebe, // ebx - 0x17aa2456, // edx - 0x135fa208, // ecx - 0x500615e6, // eax - 0x66d14205, // ebp - 0x000719a5, // eip - 0x477b481b, // cs - 0x8684dfba, // eflags - 0xe33ccddf, // esp - 0xc0e65d33, // ss - - // extended_registers - { - 0x68, 0x63, 0xdf, 0x50, 0xf7, 0x3b, 0xe8, 0xe5, - 0xcb, 0xd6, 0x66, 0x60, 0xe5, 0xa3, 0x58, 0xb3, - 0x6f, 0x34, 0xca, 0x02, 0x9b, 0x5f, 0xd0, 0x41, - 0xbd, 0xc5, 0x2d, 0xf8, 0xff, 0x15, 0xa2, 0xd0, - 0xe3, 0x2b, 0x3b, 0x8a, 0x9f, 0xc3, 0x9e, 0x28, - 0x0a, 0xc2, 0xac, 0x3b, 0x67, 0x37, 0x01, 0xfd, - 0xc3, 0xaf, 0x60, 0xf6, 0x2c, 0x4f, 0xa9, 0x52, - 0x92, 0xe5, 0x28, 0xde, 0x34, 0xb6, 0x2e, 0x44, - 0x15, 0xa4, 0xb6, 0xe4, 0xc9, 0x1a, 0x14, 0xb9, - 0x51, 0x33, 0x3c, 0xe0, 0xc7, 0x94, 0xf0, 0xf7, - 0x78, 0xdd, 0xe5, 0xca, 0xb7, 0xa6, 0xe0, 0x14, - 0xa6, 0x03, 0xab, 0x77, 0xad, 0xbd, 0xd2, 0x53, - 0x3d, 0x07, 0xe7, 0xaf, 0x90, 0x44, 0x71, 0xbe, - 0x0c, 0xdf, 0x2b, 0x97, 0x40, 0x48, 0xd5, 0xf9, - 0x62, 0x03, 0x91, 0x84, 0xd6, 0xdd, 0x29, 0x97, - 0x35, 0x02, 0xfb, 0x59, 0x97, 0xb0, 0xec, 0xa9, - 0x39, 0x6f, 0x81, 0x71, 0x2a, 0xf0, 0xe7, 0x2c, - 0x4e, 0x93, 0x90, 0xcb, 0x67, 0x69, 0xde, 0xd7, - 0x68, 0x3b, 0x0f, 0x69, 0xa8, 0xf4, 0xa8, 0x83, - 0x42, 0x80, 0x47, 0x65, 0x7a, 0xc9, 0x19, 0x5d, - 0xcb, 0x43, 0xa5, 0xff, 0xf8, 0x9e, 0x62, 0xf4, - 0xe2, 0x6c, 0xcc, 0x17, 0x55, 0x7c, 0x0d, 0x5c, - 0x8d, 0x16, 0x01, 0xd7, 0x3a, 0x0c, 0xf4, 0x7f, - 0x71, 0xdc, 0x48, 0xe9, 0x4b, 0xfe, 0x1a, 0xd0, - 0x04, 0x15, 0x33, 0xec, 0x78, 0xc6, 0x7e, 0xde, - 0x7c, 0x23, 0x18, 0x8d, 0x8f, 0xc2, 0x74, 0xc1, - 0x48, 0xcd, 0x5d, 0xee, 0xee, 0x81, 0x9e, 0x49, - 0x47, 0x8a, 0xf8, 0x61, 0xa3, 0x9c, 0x81, 0x96, - 0xbe, 0x2b, 0x5e, 0xbc, 0xcd, 0x34, 0x0a, 0x2a, - 0x3b, 0x8b, 0x7d, 0xa1, 0xf2, 0x8d, 0xb4, 0x51, - 0x9e, 0x14, 0x78, 0xa3, 0x58, 0x65, 0x2d, 0xd6, - 0x50, 0x40, 0x36, 0x32, 0x31, 0xd4, 0x3e, 0xc2, - 0xe0, 0x87, 0x1c, 0x05, 0x95, 0x80, 0x84, 0x24, - 0x08, 0x6f, 0x5b, 0xc7, 0xe1, 0x1d, 0xd5, 0xa3, - 0x94, 0x44, 0xa1, 0x7c, 0xd8, 0x4b, 0x86, 0xd2, - 0xc6, 0xa9, 0xf3, 0xe2, 0x4d, 0x6e, 0x1f, 0x0e, - 0xf2, 0xf5, 0x71, 0xf9, 0x71, 0x05, 0x24, 0xc9, - 0xc1, 0xe8, 0x91, 0x42, 0x61, 0x86, 0x57, 0x68, - 0xd9, 0xc9, 0x1d, 0xd5, 0x5a, 0xe9, 0xba, 0xe6, - 0x15, 0x8f, 0x87, 0xbd, 0x62, 0x56, 0xed, 0xda, - 0xc2, 0xa5, 0xd5, 0x39, 0xac, 0x05, 0x10, 0x14, - 0x4a, 0xe7, 0xe7, 0x3c, 0x3f, 0xb7, 0xbb, 0xed, - 0x01, 0x6e, 0xcd, 0xee, 0x81, 0xb4, 0x62, 0xf4, - 0x62, 0x16, 0xff, 0x20, 0xb4, 0xf0, 0xbc, 0xff, - 0x7d, 0xd9, 0xcf, 0x95, 0x30, 0x27, 0xe0, 0x2f, - 0x98, 0x53, 0x80, 0x15, 0x13, 0xef, 0x44, 0x58, - 0x12, 0x16, 0xdb, 0x11, 0xef, 0x73, 0x51, 0xcd, - 0x42, 0x3f, 0x98, 0x6c, 0xc9, 0x68, 0xc3, 0xf4, - 0x5b, 0x0f, 0x5d, 0x77, 0xed, 0xdf, 0x0f, 0xff, - 0xb8, 0x69, 0x98, 0x50, 0x77, 0x7a, 0xe8, 0x90, - 0x27, 0x46, 0x10, 0xd2, 0xb5, 0x00, 0x3b, 0x36, - 0x43, 0x6d, 0x67, 0x41, 0x20, 0x3a, 0x32, 0xe0, - 0x2e, 0x5a, 0xfb, 0x4e, 0x4f, 0xa4, 0xf7, 0xc2, - 0xe6, 0x81, 0x1a, 0x51, 0xa8, 0x7c, 0xd4, 0x60, - 0x7c, 0x45, 0xe2, 0xba, 0x5b, 0x42, 0xf3, 0xbf, - 0x28, 0xaa, 0xf2, 0x90, 0xe4, 0x94, 0xdd, 0xaa, - 0x22, 0xd3, 0x71, 0x33, 0xa1, 0x01, 0x43, 0x0e, - 0xfa, 0x46, 0xd2, 0x6e, 0x55, 0x5e, 0x49, 0xeb, - 0x94, 0xf0, 0xb0, 0xb1, 0x2e, 0xf2, 0x3d, 0x6c, - 0x00, 0x5e, 0x01, 0x56, 0x3b, 0xfd, 0x5b, 0xa1, - 0x2f, 0x63, 0x1d, 0xbf, 0xf9, 0xd8, 0x13, 0xf7, - 0x4d, 0xb7, 0x1e, 0x3d, 0x98, 0xd2, 0xee, 0xb8, - 0x48, 0xc8, 0x5b, 0x91, 0x0f, 0x54, 0x9e, 0x26, - 0xb2, 0xc7, 0x3a, 0x6c, 0x8a, 0x35, 0xe1, 0xba - } -}; - -static const uint8_t x86_expected_contents[] = { - 0x1b, 0xd7, 0xd5, 0xde, - 0x2e, 0x43, 0xdb, 0x9f, - 0x1a, 0xa8, 0xb7, 0x26, - 0x48, 0xe3, 0xc7, 0xca, - 0x09, 0xec, 0x99, 0xcf, - 0xcd, 0xc2, 0xc8, 0x7d, - 0x80, 0xb8, 0xde, 0x21, - 0xb0, 0x2b, 0x5d, 0x8a, - 0xc9, 0xc4, 0x86, 0x02, - 0x21, 0xea, 0xfe, 0xf1, - 0x76, 0x05, 0xd4, 0xb2, - 0xde, 0x6c, 0x14, 0x48, - 0x21, 0x9b, 0x3f, 0x98, - 0x2c, 0xe1, 0x5b, 0x47, - - // float_save.register_area --- unswapped - 0xd9, 0x04, 0x20, 0x6b, 0x88, 0x3a, 0x3f, 0xd5, - 0x59, 0x7a, 0xa9, 0xeb, 0xd0, 0x5c, 0xdf, 0xfe, - 0xad, 0xdd, 0x4a, 0x8b, 0x10, 0xcc, 0x9a, 0x33, - 0xcb, 0xb6, 0xf7, 0x86, 0xcd, 0x69, 0x25, 0xae, - 0x25, 0xe5, 0x7a, 0xa1, 0x8f, 0xb2, 0x84, 0xd9, - 0xf7, 0x2d, 0x8a, 0xa1, 0x80, 0x81, 0x7f, 0x67, - 0x07, 0xa8, 0x23, 0xf1, 0x8c, 0xdc, 0xd8, 0x04, - 0x8b, 0x9d, 0xb1, 0xcd, 0x61, 0x0c, 0x9c, 0x69, - 0xc7, 0x8d, 0x17, 0xb6, 0xe5, 0x0b, 0x94, 0xf7, - 0x78, 0x9b, 0x63, 0x49, 0xba, 0xfc, 0x08, 0x4d, - - 0x90, 0x3a, 0xc5, 0x84, - 0x76, 0x1e, 0xf7, 0x79, - 0x25, 0xbd, 0x07, 0x81, - 0x21, 0x29, 0x2d, 0x45, - 0x75, 0x28, 0xec, 0x87, - 0xf5, 0x73, 0xbb, 0xf8, - 0x88, 0xbb, 0x3e, 0xa6, - 0xbe, 0x5e, 0xd3, 0x95, - 0x56, 0x24, 0xaa, 0x17, - 0x08, 0xa2, 0x5f, 0x13, - 0xe6, 0x15, 0x06, 0x50, - 0x05, 0x42, 0xd1, 0x66, - 0xa5, 0x19, 0x07, 0x00, - 0x1b, 0x48, 0x7b, 0x47, - 0xba, 0xdf, 0x84, 0x86, - 0xdf, 0xcd, 0x3c, 0xe3, - 0x33, 0x5d, 0xe6, 0xc0, - - // extended_registers --- unswapped - 0x68, 0x63, 0xdf, 0x50, 0xf7, 0x3b, 0xe8, 0xe5, - 0xcb, 0xd6, 0x66, 0x60, 0xe5, 0xa3, 0x58, 0xb3, - 0x6f, 0x34, 0xca, 0x02, 0x9b, 0x5f, 0xd0, 0x41, - 0xbd, 0xc5, 0x2d, 0xf8, 0xff, 0x15, 0xa2, 0xd0, - 0xe3, 0x2b, 0x3b, 0x8a, 0x9f, 0xc3, 0x9e, 0x28, - 0x0a, 0xc2, 0xac, 0x3b, 0x67, 0x37, 0x01, 0xfd, - 0xc3, 0xaf, 0x60, 0xf6, 0x2c, 0x4f, 0xa9, 0x52, - 0x92, 0xe5, 0x28, 0xde, 0x34, 0xb6, 0x2e, 0x44, - 0x15, 0xa4, 0xb6, 0xe4, 0xc9, 0x1a, 0x14, 0xb9, - 0x51, 0x33, 0x3c, 0xe0, 0xc7, 0x94, 0xf0, 0xf7, - 0x78, 0xdd, 0xe5, 0xca, 0xb7, 0xa6, 0xe0, 0x14, - 0xa6, 0x03, 0xab, 0x77, 0xad, 0xbd, 0xd2, 0x53, - 0x3d, 0x07, 0xe7, 0xaf, 0x90, 0x44, 0x71, 0xbe, - 0x0c, 0xdf, 0x2b, 0x97, 0x40, 0x48, 0xd5, 0xf9, - 0x62, 0x03, 0x91, 0x84, 0xd6, 0xdd, 0x29, 0x97, - 0x35, 0x02, 0xfb, 0x59, 0x97, 0xb0, 0xec, 0xa9, - 0x39, 0x6f, 0x81, 0x71, 0x2a, 0xf0, 0xe7, 0x2c, - 0x4e, 0x93, 0x90, 0xcb, 0x67, 0x69, 0xde, 0xd7, - 0x68, 0x3b, 0x0f, 0x69, 0xa8, 0xf4, 0xa8, 0x83, - 0x42, 0x80, 0x47, 0x65, 0x7a, 0xc9, 0x19, 0x5d, - 0xcb, 0x43, 0xa5, 0xff, 0xf8, 0x9e, 0x62, 0xf4, - 0xe2, 0x6c, 0xcc, 0x17, 0x55, 0x7c, 0x0d, 0x5c, - 0x8d, 0x16, 0x01, 0xd7, 0x3a, 0x0c, 0xf4, 0x7f, - 0x71, 0xdc, 0x48, 0xe9, 0x4b, 0xfe, 0x1a, 0xd0, - 0x04, 0x15, 0x33, 0xec, 0x78, 0xc6, 0x7e, 0xde, - 0x7c, 0x23, 0x18, 0x8d, 0x8f, 0xc2, 0x74, 0xc1, - 0x48, 0xcd, 0x5d, 0xee, 0xee, 0x81, 0x9e, 0x49, - 0x47, 0x8a, 0xf8, 0x61, 0xa3, 0x9c, 0x81, 0x96, - 0xbe, 0x2b, 0x5e, 0xbc, 0xcd, 0x34, 0x0a, 0x2a, - 0x3b, 0x8b, 0x7d, 0xa1, 0xf2, 0x8d, 0xb4, 0x51, - 0x9e, 0x14, 0x78, 0xa3, 0x58, 0x65, 0x2d, 0xd6, - 0x50, 0x40, 0x36, 0x32, 0x31, 0xd4, 0x3e, 0xc2, - 0xe0, 0x87, 0x1c, 0x05, 0x95, 0x80, 0x84, 0x24, - 0x08, 0x6f, 0x5b, 0xc7, 0xe1, 0x1d, 0xd5, 0xa3, - 0x94, 0x44, 0xa1, 0x7c, 0xd8, 0x4b, 0x86, 0xd2, - 0xc6, 0xa9, 0xf3, 0xe2, 0x4d, 0x6e, 0x1f, 0x0e, - 0xf2, 0xf5, 0x71, 0xf9, 0x71, 0x05, 0x24, 0xc9, - 0xc1, 0xe8, 0x91, 0x42, 0x61, 0x86, 0x57, 0x68, - 0xd9, 0xc9, 0x1d, 0xd5, 0x5a, 0xe9, 0xba, 0xe6, - 0x15, 0x8f, 0x87, 0xbd, 0x62, 0x56, 0xed, 0xda, - 0xc2, 0xa5, 0xd5, 0x39, 0xac, 0x05, 0x10, 0x14, - 0x4a, 0xe7, 0xe7, 0x3c, 0x3f, 0xb7, 0xbb, 0xed, - 0x01, 0x6e, 0xcd, 0xee, 0x81, 0xb4, 0x62, 0xf4, - 0x62, 0x16, 0xff, 0x20, 0xb4, 0xf0, 0xbc, 0xff, - 0x7d, 0xd9, 0xcf, 0x95, 0x30, 0x27, 0xe0, 0x2f, - 0x98, 0x53, 0x80, 0x15, 0x13, 0xef, 0x44, 0x58, - 0x12, 0x16, 0xdb, 0x11, 0xef, 0x73, 0x51, 0xcd, - 0x42, 0x3f, 0x98, 0x6c, 0xc9, 0x68, 0xc3, 0xf4, - 0x5b, 0x0f, 0x5d, 0x77, 0xed, 0xdf, 0x0f, 0xff, - 0xb8, 0x69, 0x98, 0x50, 0x77, 0x7a, 0xe8, 0x90, - 0x27, 0x46, 0x10, 0xd2, 0xb5, 0x00, 0x3b, 0x36, - 0x43, 0x6d, 0x67, 0x41, 0x20, 0x3a, 0x32, 0xe0, - 0x2e, 0x5a, 0xfb, 0x4e, 0x4f, 0xa4, 0xf7, 0xc2, - 0xe6, 0x81, 0x1a, 0x51, 0xa8, 0x7c, 0xd4, 0x60, - 0x7c, 0x45, 0xe2, 0xba, 0x5b, 0x42, 0xf3, 0xbf, - 0x28, 0xaa, 0xf2, 0x90, 0xe4, 0x94, 0xdd, 0xaa, - 0x22, 0xd3, 0x71, 0x33, 0xa1, 0x01, 0x43, 0x0e, - 0xfa, 0x46, 0xd2, 0x6e, 0x55, 0x5e, 0x49, 0xeb, - 0x94, 0xf0, 0xb0, 0xb1, 0x2e, 0xf2, 0x3d, 0x6c, - 0x00, 0x5e, 0x01, 0x56, 0x3b, 0xfd, 0x5b, 0xa1, - 0x2f, 0x63, 0x1d, 0xbf, 0xf9, 0xd8, 0x13, 0xf7, - 0x4d, 0xb7, 0x1e, 0x3d, 0x98, 0xd2, 0xee, 0xb8, - 0x48, 0xc8, 0x5b, 0x91, 0x0f, 0x54, 0x9e, 0x26, - 0xb2, 0xc7, 0x3a, 0x6c, 0x8a, 0x35, 0xe1, 0xba -}; - -static const MDRawContextARM arm_raw_context = { - // context_flags - 0x591b9e6a, - // iregs - { - 0xa21594de, - 0x820d8a25, - 0xc4e133b2, - 0x173a1c02, - 0x105fb175, - 0xe871793f, - 0x5def70b3, - 0xcee3a623, - 0x7b3aa9b8, - 0x52518537, - 0x627012c5, - 0x22723dcc, - 0x16fcc971, - 0x20988bcb, - 0xf1ab806b, - 0x99d5fc03, - }, - // cpsr - 0xb70df511, - // float_save - { - // fpscr - 0xa1e1f7ce1077e6b5ULL, - // regs - { - 0xbcb8d002eed7fbdeULL, - 0x4dd26a43b96ae97fULL, - 0x8eec22db8b31741cULL, - 0xfd634bd7c5ad66a0ULL, - 0x1681da0daeb3debeULL, - 0x474a32bdf72d0b71ULL, - 0xcaf464f8b1044834ULL, - 0xcaa6592ae5c7582aULL, - 0x4ee46889d877c3dbULL, - 0xf8930cf301645cf5ULL, - 0x4da7e9ebba27f7c7ULL, - 0x69a7b02761944da3ULL, - 0x2cda2b2e78195c06ULL, - 0x66b227ab9b460a42ULL, - 0x7e77e49e52ee0849ULL, - 0xd62cd9663e76f255ULL, - 0xe9370f082451514bULL, - 0x50a1c674dd1b6029ULL, - 0x405db4575829eac4ULL, - 0x67b948764649eee7ULL, - 0x93731885419229d4ULL, - 0xdb0338bad72a4ce7ULL, - 0xa0a451f996fca4c8ULL, - 0xb4508ea668400a45ULL, - 0xbff28c5c7a142423ULL, - 0x4f31b42b96f3a431ULL, - 0x2ce6789d4ea1ff37ULL, - 0xfa150b52e4f82a3cULL, - 0xe9ec40449e6ed4f3ULL, - 0x5ceca87836fe2251ULL, - 0x66f50de463ee238cULL, - 0x42823efcd59ab511ULL, - }, - // extra - { - 0xe9e14cd2, - 0x865bb640, - 0x9f3f0b3e, - 0x94a71c52, - 0x3c012f19, - 0x6436637c, - 0x46ccedcb, - 0x7b341be7, - } - } -}; - -static const uint8_t arm_expected_contents[] = { - 0x6a, 0x9e, 0x1b, 0x59, - 0xde, 0x94, 0x15, 0xa2, - 0x25, 0x8a, 0x0d, 0x82, - 0xb2, 0x33, 0xe1, 0xc4, - 0x02, 0x1c, 0x3a, 0x17, - 0x75, 0xb1, 0x5f, 0x10, - 0x3f, 0x79, 0x71, 0xe8, - 0xb3, 0x70, 0xef, 0x5d, - 0x23, 0xa6, 0xe3, 0xce, - 0xb8, 0xa9, 0x3a, 0x7b, - 0x37, 0x85, 0x51, 0x52, - 0xc5, 0x12, 0x70, 0x62, - 0xcc, 0x3d, 0x72, 0x22, - 0x71, 0xc9, 0xfc, 0x16, - 0xcb, 0x8b, 0x98, 0x20, - 0x6b, 0x80, 0xab, 0xf1, - 0x03, 0xfc, 0xd5, 0x99, - 0x11, 0xf5, 0x0d, 0xb7, - 0xb5, 0xe6, 0x77, 0x10, - 0xce, 0xf7, 0xe1, 0xa1, - 0xde, 0xfb, 0xd7, 0xee, - 0x02, 0xd0, 0xb8, 0xbc, - 0x7f, 0xe9, 0x6a, 0xb9, - 0x43, 0x6a, 0xd2, 0x4d, - 0x1c, 0x74, 0x31, 0x8b, - 0xdb, 0x22, 0xec, 0x8e, - 0xa0, 0x66, 0xad, 0xc5, - 0xd7, 0x4b, 0x63, 0xfd, - 0xbe, 0xde, 0xb3, 0xae, - 0x0d, 0xda, 0x81, 0x16, - 0x71, 0x0b, 0x2d, 0xf7, - 0xbd, 0x32, 0x4a, 0x47, - 0x34, 0x48, 0x04, 0xb1, - 0xf8, 0x64, 0xf4, 0xca, - 0x2a, 0x58, 0xc7, 0xe5, - 0x2a, 0x59, 0xa6, 0xca, - 0xdb, 0xc3, 0x77, 0xd8, - 0x89, 0x68, 0xe4, 0x4e, - 0xf5, 0x5c, 0x64, 0x01, - 0xf3, 0x0c, 0x93, 0xf8, - 0xc7, 0xf7, 0x27, 0xba, - 0xeb, 0xe9, 0xa7, 0x4d, - 0xa3, 0x4d, 0x94, 0x61, - 0x27, 0xb0, 0xa7, 0x69, - 0x06, 0x5c, 0x19, 0x78, - 0x2e, 0x2b, 0xda, 0x2c, - 0x42, 0x0a, 0x46, 0x9b, - 0xab, 0x27, 0xb2, 0x66, - 0x49, 0x08, 0xee, 0x52, - 0x9e, 0xe4, 0x77, 0x7e, - 0x55, 0xf2, 0x76, 0x3e, - 0x66, 0xd9, 0x2c, 0xd6, - 0x4b, 0x51, 0x51, 0x24, - 0x08, 0x0f, 0x37, 0xe9, - 0x29, 0x60, 0x1b, 0xdd, - 0x74, 0xc6, 0xa1, 0x50, - 0xc4, 0xea, 0x29, 0x58, - 0x57, 0xb4, 0x5d, 0x40, - 0xe7, 0xee, 0x49, 0x46, - 0x76, 0x48, 0xb9, 0x67, - 0xd4, 0x29, 0x92, 0x41, - 0x85, 0x18, 0x73, 0x93, - 0xe7, 0x4c, 0x2a, 0xd7, - 0xba, 0x38, 0x03, 0xdb, - 0xc8, 0xa4, 0xfc, 0x96, - 0xf9, 0x51, 0xa4, 0xa0, - 0x45, 0x0a, 0x40, 0x68, - 0xa6, 0x8e, 0x50, 0xb4, - 0x23, 0x24, 0x14, 0x7a, - 0x5c, 0x8c, 0xf2, 0xbf, - 0x31, 0xa4, 0xf3, 0x96, - 0x2b, 0xb4, 0x31, 0x4f, - 0x37, 0xff, 0xa1, 0x4e, - 0x9d, 0x78, 0xe6, 0x2c, - 0x3c, 0x2a, 0xf8, 0xe4, - 0x52, 0x0b, 0x15, 0xfa, - 0xf3, 0xd4, 0x6e, 0x9e, - 0x44, 0x40, 0xec, 0xe9, - 0x51, 0x22, 0xfe, 0x36, - 0x78, 0xa8, 0xec, 0x5c, - 0x8c, 0x23, 0xee, 0x63, - 0xe4, 0x0d, 0xf5, 0x66, - 0x11, 0xb5, 0x9a, 0xd5, - 0xfc, 0x3e, 0x82, 0x42, - 0xd2, 0x4c, 0xe1, 0xe9, - 0x40, 0xb6, 0x5b, 0x86, - 0x3e, 0x0b, 0x3f, 0x9f, - 0x52, 0x1c, 0xa7, 0x94, - 0x19, 0x2f, 0x01, 0x3c, - 0x7c, 0x63, 0x36, 0x64, - 0xcb, 0xed, 0xcc, 0x46, - 0xe7, 0x1b, 0x34, 0x7b -}; - -#endif // PROCESSOR_SYNTH_MINIDUMP_UNITTEST_DATA_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/tokenize.cc b/toolkit/crashreporter/google-breakpad/src/processor/tokenize.cc deleted file mode 100644 index 8fce87a22..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/tokenize.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -#ifdef _MSC_VER -#define strtok_r strtok_s -#endif - -using std::vector; - -bool Tokenize(char *line, - const char *separators, - int max_tokens, - vector *tokens) { - tokens->clear(); - tokens->reserve(max_tokens); - - int remaining = max_tokens; - - // Split tokens on the separator character. - // strip them out before exhausting max_tokens. - char *save_ptr; - char *token = strtok_r(line, separators, &save_ptr); - while (token && --remaining > 0) { - tokens->push_back(token); - if (remaining > 1) - token = strtok_r(NULL, separators, &save_ptr); - } - - // If there's anything left, just add it as a single token. - if (remaining == 0 && (token = strtok_r(NULL, "\r\n", &save_ptr))) { - tokens->push_back(token); - } - - return tokens->size() == static_cast(max_tokens); -} - -void StringToVector(const string &str, vector &vec) { - vec.resize(str.length() + 1); - std::copy(str.begin(), str.end(), - vec.begin()); - vec[str.length()] = '\0'; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/processor/tokenize.h b/toolkit/crashreporter/google-breakpad/src/processor/tokenize.h deleted file mode 100644 index 9ff571d5c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/tokenize.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Implements a Tokenize function for splitting up strings. - -#ifndef GOOGLE_BREAKPAD_PROCESSOR_TOKENIZE_H_ -#define GOOGLE_BREAKPAD_PROCESSOR_TOKENIZE_H_ - -#include -#include - -#include "common/using_std_string.h" - -namespace google_breakpad { - -// Splits line into at most max_tokens tokens, separated by any of the -// characters in separators and placing them in the tokens vector. -// line is a 0-terminated string that optionally ends with a newline -// character or combination, which will be removed. -// If more tokens than max_tokens are present, the final token is placed -// into the vector without splitting it up at all. This modifies line as -// a side effect. Returns true if exactly max_tokens tokens are returned, -// and false if fewer are returned. This is not considered a failure of -// Tokenize, but may be treated as a failure if the caller expects an -// exact, as opposed to maximum, number of tokens. - -bool Tokenize(char *line, - const char *separators, - int max_tokens, - std::vector *tokens); -// For convenience, since you need a char* to pass to Tokenize. -// You can call StringToVector on a string, and use &vec[0]. -void StringToVector(const string &str, std::vector &vec); - -} // namespace google_breakpad - -#endif // GOOGLE_BREAKPAD_PROCESSOR_TOKENIZE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h b/toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h deleted file mode 100644 index f96e0a438..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// windows_frame_info.h: Holds debugging information about a stack frame. -// -// This structure is specific to Windows debugging information obtained -// from pdb files using the DIA API. -// -// Author: Mark Mentovai - - -#ifndef PROCESSOR_WINDOWS_FRAME_INFO_H__ -#define PROCESSOR_WINDOWS_FRAME_INFO_H__ - -#include -#include - -#include -#include - -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "processor/logging.h" -#include "processor/tokenize.h" - -namespace google_breakpad { - -#ifdef _WIN32 -#define strtoull _strtoui64 -#endif - -struct WindowsFrameInfo { - public: - enum Validity { - VALID_NONE = 0, - VALID_PARAMETER_SIZE = 1, - VALID_ALL = -1 - }; - - // The types for stack_info_. This is equivalent to MS DIA's - // StackFrameTypeEnum. Each identifies a different type of frame - // information, although all are represented in the symbol file in the - // same format. These are used as indices to the stack_info_ array. - enum StackInfoTypes { - STACK_INFO_FPO = 0, - STACK_INFO_TRAP, // not used here - STACK_INFO_TSS, // not used here - STACK_INFO_STANDARD, - STACK_INFO_FRAME_DATA, - STACK_INFO_LAST, // must be the last sequentially-numbered item - STACK_INFO_UNKNOWN = -1 - }; - - WindowsFrameInfo() : type_(STACK_INFO_UNKNOWN), - valid(VALID_NONE), - prolog_size(0), - epilog_size(0), - parameter_size(0), - saved_register_size(0), - local_size(0), - max_stack_size(0), - allocates_base_pointer(0), - program_string() {} - - WindowsFrameInfo(StackInfoTypes type, - uint32_t set_prolog_size, - uint32_t set_epilog_size, - uint32_t set_parameter_size, - uint32_t set_saved_register_size, - uint32_t set_local_size, - uint32_t set_max_stack_size, - int set_allocates_base_pointer, - const string set_program_string) - : type_(type), - valid(VALID_ALL), - prolog_size(set_prolog_size), - epilog_size(set_epilog_size), - parameter_size(set_parameter_size), - saved_register_size(set_saved_register_size), - local_size(set_local_size), - max_stack_size(set_max_stack_size), - allocates_base_pointer(set_allocates_base_pointer), - program_string(set_program_string) {} - - // Parse a textual serialization of a WindowsFrameInfo object from - // a string. Returns NULL if parsing fails, or a new object - // otherwise. type, rva and code_size are present in the STACK line, - // but not the StackFrameInfo structure, so return them as outparams. - static WindowsFrameInfo *ParseFromString(const string string, - int &type, - uint64_t &rva, - uint64_t &code_size) { - // The format of a STACK WIN record is documented at: - // - // https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md - - std::vector buffer; - StringToVector(string, buffer); - std::vector tokens; - if (!Tokenize(&buffer[0], " \r\n", 11, &tokens)) - return NULL; - - type = strtol(tokens[0], NULL, 16); - if (type < 0 || type > STACK_INFO_LAST - 1) - return NULL; - - rva = strtoull(tokens[1], NULL, 16); - code_size = strtoull(tokens[2], NULL, 16); - uint32_t prolog_size = strtoul(tokens[3], NULL, 16); - uint32_t epilog_size = strtoul(tokens[4], NULL, 16); - uint32_t parameter_size = strtoul(tokens[5], NULL, 16); - uint32_t saved_register_size = strtoul(tokens[6], NULL, 16); - uint32_t local_size = strtoul(tokens[7], NULL, 16); - uint32_t max_stack_size = strtoul(tokens[8], NULL, 16); - int has_program_string = strtoul(tokens[9], NULL, 16); - - const char *program_string = ""; - int allocates_base_pointer = 0; - if (has_program_string) { - program_string = tokens[10]; - } else { - allocates_base_pointer = strtoul(tokens[10], NULL, 16); - } - - return new WindowsFrameInfo(static_cast(type), - prolog_size, - epilog_size, - parameter_size, - saved_register_size, - local_size, - max_stack_size, - allocates_base_pointer, - program_string); - } - - // CopyFrom makes "this" WindowsFrameInfo object identical to "that". - void CopyFrom(const WindowsFrameInfo &that) { - type_ = that.type_; - valid = that.valid; - prolog_size = that.prolog_size; - epilog_size = that.epilog_size; - parameter_size = that.parameter_size; - saved_register_size = that.saved_register_size; - local_size = that.local_size; - max_stack_size = that.max_stack_size; - allocates_base_pointer = that.allocates_base_pointer; - program_string = that.program_string; - } - - // Clears the WindowsFrameInfo object so that users will see it as though - // it contains no information. - void Clear() { - type_ = STACK_INFO_UNKNOWN; - valid = VALID_NONE; - program_string.erase(); - } - - StackInfoTypes type_; - - // Identifies which fields in the structure are valid. This is of - // type Validity, but it is defined as an int because it's not - // possible to OR values into an enumerated type. Users must check - // this field before using any other. - int valid; - - // These values come from IDiaFrameData. - uint32_t prolog_size; - uint32_t epilog_size; - uint32_t parameter_size; - uint32_t saved_register_size; - uint32_t local_size; - uint32_t max_stack_size; - - // Only one of allocates_base_pointer or program_string will be valid. - // If program_string is empty, use allocates_base_pointer. - bool allocates_base_pointer; - string program_string; -}; - -} // namespace google_breakpad - - -#endif // PROCESSOR_WINDOWS_FRAME_INFO_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/COPYING b/toolkit/crashreporter/google-breakpad/src/third_party/curl/COPYING deleted file mode 100644 index 610fbdb07..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1996 - 2011, Daniel Stenberg, . - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curl.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/curl.h deleted file mode 100644 index 0d80936f7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curl.h +++ /dev/null @@ -1,1936 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: curl.h,v 1.396 2009-10-16 13:30:31 yangtse Exp $ - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * http://curl.haxx.se/libcurl/ - * - * curl-library mailing list subscription and unsubscription web interface: - * http://cool.haxx.se/mailman/listinfo/curl-library/ - */ - -/* - * Leading 'curl' path on the 'curlbuild.h' include statement is - * required to properly allow building outside of the source tree, - * due to the fact that in this case 'curlbuild.h' is generated in - * a subdirectory of the build tree while 'curl.h actually remains - * in a subdirectory of the source tree. - */ - -#include "third_party/curl/curlver.h" /* libcurl version defines */ -#include "third_party/curl/curlbuild.h" /* libcurl build definitions */ -#include "third_party/curl/curlrules.h" /* libcurl rules enforcement */ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 -#endif - -#include -#include - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ - !defined(__CYGWIN__) || defined(__MINGW32__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#else - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on system that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(__ANDROID__) -#include -#endif - -#ifndef _WIN32_WCE -#include -#endif -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) -#include -#endif -#include -#endif - -#ifdef __BEOS__ -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURL; - -/* - * Decorate exportable functions for Win32 and Symbian OS DLL linking. - * This avoids using a .def file for building libcurl.dll. - */ -#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ - !defined(CURL_STATICLIB) -#if defined(BUILDING_LIBCURL) -#define CURL_EXTERN __declspec(dllexport) -#else -#define CURL_EXTERN __declspec(dllimport) -#endif -#else - -#ifdef CURL_HIDDEN_SYMBOLS -/* - * This definition is used to make external definitions visible in the - * shared library when symbols are hidden by default. It makes no - * difference when compiling applications whether this is set or not, - * only when compiling the library. - */ -#define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -#define CURL_EXTERN -#endif -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#ifdef WIN32 -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist* contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ -#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ -#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ -#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer - do not free in formfree */ -#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer - do not free in formfree */ -#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ -#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ -#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the - regular read callback to get the data - and pass the given pointer as custom - pointer */ - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ -}; - -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -#ifndef CURL_NO_OLDIES - /* not used since 7.10.8, will be removed in a future release */ -typedef int (*curl_passwd_callback)(void *clientp, - const char *prompt, - char *buffer, - int buflen); -#endif - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -/* the kind of data that is passed to information_callback*/ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_OBSOLETE4, /* 4 - NOT USED */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_OBSOLETE10, /* 10 - NOT USED */ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_OBSOLETE12, /* 12 - NOT USED */ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_OBSOLETE16, /* 16 - NOT USED */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error - instead of a memory allocation error if CURL_DOES_CONVERSIONS - is defined - */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ - CURLE_CONV_REQD, /* 76 - caller must register conversion - callbacks using curl_easy_setopt options - CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPT_CONV_TO_NETWORK_FUNCTION, and - CURLOPT_CONV_FROM_UTF8_FUNCTION */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4 - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT - -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED - -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -#endif /*!CURL_NO_OLDIES*/ - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -typedef enum { - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -#define CURLAUTH_NONE 0 /* nothing */ -#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ -#define CURLAUTH_DIGEST (1<<1) /* Digest */ -#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ -#define CURLAUTH_NTLM (1<<3) /* NTLM */ -#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURL_ERROR_SIZE 256 - -struct curl_khkey { - const char *key; /* points to a zero-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum type { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS - } keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the - connection will be left intact etc */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed from app */ - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum { - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /*!CURL_NO_OLDIES*/ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum { - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum { - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum { - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 - -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif - -#ifdef CURL_ISOCPP -#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(FILE, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, OBJECTPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, OBJECTPOINT, 4), - - /* "name:password" to use when fetching. */ - CINIT(USERPWD, OBJECTPOINT, 5), - - /* "name:password" to use with proxy. */ - CINIT(PROXYUSERPWD, OBJECTPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, OBJECTPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(INFILE, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, OBJECTPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, OBJECTPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, OBJECTPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, OBJECTPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, OBJECTPOINT, 25), - - /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, OBJECTPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(WRITEHEADER, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, OBJECTPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), - - /* HTTP request, for odd commands like DELETE, TRACE and others */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - /* Pass a pointer to string of the output using full variable-replacement - as described elsewhere. */ - CINIT(WRITEINFO, OBJECTPOINT, 40), - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ - - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), - - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ - - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the progress callback */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), - - /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, OBJECTPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, OBJECTPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, OBJECTPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - /* What policy to use when closing connections when the cache is filled - up */ - CINIT(CLOSEPOLICY, LONG, 72), - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, OBJECTPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, OBJECTPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects - are OK within this time, then fine... This only aborts the connect - phase. [Only works on unix-style/SIGALRM operating systems] */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, OBJECTPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, OBJECTPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, OBJECTPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, OBJECTPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, OBJECTPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, OBJECTPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. */ - CINIT(ENCODING, OBJECTPOINT, 102), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( it - also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, OBJECTPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise - CURLFTPSSL_CONTROL - SSL for the control connection or fail - CURLFTPSSL_ALL - SSL for all communication or fail - */ - CINIT(USE_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CINIT(FTPSSLAUTH, LONG, 129), - - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* zero terminated string for pass on to the FTP server when asked for - "account" info */ - CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), - - /* feed cookies into cookie engine */ - CINIT(COOKIELIST, OBJECTPOINT, 135), - - /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), - - /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CINIT(LOCALPORTRANGE, LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), - - /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), - - /* set to 0 to disable session ID re-use for this transfer, default is - enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), - - /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), - - /* Set the behaviour of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), - - /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), - - /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), - - /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), - - /* CRL file */ - CINIT(CRLFILE, OBJECTPOINT, 169), - - /* Issuer certificate */ - CINIT(ISSUERCERT, OBJECTPOINT, 170), - - /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only - working with OpenSSL-powered builds. */ - CINIT(CERTINFO, LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, OBJECTPOINT, 173), - CINIT(PASSWORD, OBJECTPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, OBJECTPOINT, 175), - CINIT(PROXYPASSWORD, OBJECTPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CINIT(NOPROXY, OBJECTPOINT, 177), - - /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), - - /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ - - /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_WRITEDATA CURLOPT_FILE -#define CURLOPT_READDATA CURLOPT_INFILE -#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that - CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - libcurl, see lib/README.curlx for details */ -CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); -CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); - -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is not thread-safe! - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, - const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information in the - format "name: value" */ -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_SLIST + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 35 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - -typedef void CURLSH; - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* out of memory */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_FOURTH - -typedef struct { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ -#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ -#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ -#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ -#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ - -/* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus */ - -#endif /* __CURL_CURL_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlbuild.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlbuild.h deleted file mode 100644 index b0a53e6c9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlbuild.h +++ /dev/null @@ -1,202 +0,0 @@ -/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ -#ifndef __CURL_CURLBUILD_H -#define __CURL_CURLBUILD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: curlbuild.h.in,v 1.8 2009-04-29 15:15:38 yangtse Exp $ - ***************************************************************************/ - -/* ================================================================ */ -/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * If you think that something actually needs to be changed, adjusted - * or fixed in this file, then, report it on the libcurl development - * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ - * - * This header file shall only export symbols which are 'curl' or 'CURL' - * prefixed, otherwise public name space would be polluted. - * - * NOTE 2: - * ------- - * - * Right now you might be staring at file include/curl/curlbuild.h.in or - * at file include/curl/curlbuild.h, this is due to the following reason: - * - * On systems capable of running the configure script, the configure process - * will overwrite the distributed include/curl/curlbuild.h file with one that - * is suitable and specific to the library being configured and built, which - * is generated from the include/curl/curlbuild.h.in template file. - * - */ - -/* ================================================================ */ -/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ -/* ================================================================ */ - -#ifdef CURL_SIZEOF_LONG -# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T -# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_SOCKLEN_T -# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_OFF_T -# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_T -# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_TU -# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined -#endif - -#ifdef CURL_FORMAT_OFF_T -# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_OFF_T -# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_T -# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_TU -# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined -#endif - -/* ================================================================ */ -/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ -/* ================================================================ */ - -/* Configure process defines this to 1 when it finds out that system */ -/* header file ws2tcpip.h must be included by the external interface. */ -/* #undef CURL_PULL_WS2TCPIP_H */ -#ifdef CURL_PULL_WS2TCPIP_H -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/types.h must be included by the external interface. */ -#define CURL_PULL_SYS_TYPES_H 1 -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file stdint.h must be included by the external interface. */ -/* #undef CURL_PULL_STDINT_H */ -#ifdef CURL_PULL_STDINT_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file inttypes.h must be included by the external interface. */ -/* #undef CURL_PULL_INTTYPES_H */ -#ifdef CURL_PULL_INTTYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/socket.h must be included by the external interface. */ -#define CURL_PULL_SYS_SOCKET_H 1 -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* The size of `long', as computed by sizeof. */ -#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__)) || \ - defined(__aarch64__) || (defined(__mips__) && _MIPS_SIM == _ABI64) -#define CURL_SIZEOF_LONG 8 -#else -#define CURL_SIZEOF_LONG 4 -#endif - -/* Integral data type used for curl_socklen_t. */ -#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t - -/* The size of `curl_socklen_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -/* Data type definition of curl_socklen_t. */ -typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; - -/* Signed integral data type used for curl_off_t. */ -#if defined(_M_X64) || (defined(__x86_64__) && !defined(__ILP32__)) || \ - defined(__aarch64__) -#define CURL_TYPEOF_CURL_OFF_T long -#else -#define CURL_TYPEOF_CURL_OFF_T int64_t -#endif - -/* Data type definition of curl_off_t. */ -typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; - -/* curl_off_t formatting string directive without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_T "ld" - -/* unsigned curl_off_t formatting string without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_TU "lu" - -/* curl_off_t formatting string directive with "%" conversion specifier. */ -#define CURL_FORMAT_OFF_T "%ld" - -/* The size of `curl_off_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_OFF_T 8 - -/* curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_T L - -/* unsigned curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_TU UL - -#endif /* __CURL_CURLBUILD_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlrules.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlrules.h deleted file mode 100644 index abac4397d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlrules.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef __CURL_CURLRULES_H -#define __CURL_CURLRULES_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: curlrules.h,v 1.7 2009-10-27 16:56:20 yangtse Exp $ - ***************************************************************************/ - -/* ================================================================ */ -/* COMPILE TIME SANITY CHECKS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * All checks done in this file are intentionally placed in a public - * header file which is pulled by curl/curl.h when an application is - * being built using an already built libcurl library. Additionally - * this file is also included and used when building the library. - * - * If compilation fails on this file it is certainly sure that the - * problem is elsewhere. It could be a problem in the curlbuild.h - * header file, or simply that you are using different compilation - * settings than those used to build the library. - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * Do not deactivate any check, these are done to make sure that the - * library is properly built and used. - * - * You can find further help on the libcurl development mailing list: - * http://cool.haxx.se/mailman/listinfo/curl-library/ - * - * NOTE 2 - * ------ - * - * Some of the following compile time checks are based on the fact - * that the dimension of a constant array can not be a negative one. - * In this way if the compile time verification fails, the compilation - * will fail issuing an error. The error description wording is compiler - * dependent but it will be quite similar to one of the following: - * - * "negative subscript or subscript is too large" - * "array must have at least one element" - * "-1 is an illegal array size" - * "size of array is negative" - * - * If you are building an application which tries to use an already - * built libcurl library and you are getting this kind of errors on - * this file, it is a clear indication that there is a mismatch between - * how the library was built and how you are trying to use it for your - * application. Your already compiled or binary library provider is the - * only one who can give you the details you need to properly use it. - */ - -/* - * Verify that some macros are actually defined. - */ - -#ifndef CURL_SIZEOF_LONG -# error "CURL_SIZEOF_LONG definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_SOCKLEN_T -# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_SOCKLEN_T -# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_OFF_T -# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_T -# error "CURL_FORMAT_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_TU -# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing -#endif - -#ifndef CURL_FORMAT_OFF_T -# error "CURL_FORMAT_OFF_T definition is missing!" - Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_OFF_T -# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_T -# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_TU -# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing -#endif - -/* - * Macros private to this header file. - */ - -#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 - -#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 - -/* - * Verify that the size previously defined and expected for long - * is the same as the one reported by sizeof() at compile time. - */ - -typedef char - __curl_rule_01__ - [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; - -/* - * Verify that the size previously defined and expected for - * curl_off_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char - __curl_rule_02__ - [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; - -/* - * Verify at compile time that the size of curl_off_t as reported - * by sizeof() is greater or equal than the one reported for long - * for the current compilation. - */ - -typedef char - __curl_rule_03__ - [CurlchkszGE(curl_off_t, long)]; - -/* - * Verify that the size previously defined and expected for - * curl_socklen_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char - __curl_rule_04__ - [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; - -/* - * Verify at compile time that the size of curl_socklen_t as reported - * by sizeof() is greater or equal than the one reported for int for - * the current compilation. - */ - -typedef char - __curl_rule_05__ - [CurlchkszGE(curl_socklen_t, int)]; - -/* ================================================================ */ -/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ -/* ================================================================ */ - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) - /* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else - /* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#ifdef CURL_ISOCPP -# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix -#else -# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix -#endif -#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix) -#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T) -#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU) - -/* - * Get rid of macros private to this header file. - */ - -#undef CurlchkszEQ -#undef CurlchkszGE - -/* - * Get rid of macros not intended to exist beyond this point. - */ - -#undef CURL_PULL_WS2TCPIP_H -#undef CURL_PULL_SYS_TYPES_H -#undef CURL_PULL_SYS_SOCKET_H -#undef CURL_PULL_STDINT_H -#undef CURL_PULL_INTTYPES_H - -#undef CURL_TYPEOF_CURL_SOCKLEN_T -#undef CURL_TYPEOF_CURL_OFF_T - -#endif /* __CURL_CURLRULES_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlver.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlver.h deleted file mode 100644 index afa85c15a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/curlver.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: curlver.h,v 1.48 2009-08-12 11:24:52 bagder Exp $ - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2009 Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.19.7" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 19 -#define LIBCURL_VERSION_PATCH 7 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. -*/ -#define LIBCURL_VERSION_NUM 0x071307 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in CVS, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date should follow this template: - * - * "Mon Feb 12 11:35:33 UTC 2007" - */ -#define LIBCURL_TIMESTAMP "Wed Nov 4 12:34:59 UTC 2009" - -#endif /* __CURL_CURLVER_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/easy.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/easy.h deleted file mode 100644 index 40449c3ec..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/easy.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: easy.h,v 1.14 2008-05-12 21:43:28 bagder Exp $ - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistant connections cannot - * be transfered. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/mprintf.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/mprintf.h deleted file mode 100644 index d7202de17..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/mprintf.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: mprintf.h,v 1.16 2008-05-20 10:21:50 patrickm Exp $ - ***************************************************************************/ - -#include -#include /* needed for FILE */ - -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args); -CURL_EXTERN char *curl_maprintf(const char *format, ...); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); - -#ifdef _MPRINTF_REPLACE -# undef printf -# undef fprintf -# undef sprintf -# undef vsprintf -# undef snprintf -# undef vprintf -# undef vfprintf -# undef vsnprintf -# undef aprintf -# undef vaprintf -# define printf curl_mprintf -# define fprintf curl_mfprintf -#ifdef CURLDEBUG -/* When built with CURLDEBUG we define away the sprintf() functions since we - don't want internal code to be using them */ -# define sprintf sprintf_was_used -# define vsprintf vsprintf_was_used -#else -# define sprintf curl_msprintf -# define vsprintf curl_mvsprintf -#endif -# define snprintf curl_msnprintf -# define vprintf curl_mvprintf -# define vfprintf curl_mvfprintf -# define vsnprintf curl_mvsnprintf -# define aprintf curl_maprintf -# define vaprintf curl_mvaprintf -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __CURL_MPRINTF_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/multi.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/multi.h deleted file mode 100644 index 153f7721c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/multi.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: multi.h,v 1.45 2008-05-20 10:21:50 patrickm Exp $ - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURLM; - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic informations. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a zero-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, - int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - -typedef enum { - /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), - - /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/stdcheaders.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/stdcheaders.h deleted file mode 100644 index f739d7f9a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/stdcheaders.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: stdcheaders.h,v 1.9 2009-05-18 12:25:45 yangtse Exp $ - ***************************************************************************/ - -#include - -size_t fread (void *, size_t, size_t, FILE *); -size_t fwrite (const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/typecheck-gcc.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/typecheck-gcc.h deleted file mode 100644 index 978830581..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/typecheck-gcc.h +++ /dev/null @@ -1,551 +0,0 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * $Id: typecheck-gcc.h,v 1.9 2009-01-25 23:26:31 bagder Exp $ - ***************************************************************************/ - -/* wraps curl_easy_setopt() with typechecking */ - -/* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt) && ! _curl_is_sometype(value)) - * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and - * _curl_easy_setopt_err_sometype below - * - * To add an option that uses the same type as an existing option, you'll just - * need to extend the appropriate _curl_*_option macro - */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__ (option) _curl_opt = option; \ - if (__builtin_constant_p(_curl_opt)) { \ - if (_curl_is_long_option(_curl_opt) && !_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if (_curl_is_off_t_option(_curl_opt) && !_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if (_curl_is_string_option(_curl_opt) && !_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if (_curl_is_write_cb_option(_curl_opt) && !_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\ - _curl_easy_setopt_err_sockopt_cb(); \ - if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION && \ - !_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION && \ - !_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION && \ - !_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if (_curl_is_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if (_curl_is_cb_data_option(_curl_opt) && !_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if ((_curl_opt) == CURLOPT_HTTPPOST && \ - !_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if (_curl_is_slist_option(_curl_opt) && \ - !_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) - -/* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__ (info) _curl_info = info; \ - if (__builtin_constant_p(_curl_info)) { \ - if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if (_curl_is_slist_info(_curl_info) && \ - !_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) - -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments - */ -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) - - -/* the actual warnings, triggered by calling the _curl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((warning(message))) __attribute__((unused)) \ - __attribute__((noinline)) id(void) { __asm__(""); } - -_CURL_WARNING(_curl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a string (char* or char[]) argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a curl_opensocket_callback argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a FILE* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a void* or char* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a struct curl_httppost* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a struct curl_slist* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument for this option") - -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to char * for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* To add a new option to one of the groups, just add - * (option) == CURLOPT_SOMETHING - * to the or-expression. If the option takes a long or curl_off_t, you don't - * have to do anything - */ - -/* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define _curl_is_off_t_option(option) \ - ((option) > CURLOPTTYPE_OFF_T) - -/* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_URL || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_ENCODING || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_ISSUERCERT || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_WRITEDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_WRITEHEADER || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_PRIVATE || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) - -/* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (CURLINFO_SLIST < (info)) - - -/* typecheck helpers -- check whether given expression has requested type*/ - -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void*)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char)) - -/* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) -#else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *)) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) - -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func), type*)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); -typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); -typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); -typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); -typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); -typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); -typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); -typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); -typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); -typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (_curl_opensocket_callback1) - (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback2) - (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback3) - (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback4) - (const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (_curl_progress_callback1)(void *, - double, double, double, double); -typedef int (_curl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4)) -typedef int (_curl_debug_callback1) (CURL *, - curl_infotype, char *, size_t, void *); -typedef int (_curl_debug_callback2) (CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (_curl_debug_callback3) (CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (_curl_debug_callback4) (CURL *, - curl_infotype, const char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this will of course break if we're included before OpenSSL headers... - */ -typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *); -#else -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) -typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); -typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); -typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) -typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); - - -#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/curl/types.h b/toolkit/crashreporter/google-breakpad/src/third_party/curl/types.h deleted file mode 100644 index d37d6ae9e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/curl/types.h +++ /dev/null @@ -1 +0,0 @@ -/* not used */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/Makefile.am b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/Makefile.am deleted file mode 100644 index bd3129e1a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -include_HEADERS = libdis.h -lib_LTLIBRARIES = libdisasm.la -libdisasm_la_SOURCES = \ - ia32_implicit.c \ - ia32_implicit.h \ - ia32_insn.c \ - ia32_insn.h \ - ia32_invariant.c \ - ia32_invariant.h \ - ia32_modrm.c \ - ia32_modrm.h \ - ia32_opcode_tables.c \ - ia32_opcode_tables.h \ - ia32_operand.c \ - ia32_operand.h \ - ia32_reg.c \ - ia32_reg.h \ - ia32_settings.c \ - ia32_settings.h \ - libdis.h \ - qword.h \ - x86_disasm.c \ - x86_format.c \ - x86_imm.c \ - x86_imm.h \ - x86_insn.c \ - x86_misc.c \ - x86_operand_list.c \ - x86_operand_list.h - -# Cheat to get non-autoconf swig into tarball, -# even if it doesn't build by default. -EXTRA_DIST = \ -swig/Makefile \ -swig/libdisasm.i \ -swig/libdisasm_oop.i \ -swig/python/Makefile-swig \ -swig/perl/Makefile-swig \ -swig/perl/Makefile.PL \ -swig/ruby/Makefile-swig \ -swig/ruby/extconf.rb \ -swig/tcl/Makefile-swig \ -swig/README diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/TODO b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/TODO deleted file mode 100644 index 148addf9b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/TODO +++ /dev/null @@ -1,43 +0,0 @@ -x86_format.c ------------- -intel: jmpf -> jmp, callf -> call -att: jmpf -> ljmp, callf -> lcall - -opcode table ------------- -finish typing instructions -fix flag clear/set/toggle types - -ix64 stuff ----------- -document output file formats in web page -features doc: register aliases, implicit operands, stack mods, -ring0 flags, eflags, cpu model/isa - -ia32_handle_* implementation - -fix operand 0F C2 -CMPPS - -* sysenter, sysexit as CALL types -- preceded by MSR writes -* SYSENTER/SYSEXIT stack : overwrites SS, ESP -* stos, cmps, scas, movs, ins, outs, lods -> OP_PTR -* OP_SIZE in implicit operands -* use OP_SIZE to choose reg sizes! - -DONE?? : -implicit operands: provide action ? -e.g. add/inc for stach, write, etc -replace table numbers in opcodes.dat with -#defines for table names - -replace 0 with INSN_INVALID [or maybe FF for imnvalid and 00 for Not Applicable */ -no wait that is only for prefix tables -- n/p - -if ( prefx) only use if insn != invalid - -these should cover all the wacky disasm exceptions - -for the rep one we can chet, match only a 0x90 - -todo: privilege | ring diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.c deleted file mode 100644 index 8b075d2ee..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.c +++ /dev/null @@ -1,422 +0,0 @@ -#include - -#include "ia32_implicit.h" -#include "ia32_insn.h" -#include "ia32_reg.h" -#include "x86_operand_list.h" - -/* Conventions: Register operands which are aliases of another register - * operand (e.g. AX in one operand and AL in another) assume that the - * operands are different registers and that alias tracking will resolve - * data flow. This means that something like - * mov ax, al - * would have 'write only' access for AX and 'read only' access for AL, - * even though both AL and AX are read and written */ -typedef struct { - uint32_t type; - uint32_t operand; -} op_implicit_list_t; - -static op_implicit_list_t list_aaa[] = - /* 37 : AAA : rw AL */ - /* 3F : AAS : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* aaa */ - -static op_implicit_list_t list_aad[] = - /* D5 0A, D5 (ib) : AAD : rw AX */ - /* D4 0A, D4 (ib) : AAM : rw AX */ - {{ OP_R | OP_W, REG_WORD_OFFSET }, {0}}; /* aad */ - -static op_implicit_list_t list_call[] = - /* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */ - /* C2, C3, CA, CB : RET : rw ESP, rw EIP */ - {{ OP_R | OP_W, REG_EIP_INDEX }, - { OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* call, ret */ - -static op_implicit_list_t list_cbw[] = - /* 98 : CBW : r AL, rw AX */ - {{ OP_R | OP_W, REG_WORD_OFFSET }, - { OP_R, REG_BYTE_OFFSET}, {0}}; /* cbw */ - -static op_implicit_list_t list_cwde[] = - /* 98 : CWDE : r AX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_R, REG_WORD_OFFSET }, {0}}; /* cwde */ - -static op_implicit_list_t list_clts[] = - /* 0F 06 : CLTS : rw CR0 */ - {{ OP_R | OP_W, REG_CTRL_OFFSET}, {0}}; /* clts */ - -static op_implicit_list_t list_cmpxchg[] = - /* 0F B0 : CMPXCHG : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* cmpxchg */ - -static op_implicit_list_t list_cmpxchgb[] = - /* 0F B1 : CMPXCHG : rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* cmpxchg */ - -static op_implicit_list_t list_cmpxchg8b[] = - /* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R, REG_DWORD_OFFSET + 1 }, - { OP_R, REG_DWORD_OFFSET + 3 }, {0}}; /* cmpxchg8b */ - -static op_implicit_list_t list_cpuid[] = - /* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET + 3 }, {0}}; /* cpuid */ - -static op_implicit_list_t list_cwd[] = - /* 99 : CWD/CWQ : rw EAX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* cwd */ - -static op_implicit_list_t list_daa[] = - /* 27 : DAA : rw AL */ - /* 2F : DAS : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* daa */ - -static op_implicit_list_t list_idiv[] = - /* F6 : DIV, IDIV : r AX, w AL, w AH */ - /* FIXED: first op was EAX, not Aw. TODO: verify! */ - {{ OP_R, REG_WORD_OFFSET }, - { OP_W, REG_BYTE_OFFSET }, - { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* div */ - -static op_implicit_list_t list_div[] = - /* F7 : DIV, IDIV : rw EDX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* div */ - -static op_implicit_list_t list_enter[] = - /* C8 : ENTER : rw ESP w EBP */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 4 }, - { OP_R, REG_DWORD_OFFSET + 5 }, {0}}; /* enter */ - -static op_implicit_list_t list_f2xm1[] = - /* D9 F0 : F2XM1 : rw ST(0) */ - /* D9 E1 : FABS : rw ST(0) */ - /* D9 E0 : FCHS : rw ST(0) */ - /* D9 FF : FCOS : rw ST(0)*/ - /* D8, DA : FDIV : rw ST(0) */ - /* D8, DA : FDIVR : rw ST(0) */ - /* D9 F2 : FPTAN : rw ST(0) */ - /* D9 FC : FRNDINT : rw ST(0) */ - /* D9 FB : FSINCOS : rw ST(0) */ - /* D9 FE : FSIN : rw ST(0) */ - /* D9 FA : FSQRT : rw ST(0) */ - /* D9 F4 : FXTRACT : rw ST(0) */ - {{ OP_R | OP_W, REG_FPU_OFFSET }, {0}}; /* f2xm1 */ - -static op_implicit_list_t list_fcom[] = - /* D8, DC, DE D9 : FCOM : r ST(0) */ - /* DE, DA : FICOM : r ST(0) */ - /* DF, D8 : FIST : r ST(0) */ - /* D9 E4 : FTST : r ST(0) */ - /* D9 E5 : FXAM : r ST(0) */ - {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fcom */ - -static op_implicit_list_t list_fpatan[] = - /* D9 F3 : FPATAN : r ST(0), rw ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fpatan */ - -static op_implicit_list_t list_fprem[] = - /* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */ - /* D9 FD : FSCALE : rw ST(0), r ST(1) */ - {{ OP_R | OP_W, REG_FPU_OFFSET }, - { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fprem */ - -static op_implicit_list_t list_faddp[] = - /* DE C1 : FADDP : r ST(0), rw ST(1) */ - /* DE E9 : FSUBP : r ST(0), rw ST(1) */ - /* D9 F1 : FYL2X : r ST(0), rw ST(1) */ - /* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, - { OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0}}; /* faddp */ - -static op_implicit_list_t list_fucompp[] = - /* DA E9 : FUCOMPP : r ST(0), r ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, - { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fucompp */ - -static op_implicit_list_t list_imul[] = - /* F6 : IMUL : r AL, w AX */ - /* F6 : MUL : r AL, w AX */ - {{ OP_R, REG_BYTE_OFFSET }, - { OP_W, REG_WORD_OFFSET }, {0}}; /* imul */ - -static op_implicit_list_t list_mul[] = - /* F7 : IMUL : rw EAX, w EDX */ - /* F7 : MUL : rw EAX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* imul */ - -static op_implicit_list_t list_lahf[] = - /* 9F : LAHF : r EFLAGS, w AH */ - {{ OP_R, REG_FLAGS_INDEX }, - { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* lahf */ - -static op_implicit_list_t list_ldmxcsr[] = - /* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */ - {{ OP_W, REG_MXCSG_INDEX }, {0}}; /* ldmxcsr */ - -static op_implicit_list_t list_leave[] = - /* C9 : LEAVE : rw ESP, w EBP */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_DWORD_OFFSET + 5 }, {0}}; /* leave */ - -static op_implicit_list_t list_lgdt[] = - /* 0F 01 : LGDT : w GDTR */ - {{ OP_W, REG_GDTR_INDEX }, {0}}; /* lgdt */ - -static op_implicit_list_t list_lidt[] = - /* 0F 01 : LIDT : w IDTR */ - {{ OP_W, REG_IDTR_INDEX }, {0}}; /* lidt */ - -static op_implicit_list_t list_lldt[] = - /* 0F 00 : LLDT : w LDTR */ - {{ OP_W, REG_LDTR_INDEX }, {0}}; /* lldt */ - -static op_implicit_list_t list_lmsw[] = - /* 0F 01 : LMSW : w CR0 */ - {{ OP_W, REG_CTRL_OFFSET }, {0}}; /* lmsw */ - -static op_implicit_list_t list_loop[] = - /* E0, E1, E2 : LOOP : rw ECX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* loop */ - -static op_implicit_list_t list_ltr[] = - /* 0F 00 : LTR : w Task Register */ - {{ OP_W, REG_TR_INDEX }, {0}}; /* ltr */ - -static op_implicit_list_t list_pop[] = - /* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */ - /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ - {{ OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* pop, push */ - -static op_implicit_list_t list_popad[] = - /* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_DWORD_OFFSET + 7 }, - { OP_W, REG_DWORD_OFFSET + 6 }, - { OP_W, REG_DWORD_OFFSET + 5 }, - { OP_W, REG_DWORD_OFFSET + 3 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* popad */ - -static op_implicit_list_t list_popfd[] = - /* 9D : POPFD : rw esp, w eflags */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_FLAGS_INDEX }, {0}}; /* popfd */ - -static op_implicit_list_t list_pushad[] = - /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ - /* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_R, REG_DWORD_OFFSET }, - { OP_R, REG_DWORD_OFFSET + 1 }, - { OP_R, REG_DWORD_OFFSET + 2 }, - { OP_R, REG_DWORD_OFFSET + 3 }, - { OP_R, REG_DWORD_OFFSET + 5 }, - { OP_R, REG_DWORD_OFFSET + 6 }, - { OP_R, REG_DWORD_OFFSET + 7 }, {0}}; /* pushad */ - -static op_implicit_list_t list_pushfd[] = - /* 9C : PUSHFD : rw esp, r eflags */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_R, REG_FLAGS_INDEX }, {0}}; /* pushfd */ - -static op_implicit_list_t list_rdmsr[] = - /* 0F 32 : RDMSR : r ECX, w EDX, w EAX */ - {{ OP_R, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdmsr */ - -static op_implicit_list_t list_rdpmc[] = - /* 0F 33 : RDPMC : r ECX, w EDX, w EAX */ - {{ OP_R, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdpmc */ - -static op_implicit_list_t list_rdtsc[] = - /* 0F 31 : RDTSC : rw EDX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* rdtsc */ - -static op_implicit_list_t list_rep[] = - /* F3, F2 ... : REP : rw ECX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* rep */ - -static op_implicit_list_t list_rsm[] = - /* 0F AA : RSM : r CR4, r CR0 */ - {{ OP_R, REG_CTRL_OFFSET + 4 }, - { OP_R, REG_CTRL_OFFSET }, {0}}; /* rsm */ - -static op_implicit_list_t list_sahf[] = - /* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sahf */ - -static op_implicit_list_t list_sgdt[] = - /* 0F : SGDT : r gdtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sgdt */ - -static op_implicit_list_t list_sidt[] = - /* 0F : SIDT : r idtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sidt */ - -static op_implicit_list_t list_sldt[] = - /* 0F : SLDT : r ldtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sldt */ - -static op_implicit_list_t list_smsw[] = - /* 0F : SMSW : r CR0 */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* smsw */ - -static op_implicit_list_t list_stmxcsr[] = - /* 0F AE : STMXCSR : r MXCSR */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* stmxcsr */ - -static op_implicit_list_t list_str[] = - /* 0F 00 : STR : r TR (task register) */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* str */ - -static op_implicit_list_t list_sysenter[] = - /* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags - * r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysenter */ - -static op_implicit_list_t list_sysexit[] = - /* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp - * r sysenter_cs_msr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysexit */ - -static op_implicit_list_t list_wrmsr[] = - /* 0F 30 : WRMST : r edx, r eax, r ecx */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* wrmsr */ - -static op_implicit_list_t list_xlat[] = - /* D7 : XLAT : rw al r ebx (ptr) */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* xlat */ -/* TODO: - * monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R - * mwait 0f 01 c9 eax OP_R ecx OP_R - */ -static op_implicit_list_t list_monitor[] = - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* monitor */ -static op_implicit_list_t list_mwait[] = - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* mwait */ - -op_implicit_list_t *op_implicit_list[] = { - /* This is a list of implicit operands which are read/written by - * various x86 instructions. Note that modifications to the stack - * register are mentioned here, but that additional information on - * the effect an instruction has on the stack is contained in the - * x86_insn_t 'stack_mod' and 'stack_mod_val' fields. Use of the - * eflags register, i.e. setting, clearing, and testing flags, is - * not recorded here but rather in the flags_set and flags_tested - * fields of the x86_insn_t.*/ - NULL, - list_aaa, list_aad, list_call, list_cbw, /* 1 - 4 */ - list_cwde, list_clts, list_cmpxchg, list_cmpxchgb, /* 5 - 8 */ - list_cmpxchg8b, list_cpuid, list_cwd, list_daa, /* 9 - 12 */ - list_idiv, list_div, list_enter, list_f2xm1, /* 13 - 16 */ - list_fcom, list_fpatan, list_fprem, list_faddp, /* 17 - 20 */ - list_fucompp, list_imul, list_mul, list_lahf, /* 21 - 24 */ - list_ldmxcsr, list_leave, list_lgdt, list_lidt, /* 25 - 28 */ - list_lldt, list_lmsw, list_loop, list_ltr, /* 29 - 32 */ - list_pop, list_popad, list_popfd, list_pushad, /* 33 - 36 */ - list_pushfd, list_rdmsr, list_rdpmc, list_rdtsc, /* 37 - 40 */ - /* NOTE: 'REP' is a hack since it is a prefix: if its position - * in the table changes, then change IDX_IMPLICIT_REP in the .h */ - list_rep, list_rsm, list_sahf, list_sgdt, /* 41 - 44 */ - list_sidt, list_sldt, list_smsw, list_stmxcsr, /* 45 - 48 */ - list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */ - list_xlat, list_monitor, list_mwait, /* 53 - 55*/ - NULL /* end of list */ - }; - -#define LAST_IMPL_IDX 55 - -static void handle_impl_reg( x86_op_t *op, uint32_t val ) { - x86_reg_t *reg = &op->data.reg; - op->type = op_register; - ia32_handle_register( reg, (unsigned int) val ); - switch (reg->size) { - case 1: - op->datatype = op_byte; break; - case 2: - op->datatype = op_word; break; - case 4: - op->datatype = op_dword; break; - case 8: - op->datatype = op_qword; break; - case 10: - op->datatype = op_extreal; break; - case 16: - op->datatype = op_dqword; break; - } - return; -} - -/* 'impl_idx' is the value from the opcode table: between 1 and LAST_IMPL_IDX */ -/* returns number of operands added */ -unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx ) { - op_implicit_list_t *list; - x86_op_t *op; - unsigned int num = 0; - - if (! impl_idx || impl_idx > LAST_IMPL_IDX ) { - return 0; - } - - for ( list = op_implicit_list[impl_idx]; list->type; list++, num++ ) { - enum x86_op_access access = (enum x86_op_access) OP_PERM(list->type); - enum x86_op_flags flags = (enum x86_op_flags) (OP_FLAGS(list->type) >> 12); - - op = NULL; - /* In some cases (MUL), EAX is an implicit operand hardcoded in - * the instruction without being explicitly listed in assembly. - * For this situation, find the hardcoded operand and add the - * implied flag rather than adding a new implicit operand. */ - x86_oplist_t * existing; - if (ia32_true_register_id(list->operand) == REG_DWORD_OFFSET) { - for ( existing = insn->operands; existing; existing = existing->next ) { - if (existing->op.type == op_register && - existing->op.data.reg.id == list->operand) { - op = &existing->op; - break; - } - } - } - if (!op) { - op = x86_operand_new( insn ); - /* all implicit operands are registers */ - handle_impl_reg( op, list->operand ); - /* decrement the 'explicit count' incremented by default in - * x86_operand_new */ - insn->explicit_count = insn->explicit_count -1; - } - if (!op) { - return num; /* gah! return early */ - } - op->access |= access; - op->flags |= flags; - op->flags |= op_implied; - } - - return num; -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.h deleted file mode 100644 index 0002b28b9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_implicit.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef IA32_IMPLICIT_H -#define IA32_IMPLICIT_H - -#include "libdis.h" - -/* OK, this is a hack to deal with prefixes having implicit operands... - * thought I had removed all the old hackishness ;( */ - -#define IDX_IMPLICIT_REP 41 /* change this if the table changes! */ - -unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx ); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.c deleted file mode 100644 index cc277608b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.c +++ /dev/null @@ -1,623 +0,0 @@ -#include -#include -#include -#include "qword.h" - -#include "ia32_insn.h" -#include "ia32_opcode_tables.h" - -#include "ia32_reg.h" -#include "ia32_operand.h" -#include "ia32_implicit.h" -#include "ia32_settings.h" - -#include "libdis.h" - -extern ia32_table_desc_t ia32_tables[]; -extern ia32_settings_t ia32_settings; - -#define IS_SP( op ) (op->type == op_register && \ - (op->data.reg.id == REG_ESP_INDEX || \ - op->data.reg.alias == REG_ESP_INDEX) ) -#define IS_IMM( op ) (op->type == op_immediate ) - -#ifdef WIN32 -# define INLINE -#else -# define INLINE inline -#endif - -/* for calculating stack modification based on an operand */ -static INLINE int32_t long_from_operand( x86_op_t *op ) { - - if (! IS_IMM(op) ) { - return 0L; - } - - switch ( op->datatype ) { - case op_byte: - return (int32_t) op->data.sbyte; - case op_word: - return (int32_t) op->data.sword; - case op_qword: - return (int32_t) op->data.sqword; - case op_dword: - return op->data.sdword; - default: - /* these are not used in stack insn */ - break; - } - - return 0L; -} - - -/* determine what this insn does to the stack */ -static void ia32_stack_mod(x86_insn_t *insn) { - x86_op_t *dest, *src = NULL; - - if (! insn || ! insn->operands ) { - return; - } - - dest = &insn->operands->op; - if ( dest ) { - src = &insn->operands->next->op; - } - - insn->stack_mod = 0; - insn->stack_mod_val = 0; - - switch ( insn->type ) { - case insn_call: - case insn_callcc: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size * -1; - break; - case insn_push: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size * -1; - break; - case insn_return: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size; - case insn_int: case insn_intcc: - case insn_iret: - break; - case insn_pop: - insn->stack_mod = 1; - if (! IS_SP( dest ) ) { - insn->stack_mod_val = insn->op_size; - } /* else we don't know the stack change in a pop esp */ - break; - case insn_enter: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_leave: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_pushregs: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_popregs: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_pushflags: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_popflags: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_add: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = long_from_operand( src ); - } - break; - case insn_sub: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = long_from_operand( src ); - insn->stack_mod_val *= -1; - } - break; - case insn_inc: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = 1; - } - break; - case insn_dec: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = 1; - } - break; - case insn_mov: case insn_movcc: - case insn_xchg: case insn_xchgcc: - case insn_mul: case insn_div: - case insn_shl: case insn_shr: - case insn_rol: case insn_ror: - case insn_and: case insn_or: - case insn_not: case insn_neg: - case insn_xor: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - } - break; - default: - break; - } - if (! strcmp("enter", insn->mnemonic) ) { - insn->stack_mod = 1; - } else if (! strcmp("leave", insn->mnemonic) ) { - insn->stack_mod = 1; - } - - /* for mov, etc we return 0 -- unknown stack mod */ - - return; -} - -/* get the cpu details for this insn from cpu flags int */ -static void ia32_handle_cpu( x86_insn_t *insn, unsigned int cpu ) { - insn->cpu = (enum x86_insn_cpu) CPU_MODEL(cpu); - insn->isa = (enum x86_insn_isa) (ISA_SUBSET(cpu)) >> 16; - return; -} - -/* handle mnemonic type and group */ -static void ia32_handle_mnemtype(x86_insn_t *insn, unsigned int mnemtype) { - unsigned int type = mnemtype & ~INS_FLAG_MASK; - insn->group = (enum x86_insn_group) (INS_GROUP(type)) >> 12; - insn->type = (enum x86_insn_type) INS_TYPE(type); - - return; -} - -static void ia32_handle_notes(x86_insn_t *insn, unsigned int notes) { - insn->note = (enum x86_insn_note) notes; - return; -} - -static void ia32_handle_eflags( x86_insn_t *insn, unsigned int eflags) { - unsigned int flags; - - /* handle flags effected */ - flags = INS_FLAGS_TEST(eflags); - /* handle weird OR cases */ - /* these are either JLE (ZF | SF<>OF) or JBE (CF | ZF) */ - if (flags & INS_TEST_OR) { - flags &= ~INS_TEST_OR; - if ( flags & INS_TEST_ZERO ) { - flags &= ~INS_TEST_ZERO; - if ( flags & INS_TEST_CARRY ) { - flags &= ~INS_TEST_CARRY ; - flags |= (int)insn_carry_or_zero_set; - } else if ( flags & INS_TEST_SFNEOF ) { - flags &= ~INS_TEST_SFNEOF; - flags |= (int)insn_zero_set_or_sign_ne_oflow; - } - } - } - insn->flags_tested = (enum x86_flag_status) flags; - - insn->flags_set = (enum x86_flag_status) INS_FLAGS_SET(eflags) >> 16; - - return; -} - -static void ia32_handle_prefix( x86_insn_t *insn, unsigned int prefixes ) { - - insn->prefix = (enum x86_insn_prefix) prefixes & PREFIX_MASK; // >> 20; - if (! (insn->prefix & PREFIX_PRINT_MASK) ) { - /* no printable prefixes */ - insn->prefix = insn_no_prefix; - } - - /* concat all prefix strings */ - if ( (unsigned int)insn->prefix & PREFIX_LOCK ) { - strncat(insn->prefix_string, "lock ", 32 - - strlen(insn->prefix_string)); - } - - if ( (unsigned int)insn->prefix & PREFIX_REPNZ ) { - strncat(insn->prefix_string, "repnz ", 32 - - strlen(insn->prefix_string)); - } else if ( (unsigned int)insn->prefix & PREFIX_REPZ ) { - strncat(insn->prefix_string, "repz ", 32 - - strlen(insn->prefix_string)); - } - - return; -} - - -static void reg_32_to_16( x86_op_t *op, x86_insn_t *insn, void *arg ) { - - /* if this is a 32-bit register and it is a general register ... */ - if ( op->type == op_register && op->data.reg.size == 4 && - (op->data.reg.type & reg_gen) ) { - /* WORD registers are 8 indices off from DWORD registers */ - ia32_handle_register( &(op->data.reg), - op->data.reg.id + 8 ); - } -} - -static void handle_insn_metadata( x86_insn_t *insn, ia32_insn_t *raw_insn ) { - ia32_handle_mnemtype( insn, raw_insn->mnem_flag ); - ia32_handle_notes( insn, raw_insn->notes ); - ia32_handle_eflags( insn, raw_insn->flags_effected ); - ia32_handle_cpu( insn, raw_insn->cpu ); - ia32_stack_mod( insn ); -} - -static size_t ia32_decode_insn( unsigned char *buf, size_t buf_len, - ia32_insn_t *raw_insn, x86_insn_t *insn, - unsigned int prefixes ) { - size_t size, op_size; - unsigned char modrm; - - /* this should never happen, but just in case... */ - if ( raw_insn->mnem_flag == INS_INVALID ) { - return 0; - } - - if (ia32_settings.options & opt_16_bit) { - insn->op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2; - insn->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2; - } else { - insn->op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4; - insn->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4; - } - - - /* ++++ 1. Copy mnemonic and mnemonic-flags to CODE struct */ - if ((ia32_settings.options & opt_att_mnemonics) && raw_insn->mnemonic_att[0]) { - strncpy( insn->mnemonic, raw_insn->mnemonic_att, 16 ); - } - else { - strncpy( insn->mnemonic, raw_insn->mnemonic, 16 ); - } - ia32_handle_prefix( insn, prefixes ); - - handle_insn_metadata( insn, raw_insn ); - - /* prefetch the next byte in case it is a modr/m byte -- saves - * worrying about whether the 'mod/rm' operand or the 'reg' operand - * occurs first */ - modrm = GET_BYTE( buf, buf_len ); - - /* ++++ 2. Decode Explicit Operands */ - /* Intel uses up to 3 explicit operands in its instructions; - * the first is 'dest', the second is 'src', and the third - * is an additional source value (usually an immediate value, - * e.g. in the MUL instructions). These three explicit operands - * are encoded in the opcode tables, even if they are not used - * by the instruction. Additional implicit operands are stored - * in a supplemental table and are handled later. */ - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->dest, - raw_insn->dest_flag, prefixes, modrm ); - /* advance buffer, increase size if necessary */ - buf += op_size; - buf_len -= op_size; - size = op_size; - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->src, - raw_insn->src_flag, prefixes, modrm ); - buf += op_size; - buf_len -= op_size; - size += op_size; - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->aux, - raw_insn->aux_flag, prefixes, modrm ); - size += op_size; - - - /* ++++ 3. Decode Implicit Operands */ - /* apply implicit operands */ - ia32_insn_implicit_ops( insn, raw_insn->implicit_ops ); - /* we have one small inelegant hack here, to deal with - * the two prefixes that have implicit operands. If Intel - * adds more, we'll change the algorithm to suit :) */ - if ( (prefixes & PREFIX_REPZ) || (prefixes & PREFIX_REPNZ) ) { - ia32_insn_implicit_ops( insn, IDX_IMPLICIT_REP ); - } - - - /* 16-bit hack: foreach operand, if 32-bit reg, make 16-bit reg */ - if ( insn->op_size == 2 ) { - x86_operand_foreach( insn, reg_32_to_16, NULL, op_any ); - } - - return size; -} - - -/* convenience routine */ -#define USES_MOD_RM(flag) \ - (flag == ADDRMETH_E || flag == ADDRMETH_M || flag == ADDRMETH_Q || \ - flag == ADDRMETH_W || flag == ADDRMETH_R) - -static int uses_modrm_flag( unsigned int flag ) { - unsigned int meth; - if ( flag == ARG_NONE ) { - return 0; - } - meth = (flag & ADDRMETH_MASK); - if ( USES_MOD_RM(meth) ) { - return 1; - } - - return 0; -} - -/* This routine performs the actual byte-by-byte opcode table lookup. - * Originally it was pretty simple: get a byte, adjust it to a proper - * index into the table, then check the table row at that index to - * determine what to do next. But is anything that simple with Intel? - * This is now a huge, convoluted mess, mostly of bitter comments. */ -/* buf: pointer to next byte to read from stream - * buf_len: length of buf - * table: index of table to use for lookups - * raw_insn: output pointer that receives opcode definition - * prefixes: output integer that is encoded with prefixes in insn - * returns : number of bytes consumed from stream during lookup */ -size_t ia32_table_lookup( unsigned char *buf, size_t buf_len, - unsigned int table, ia32_insn_t **raw_insn, - unsigned int *prefixes ) { - unsigned char *next, op = buf[0]; /* byte value -- 'opcode' */ - size_t size = 1, sub_size = 0, next_len; - ia32_table_desc_t *table_desc; - unsigned int subtable, prefix = 0, recurse_table = 0; - - table_desc = &ia32_tables[table]; - - op = GET_BYTE( buf, buf_len ); - - if ( table_desc->type == tbl_fpu && op > table_desc->maxlim) { - /* one of the fucking FPU tables out of the 00-BH range */ - /* OK,. this is a bit of a hack -- the proper way would - * have been to use subtables in the 00-BF FPU opcode tables, - * but that is rather wasteful of space... */ - table_desc = &ia32_tables[table +1]; - } - - /* PERFORM TABLE LOOKUP */ - - /* ModR/M trick: shift extension bits into lowest bits of byte */ - /* Note: non-ModR/M tables have a shift value of 0 */ - op >>= table_desc->shift; - - /* ModR/M trick: mask out high bits to turn extension into an index */ - /* Note: non-ModR/M tables have a mask value of 0xFF */ - op &= table_desc->mask; - - - /* Sparse table trick: check that byte is <= max value */ - /* Note: full (256-entry) tables have a maxlim of 155 */ - if ( op > table_desc->maxlim ) { - /* this is a partial table, truncated at the tail, - and op is out of range! */ - return INVALID_INSN; - } - - /* Sparse table trick: check that byte is >= min value */ - /* Note: full (256-entry) tables have a minlim of 0 */ - if ( table_desc->minlim > op ) { - /* this is a partial table, truncated at the head, - and op is out of range! */ - return INVALID_INSN; - } - /* adjust op to be an offset from table index 0 */ - op -= table_desc->minlim; - - /* Yay! 'op' is now fully adjusted to be an index into 'table' */ - *raw_insn = &(table_desc->table[op]); - //printf("BYTE %X TABLE %d OP %X\n", buf[0], table, op ); - - if ( (*raw_insn)->mnem_flag & INS_FLAG_PREFIX ) { - prefix = (*raw_insn)->mnem_flag & PREFIX_MASK; - } - - - /* handle escape to a multibyte/coproc/extension/etc table */ - /* NOTE: if insn is a prefix and has a subtable, then we - * only recurse if this is the first prefix byte -- - * that is, if *prefixes is 0. - * NOTE also that suffix tables are handled later */ - subtable = (*raw_insn)->table; - - if ( subtable && ia32_tables[subtable].type != tbl_suffix && - (! prefix || ! *prefixes) ) { - - if ( ia32_tables[subtable].type == tbl_ext_ext || - ia32_tables[subtable].type == tbl_fpu_ext ) { - /* opcode extension: reuse current byte in buffer */ - next = buf; - next_len = buf_len; - } else { - /* "normal" opcode: advance to next byte in buffer */ - if ( buf_len > 1 ) { - next = &buf[1]; - next_len = buf_len - 1; - } - else { - // buffer is truncated - return INVALID_INSN; - } - } - /* we encountered a multibyte opcode: recurse using the - * table specified in the opcode definition */ - sub_size = ia32_table_lookup( next, next_len, subtable, - raw_insn, prefixes ); - - /* SSE/prefix hack: if the original opcode def was a - * prefix that specified a subtable, and the subtable - * lookup returned a valid insn, then we have encountered - * an SSE opcode definition; otherwise, we pretend we - * never did the subtable lookup, and deal with the - * prefix normally later */ - if ( prefix && ( sub_size == INVALID_INSN || - INS_TYPE((*raw_insn)->mnem_flag) == INS_INVALID ) ) { - /* this is a prefix, not an SSE insn : - * lookup next byte in main table, - * subsize will be reset during the - * main table lookup */ - recurse_table = 1; - } else { - /* this is either a subtable (two-byte) insn - * or an invalid insn: either way, set prefix - * to NULL and end the opcode lookup */ - prefix = 0; - // short-circuit lookup on invalid insn - if (sub_size == INVALID_INSN) return INVALID_INSN; - } - } else if ( prefix ) { - recurse_table = 1; - } - - /* by default, we assume that we have the opcode definition, - * and there is no need to recurse on the same table, but - * if we do then a prefix was encountered... */ - if ( recurse_table ) { - /* this must have been a prefix: use the same table for - * lookup of the next byte */ - sub_size = ia32_table_lookup( &buf[1], buf_len - 1, table, - raw_insn, prefixes ); - - // short-circuit lookup on invalid insn - if (sub_size == INVALID_INSN) return INVALID_INSN; - - /* a bit of a hack for branch hints */ - if ( prefix & BRANCH_HINT_MASK ) { - if ( INS_GROUP((*raw_insn)->mnem_flag) == INS_EXEC ) { - /* segment override prefixes are invalid for - * all branch instructions, so delete them */ - prefix &= ~PREFIX_REG_MASK; - } else { - prefix &= ~BRANCH_HINT_MASK; - } - } - - /* apply prefix to instruction */ - - /* TODO: implement something enforcing prefix groups */ - (*prefixes) |= prefix; - } - - /* if this lookup was in a ModR/M table, then an opcode byte is - * NOT consumed: subtract accordingly. NOTE that if none of the - * operands used the ModR/M, then we need to consume the byte - * here, but ONLY in the 'top-level' opcode extension table */ - - if ( table_desc->type == tbl_ext_ext ) { - /* extensions-to-extensions never consume a byte */ - --size; - } else if ( (table_desc->type == tbl_extension || - table_desc->type == tbl_fpu || - table_desc->type == tbl_fpu_ext ) && - /* extensions that have an operand encoded in ModR/M - * never consume a byte */ - (uses_modrm_flag((*raw_insn)->dest_flag) || - uses_modrm_flag((*raw_insn)->src_flag) ) ) { - --size; - } - - size += sub_size; - - return size; -} - -static size_t handle_insn_suffix( unsigned char *buf, size_t buf_len, - ia32_insn_t *raw_insn, x86_insn_t * insn ) { - ia32_insn_t *sfx_insn; - size_t size; - unsigned int prefixes = 0; - - size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn, - &prefixes ); - if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) { - return 0; - } - - strncpy( insn->mnemonic, sfx_insn->mnemonic, 16 ); - handle_insn_metadata( insn, sfx_insn ); - - return 1; -} - -/* invalid instructions are handled by returning 0 [error] from the - * function, setting the size of the insn to 1 byte, and copying - * the byte at the start of the invalid insn into the x86_insn_t. - * if the caller is saving the x86_insn_t for invalid instructions, - * instead of discarding them, this will maintain a consistent - * address space in the x86_insn_ts */ - -/* this function is called by the controlling disassembler, so its name and - * calling convention cannot be changed */ -/* buf points to the loc of the current opcode (start of the - * instruction) in the instruction stream. The instruction - * stream is assumed to be a buffer of bytes read directly - * from the file for the purpose of disassembly; a mem-mapped - * file is ideal for * this. - * insn points to a code structure to be filled by instr_decode - * returns the size of the decoded instruction in bytes */ -size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len, - x86_insn_t *insn ) { - ia32_insn_t *raw_insn = NULL; - unsigned int prefixes = 0; - size_t size, sfx_size; - - if ( (ia32_settings.options & opt_ignore_nulls) && buf_len > 3 && - !buf[0] && !buf[1] && !buf[2] && !buf[3]) { - /* IF IGNORE_NULLS is set AND - * first 4 bytes in the intruction stream are NULL - * THEN return 0 (END_OF_DISASSEMBLY) */ - /* TODO: set errno */ - MAKE_INVALID( insn, buf ); - return 0; /* 4 00 bytes in a row? This isn't code! */ - } - - /* Perform recursive table lookup starting with main table (0) */ - size = ia32_table_lookup(buf, buf_len, idx_Main, &raw_insn, &prefixes); - if ( size == INVALID_INSN || size > buf_len || raw_insn->mnem_flag == INS_INVALID ) { - MAKE_INVALID( insn, buf ); - /* TODO: set errno */ - return 0; - } - - /* We now have the opcode itself figured out: we can decode - * the rest of the instruction. */ - size += ia32_decode_insn( &buf[size], buf_len - size, raw_insn, insn, - prefixes ); - if ( raw_insn->mnem_flag & INS_FLAG_SUFFIX ) { - /* AMD 3DNow! suffix -- get proper operand type here */ - sfx_size = handle_insn_suffix( &buf[size], buf_len - size, - raw_insn, insn ); - if (! sfx_size ) { - /* TODO: set errno */ - MAKE_INVALID( insn, buf ); - return 0; - } - - size += sfx_size; - } - - if (! size ) { - /* invalid insn */ - MAKE_INVALID( insn, buf ); - return 0; - } - - - insn->size = size; - return size; /* return size of instruction in bytes */ -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.h deleted file mode 100644 index d3f36c3b2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.h +++ /dev/null @@ -1,506 +0,0 @@ -#ifndef IA32_INSN_H -#define IA32_INSN_H -/* this file contains the structure of opcode definitions and the - * constants they use */ - -#include -#include "libdis.h" - - -#define GET_BYTE( buf, buf_len ) buf_len ? *buf : 0 - -#define OP_SIZE_16 1 -#define OP_SIZE_32 2 -#define ADDR_SIZE_16 4 -#define ADDR_SIZE_32 8 - -#define MAX_INSTRUCTION_SIZE 20 - -/* invalid instructions are handled by returning 0 [error] from the - * function, setting the size of the insn to 1 byte, and copying - * the byte at the start of the invalid insn into the x86_insn_t. - * if the caller is saving the x86_insn_t for invalid instructions, - * instead of discarding them, this will maintain a consistent - * address space in the x86_insn_ts */ - -#define INVALID_INSN ((size_t) -1) /* return value for invalid insn */ -#define MAKE_INVALID( i, buf ) \ - strcpy( i->mnemonic, "invalid" ); \ - x86_oplist_free( i ); \ - i->size = 1; \ - i->group = insn_none; \ - i->type = insn_invalid; \ - memcpy( i->bytes, buf, 1 ); - - -size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len, - x86_insn_t *insn); - - -/* --------------------------------------------------------- Table Lookup */ -/* IA32 Instruction defintion for ia32_opcodes.c */ -typedef struct { - unsigned int table; /* escape to this sub-table */ - unsigned int mnem_flag; /* Flags referring to mnemonic */ - unsigned int notes; /* Notes for this instruction */ - unsigned int dest_flag, src_flag, aux_flag; /* and for specific operands */ - unsigned int cpu; /* minimumCPU [AND with clocks?? */ - char mnemonic[16]; /* buffers for building instruction */ - char mnemonic_att[16]; /* at&t style mnemonic name */ - int32_t dest; - int32_t src; - int32_t aux; - unsigned int flags_effected; - unsigned int implicit_ops; /* implicit operands */ -} ia32_insn_t; - - - -/* --------------------------------------------------------- Prefixes */ -/* Prefix Flags */ -/* Prefixes, same order as in the manual */ -/* had to reverse the values of the first three as they were entered into - * libdis.h incorrectly. */ -#define PREFIX_LOCK 0x0004 -#define PREFIX_REPNZ 0x0002 -#define PREFIX_REPZ 0x0001 -#define PREFIX_OP_SIZE 0x0010 -#define PREFIX_ADDR_SIZE 0x0020 -#define PREFIX_CS 0x0100 -#define PREFIX_SS 0x0200 -#define PREFIX_DS 0x0300 -#define PREFIX_ES 0x0400 -#define PREFIX_FS 0x0500 -#define PREFIX_GS 0x0600 -#define PREFIX_TAKEN 0x1000 /* branch taken */ -#define PREFIX_NOTTAKEN 0x2000 /* branch not taken */ -#define PREFIX_REG_MASK 0x0F00 -#define BRANCH_HINT_MASK 0x3000 -#define PREFIX_PRINT_MASK 0x000F /* printable prefixes */ -#define PREFIX_MASK 0xFFFF - -/* ---------------------------------------------------------- CPU Type */ - -#define cpu_8086 0x0001 -#define cpu_80286 0x0002 -#define cpu_80386 0x0003 -#define cpu_80387 0x0004 /* originally these were a co-proc */ -#define cpu_80486 0x0005 -#define cpu_PENTIUM 0x0006 -#define cpu_PENTPRO 0x0007 -#define cpu_PENTIUM2 0x0008 -#define cpu_PENTIUM3 0x0009 -#define cpu_PENTIUM4 0x000A -#define cpu_K6 0x0010 -#define cpu_K7 0x0020 -#define cpu_ATHLON 0x0030 -#define CPU_MODEL_MASK 0xFFFF -#define CPU_MODEL(cpu) (cpu & CPU_MODEL_MASK) -/* intel instruction subsets */ -#define isa_GP 0x10000 /* General Purpose Instructions */ -#define isa_FPU 0x20000 /* FPU instructions */ -#define isa_FPUMGT 0x30000 /* FPU/SIMD Management */ -#define isa_MMX 0x40000 /* MMX */ -#define isa_SSE1 0x50000 /* SSE */ -#define isa_SSE2 0x60000 /* SSE 2 */ -#define isa_SSE3 0x70000 /* SSE 3 */ -#define isa_3DNOW 0x80000 /* AMD 3d Now */ -#define isa_SYS 0x90000 /* System Instructions */ -#define ISA_SUBSET_MASK 0xFFFF0000 -#define ISA_SUBSET(isa) (isa & ISA_SUBSET_MASK) - - -/* ------------------------------------------------------ Operand Decoding */ -#define ARG_NONE 0 - -/* Using a mask allows us to store info such as OP_SIGNED in the - * operand flags field */ -#define OPFLAGS_MASK 0x0000FFFF - -/* Operand Addressing Methods, per intel manual */ -#define ADDRMETH_MASK 0x00FF0000 - -/* note: for instructions with implied operands, use no ADDRMETH */ -#define ADDRMETH_A 0x00010000 -#define ADDRMETH_C 0x00020000 -#define ADDRMETH_D 0x00030000 -#define ADDRMETH_E 0x00040000 -#define ADDRMETH_F 0x00050000 -#define ADDRMETH_G 0x00060000 -#define ADDRMETH_I 0x00070000 -#define ADDRMETH_J 0x00080000 -#define ADDRMETH_M 0x00090000 -#define ADDRMETH_O 0x000A0000 -#define ADDRMETH_P 0x000B0000 -#define ADDRMETH_Q 0x000C0000 -#define ADDRMETH_R 0x000D0000 -#define ADDRMETH_S 0x000E0000 -#define ADDRMETH_T 0x000F0000 -#define ADDRMETH_V 0x00100000 -#define ADDRMETH_W 0x00110000 -#define ADDRMETH_X 0x00120000 -#define ADDRMETH_Y 0x00130000 -#define ADDRMETH_RR 0x00140000 /* gen reg hard-coded in opcode */ -#define ADDRMETH_RS 0x00150000 /* seg reg hard-coded in opcode */ -#define ADDRMETH_RT 0x00160000 /* test reg hard-coded in opcode */ -#define ADDRMETH_RF 0x00170000 /* fpu reg hard-coded in opcode */ -#define ADDRMETH_II 0x00180000 /* immediate hard-coded in opcode */ -#define ADDRMETH_PP 0x00190000 /* mm reg ONLY in modr/m field */ -#define ADDRMETH_VV 0x001A0000 /* xmm reg ONLY in mod/rm field */ - -/* Operand Types, per intel manual */ -#define OPTYPE_MASK 0xFF000000 - -#define OPTYPE_a 0x01000000 /* BOUND: h:h or w:w */ -#define OPTYPE_b 0x02000000 /* byte */ -#define OPTYPE_c 0x03000000 /* byte or word */ -#define OPTYPE_d 0x04000000 /* word */ -#define OPTYPE_dq 0x05000000 /* qword */ -#define OPTYPE_p 0x06000000 /* 16:16 or 16:32 pointer */ -#define OPTYPE_pi 0x07000000 /* dword MMX reg */ -#define OPTYPE_ps 0x08000000 /* 128-bit single fp */ -#define OPTYPE_q 0x09000000 /* dword */ -#define OPTYPE_s 0x0A000000 /* 6-byte descriptor */ -#define OPTYPE_ss 0x0B000000 /* scalar of 128-bit single fp */ -#define OPTYPE_si 0x0C000000 /* word general register */ -#define OPTYPE_v 0x0D000000 /* hword or word */ -#define OPTYPE_w 0x0E000000 /* hword */ -#define OPTYPE_m 0x0F000000 /* to handle LEA */ -#define OPTYPE_none 0xFF000000 /* no valid operand size, INVLPG */ - -/* custom ones for FPU instructions */ -#define OPTYPE_fs 0x10000000 /* pointer to single-real*/ -#define OPTYPE_fd 0x20000000 /* pointer to double real */ -#define OPTYPE_fe 0x30000000 /* pointer to extended real */ -#define OPTYPE_fb 0x40000000 /* pointer to packed BCD */ -#define OPTYPE_fv 0x50000000 /* pointer to FPU env: 14|28-bytes */ -#define OPTYPE_ft 0x60000000 /* pointer to FPU state: 94|108-bytes */ -#define OPTYPE_fx 0x70000000 /* pointer to FPU regs: 512 bites */ -#define OPTYPE_fp 0x80000000 /* general fpu register: dbl ext */ - -/* SSE2 operand types */ -#define OPTYPE_sd 0x90000000 /* scalar of 128-bit double fp */ -#define OPTYPE_pd 0xA0000000 /* 128-bit double fp */ - - - -/* ---------------------------------------------- Opcode Table Descriptions */ -/* the table type describes how to handle byte/size increments before - * and after lookup. Some tables re-use the current byte, others - * consume a byte only if the ModR/M encodes no operands, etc */ -enum ia32_tbl_type_id { - tbl_opcode = 0, /* standard opcode table: no surprises */ - tbl_prefix, /* Prefix Override, e.g. 66/F2/F3 */ - tbl_suffix, /* 3D Now style */ - tbl_extension, /* ModR/M extension: 00-FF -> 00-07 */ - tbl_ext_ext, /* extension of modr/m using R/M field */ - tbl_fpu, /* fpu table: 00-BF -> 00-0F */ - tbl_fpu_ext /* fpu extension : C0-FF -> 00-1F */ - }; - -/* How it works: - * Bytes are 'consumed' if the next table lookup requires that the byte - * pointer be advanced in the instruction stream. 'Does not consume' means - * that, when the lookup function recurses, the same byte it re-used in the - * new table. It also means that size is not decremented, for example when - * a ModR/M byte is used. Note that tbl_extension (ModR/M) instructions that - * do not increase the size of an insn with their operands have a forced - 3 size increase in the lookup algo. Weird, yes, confusing, yes, welcome - * to the Intel ISA. Another note: tbl_prefix is used as an override, so an - * empty insn in a prefix table causes the instruction in the original table - * to be used, rather than an invalid insn being generated. - * tbl_opcode uses current byte and consumes it - * tbl_prefix uses current byte but does not consume it - * tbl_suffix uses and consumes last byte in insn - * tbl_extension uses current byte but does not consume it - * tbl_ext_ext uses current byte but does not consume it - * tbl_fpu uses current byte and consumes it - * tbl_fpu_ext uses current byte but does not consume it - */ - -/* Convenience struct for opcode tables : these will be stored in a - * 'table of tables' so we can use a table index instead of a pointer */ -typedef struct { /* Assembly instruction tables */ - ia32_insn_t *table; /* Pointer to table of instruction encodings */ - enum ia32_tbl_type_id type; - unsigned char shift; /* amount to shift modrm byte */ - unsigned char mask; /* bit mask for look up */ - unsigned char minlim,maxlim; /* limits on min/max entries. */ -} ia32_table_desc_t; - - -/* ---------------------------------------------- 'Cooked' Operand Type Info */ -/* Permissions: */ -#define OP_R 0x001 /* operand is READ */ -#define OP_W 0x002 /* operand is WRITTEN */ -#define OP_RW 0x003 /* (OP_R|OP_W): convenience macro */ -#define OP_X 0x004 /* operand is EXECUTED */ - -#define OP_PERM_MASK 0x0000007 /* perms are NOT mutually exclusive */ -#define OP_PERM( type ) (type & OP_PERM_MASK) - -/* Flags */ -#define OP_SIGNED 0x010 /* operand is signed */ - -#define OP_FLAG_MASK 0x0F0 /* mods are NOT mutually exclusive */ -#define OP_FLAGS( type ) (type & OP_FLAG_MASK) - -#define OP_REG_MASK 0x0000FFFF /* lower WORD is register ID */ -#define OP_REGTBL_MASK 0xFFFF0000 /* higher word is register type [gen/dbg] */ -#define OP_REGID( type ) (type & OP_REG_MASK) -#define OP_REGTYPE( type ) (type & OP_REGTBL_MASK) - -/* ------------------------------------------'Cooked' Instruction Type Info */ -/* high-bit opcode types/insn meta-types */ -#define INS_FLAG_PREFIX 0x10000000 /* insn is a prefix */ -#define INS_FLAG_SUFFIX 0x20000000 /* followed by a suffix byte */ -#define INS_FLAG_MASK 0xFF000000 - -/* insn notes */ -#define INS_NOTE_RING0 0x00000001 /* insn is privileged */ -#define INS_NOTE_SMM 0x00000002 /* Sys Mgt Mode only */ -#define INS_NOTE_SERIAL 0x00000004 /* serializes */ -#define INS_NOTE_NONSWAP 0x00000008 /* insn is not swapped in att format */ // could be separate field? -#define INS_NOTE_NOSUFFIX 0x00000010 /* insn has no size suffix in att format */ // could be separate field? -//#define INS_NOTE_NMI - -#define INS_INVALID 0 - -/* instruction groups */ -#define INS_EXEC 0x1000 -#define INS_ARITH 0x2000 -#define INS_LOGIC 0x3000 -#define INS_STACK 0x4000 -#define INS_COND 0x5000 -#define INS_LOAD 0x6000 -#define INS_ARRAY 0x7000 -#define INS_BIT 0x8000 -#define INS_FLAG 0x9000 -#define INS_FPU 0xA000 -#define INS_TRAPS 0xD000 -#define INS_SYSTEM 0xE000 -#define INS_OTHER 0xF000 - -#define INS_GROUP_MASK 0xF000 -#define INS_GROUP( type ) ( type & INS_GROUP_MASK ) - -/* INS_EXEC group */ -#define INS_BRANCH (INS_EXEC | 0x01) /* Unconditional branch */ -#define INS_BRANCHCC (INS_EXEC | 0x02) /* Conditional branch */ -#define INS_CALL (INS_EXEC | 0x03) /* Jump to subroutine */ -#define INS_CALLCC (INS_EXEC | 0x04) /* Jump to subroutine */ -#define INS_RET (INS_EXEC | 0x05) /* Return from subroutine */ - -/* INS_ARITH group */ -#define INS_ADD (INS_ARITH | 0x01) -#define INS_SUB (INS_ARITH | 0x02) -#define INS_MUL (INS_ARITH | 0x03) -#define INS_DIV (INS_ARITH | 0x04) -#define INS_INC (INS_ARITH | 0x05) /* increment */ -#define INS_DEC (INS_ARITH | 0x06) /* decrement */ -#define INS_SHL (INS_ARITH | 0x07) /* shift right */ -#define INS_SHR (INS_ARITH | 0x08) /* shift left */ -#define INS_ROL (INS_ARITH | 0x09) /* rotate left */ -#define INS_ROR (INS_ARITH | 0x0A) /* rotate right */ -#define INS_MIN (INS_ARITH | 0x0B) /* min func */ -#define INS_MAX (INS_ARITH | 0x0C) /* max func */ -#define INS_AVG (INS_ARITH | 0x0D) /* avg func */ -#define INS_FLR (INS_ARITH | 0x0E) /* floor func */ -#define INS_CEIL (INS_ARITH | 0x0F) /* ceiling func */ - -/* INS_LOGIC group */ -#define INS_AND (INS_LOGIC | 0x01) -#define INS_OR (INS_LOGIC | 0x02) -#define INS_XOR (INS_LOGIC | 0x03) -#define INS_NOT (INS_LOGIC | 0x04) -#define INS_NEG (INS_LOGIC | 0x05) -#define INS_NAND (INS_LOGIC | 0x06) - -/* INS_STACK group */ -#define INS_PUSH (INS_STACK | 0x01) -#define INS_POP (INS_STACK | 0x02) -#define INS_PUSHREGS (INS_STACK | 0x03) /* push register context */ -#define INS_POPREGS (INS_STACK | 0x04) /* pop register context */ -#define INS_PUSHFLAGS (INS_STACK | 0x05) /* push all flags */ -#define INS_POPFLAGS (INS_STACK | 0x06) /* pop all flags */ -#define INS_ENTER (INS_STACK | 0x07) /* enter stack frame */ -#define INS_LEAVE (INS_STACK | 0x08) /* leave stack frame */ - -/* INS_COND group */ -#define INS_TEST (INS_COND | 0x01) -#define INS_CMP (INS_COND | 0x02) - -/* INS_LOAD group */ -#define INS_MOV (INS_LOAD | 0x01) -#define INS_MOVCC (INS_LOAD | 0x02) -#define INS_XCHG (INS_LOAD | 0x03) -#define INS_XCHGCC (INS_LOAD | 0x04) -#define INS_CONV (INS_LOAD | 0x05) /* move and convert type */ - -/* INS_ARRAY group */ -#define INS_STRCMP (INS_ARRAY | 0x01) -#define INS_STRLOAD (INS_ARRAY | 0x02) -#define INS_STRMOV (INS_ARRAY | 0x03) -#define INS_STRSTOR (INS_ARRAY | 0x04) -#define INS_XLAT (INS_ARRAY | 0x05) - -/* INS_BIT group */ -#define INS_BITTEST (INS_BIT | 0x01) -#define INS_BITSET (INS_BIT | 0x02) -#define INS_BITCLR (INS_BIT | 0x03) - -/* INS_FLAG group */ -#define INS_CLEARCF (INS_FLAG | 0x01) /* clear Carry flag */ -#define INS_CLEARZF (INS_FLAG | 0x02) /* clear Zero flag */ -#define INS_CLEAROF (INS_FLAG | 0x03) /* clear Overflow flag */ -#define INS_CLEARDF (INS_FLAG | 0x04) /* clear Direction flag */ -#define INS_CLEARSF (INS_FLAG | 0x05) /* clear Sign flag */ -#define INS_CLEARPF (INS_FLAG | 0x06) /* clear Parity flag */ -#define INS_SETCF (INS_FLAG | 0x07) -#define INS_SETZF (INS_FLAG | 0x08) -#define INS_SETOF (INS_FLAG | 0x09) -#define INS_SETDF (INS_FLAG | 0x0A) -#define INS_SETSF (INS_FLAG | 0x0B) -#define INS_SETPF (INS_FLAG | 0x0C) -#define INS_TOGCF (INS_FLAG | 0x10) /* toggle */ -#define INS_TOGZF (INS_FLAG | 0x20) -#define INS_TOGOF (INS_FLAG | 0x30) -#define INS_TOGDF (INS_FLAG | 0x40) -#define INS_TOGSF (INS_FLAG | 0x50) -#define INS_TOGPF (INS_FLAG | 0x60) - -/* INS_FPU */ -#define INS_FMOV (INS_FPU | 0x1) -#define INS_FMOVCC (INS_FPU | 0x2) -#define INS_FNEG (INS_FPU | 0x3) -#define INS_FABS (INS_FPU | 0x4) -#define INS_FADD (INS_FPU | 0x5) -#define INS_FSUB (INS_FPU | 0x6) -#define INS_FMUL (INS_FPU | 0x7) -#define INS_FDIV (INS_FPU | 0x8) -#define INS_FSQRT (INS_FPU | 0x9) -#define INS_FCMP (INS_FPU | 0xA) -#define INS_FCOS (INS_FPU | 0xC) /* cosine */ -#define INS_FLDPI (INS_FPU | 0xD) /* load pi */ -#define INS_FLDZ (INS_FPU | 0xE) /* load 0 */ -#define INS_FTAN (INS_FPU | 0xF) /* tanget */ -#define INS_FSINE (INS_FPU | 0x10) /* sine */ -#define INS_FSYS (INS_FPU | 0x20) /* misc */ - -/* INS_TRAP */ -#define INS_TRAP (INS_TRAPS | 0x01) /* generate trap */ -#define INS_TRAPCC (INS_TRAPS | 0x02) /* conditional trap gen */ -#define INS_TRET (INS_TRAPS | 0x03) /* return from trap */ -#define INS_BOUNDS (INS_TRAPS | 0x04) /* gen bounds trap */ -#define INS_DEBUG (INS_TRAPS | 0x05) /* gen breakpoint trap */ -#define INS_TRACE (INS_TRAPS | 0x06) /* gen single step trap */ -#define INS_INVALIDOP (INS_TRAPS | 0x07) /* gen invalid insn */ -#define INS_OFLOW (INS_TRAPS | 0x08) /* gen overflow trap */ -#define INS_ICEBP (INS_TRAPS | 0x09) /* ICE breakpoint */ - -/* INS_SYSTEM */ -#define INS_HALT (INS_SYSTEM | 0x01) /* halt machine */ -#define INS_IN (INS_SYSTEM | 0x02) /* input form port */ -#define INS_OUT (INS_SYSTEM | 0x03) /* output to port */ -#define INS_CPUID (INS_SYSTEM | 0x04) /* identify cpu */ - -/* INS_OTHER */ -#define INS_NOP (INS_OTHER | 0x01) -#define INS_BCDCONV (INS_OTHER | 0x02) /* convert to/from BCD */ -#define INS_SZCONV (INS_OTHER | 0x03) /* convert size of operand */ -#define INS_SALC (INS_OTHER | 0x04) /* set %al on carry */ -#define INS_UNKNOWN (INS_OTHER | 0x05) - - -#define INS_TYPE_MASK 0xFFFF -#define INS_TYPE( type ) ( type & INS_TYPE_MASK ) - - /* flags effected by instruction */ -#define INS_TEST_CARRY 0x01 /* carry */ -#define INS_TEST_ZERO 0x02 /* zero/equal */ -#define INS_TEST_OFLOW 0x04 /* overflow */ -#define INS_TEST_DIR 0x08 /* direction */ -#define INS_TEST_SIGN 0x10 /* negative */ -#define INS_TEST_PARITY 0x20 /* parity */ -#define INS_TEST_OR 0x40 /* used in jle */ -#define INS_TEST_NCARRY 0x100 /* ! carry */ -#define INS_TEST_NZERO 0x200 /* ! zero */ -#define INS_TEST_NOFLOW 0x400 /* ! oflow */ -#define INS_TEST_NDIR 0x800 /* ! dir */ -#define INS_TEST_NSIGN 0x100 /* ! sign */ -#define INS_TEST_NPARITY 0x2000 /* ! parity */ -/* SF == OF */ -#define INS_TEST_SFEQOF 0x4000 -/* SF != OF */ -#define INS_TEST_SFNEOF 0x8000 - -#define INS_TEST_ALL INS_TEST_CARRY | INS_TEST_ZERO | \ - INS_TEST_OFLOW | INS_TEST_SIGN | \ - INS_TEST_PARITY - -#define INS_SET_CARRY 0x010000 /* carry */ -#define INS_SET_ZERO 0x020000 /* zero/equal */ -#define INS_SET_OFLOW 0x040000 /* overflow */ -#define INS_SET_DIR 0x080000 /* direction */ -#define INS_SET_SIGN 0x100000 /* negative */ -#define INS_SET_PARITY 0x200000 /* parity */ -#define INS_SET_NCARRY 0x1000000 -#define INS_SET_NZERO 0x2000000 -#define INS_SET_NOFLOW 0x4000000 -#define INS_SET_NDIR 0x8000000 -#define INS_SET_NSIGN 0x10000000 -#define INS_SET_NPARITY 0x20000000 -#define INS_SET_SFEQOF 0x40000000 -#define INS_SET_SFNEOF 0x80000000 - -#define INS_SET_ALL INS_SET_CARRY | INS_SET_ZERO | \ - INS_SET_OFLOW | INS_SET_SIGN | \ - INS_SET_PARITY - -#define INS_TEST_MASK 0x0000FFFF -#define INS_FLAGS_TEST(x) (x & INS_TEST_MASK) -#define INS_SET_MASK 0xFFFF0000 -#define INS_FLAGS_SET(x) (x & INS_SET_MASK) - -#if 0 -/* TODO: actually start using these */ -#define X86_PAIR_NP 1 /* not pairable; execs in U */ -#define X86_PAIR_PU 2 /* pairable in U pipe */ -#define X86_PAIR_PV 3 /* pairable in V pipe */ -#define X86_PAIR_UV 4 /* pairable in UV pipe */ -#define X86_PAIR_FX 5 /* pairable with FXCH */ - -#define X86_EXEC_PORT_0 1 -#define X86_EXEC_PORT_1 2 -#define X86_EXEC_PORT_2 4 -#define X86_EXEC_PORT_3 8 -#define X86_EXEC_PORT_4 16 - -#define X86_EXEC_UNITS - -typedef struct { /* representation of an insn during decoding */ - uint32_t flags; /* runtime settings */ - /* instruction prefixes and other foolishness */ - uint32_t prefix; /* encoding of prefix */ - char prefix_str[16]; /* mnemonics for prefix */ - uint32_t branch_hint; /* gah! */ - unsigned int cpu_ver; /* TODO: cpu version */ - unsigned int clocks; /* TODO: clock cycles: min/max */ - unsigned char last_prefix; - /* runtime intruction decoding helpers */ - unsigned char mode; /* 16, 32, 64 */ - unsigned char gen_regs; /* offset of default general reg set */ - unsigned char sz_operand; /* operand size for insn */ - unsigned char sz_address; /* address size for insn */ - unsigned char uops; /* uops per insn */ - unsigned char pairing; /* np,pu,pv.lv */ - unsigned char exec_unit; - unsigned char exec_port; - unsigned char latency; -} ia32_info_t; -#define MODE_32 0 /* default */ -#define MODE_16 1 -#define MODE_64 2 -#endif - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.c deleted file mode 100644 index 68ec153d2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.c +++ /dev/null @@ -1,313 +0,0 @@ -#include -#include - -#include "ia32_invariant.h" -#include "ia32_insn.h" -#include "ia32_settings.h" - -extern ia32_table_desc_t *ia32_tables; -extern ia32_settings_t ia32_settings; - -extern size_t ia32_table_lookup( unsigned char *buf, size_t buf_len, - unsigned int table, ia32_insn_t **raw_insn, - unsigned int *prefixes ); - - -/* -------------------------------- ModR/M, SIB */ -/* Convenience flags */ -#define MODRM_EA 1 /* ModR/M is an effective addr */ -#define MODRM_reg 2 /* ModR/M is a register */ - -/* ModR/M flags */ -#define MODRM_RM_SIB 0x04 /* R/M == 100 */ -#define MODRM_RM_NOREG 0x05 /* R/B == 101 */ -/* if (MODRM.MOD_NODISP && MODRM.RM_NOREG) then just disp32 */ -#define MODRM_MOD_NODISP 0x00 /* mod == 00 */ -#define MODRM_MOD_DISP8 0x01 /* mod == 01 */ -#define MODRM_MOD_DISP32 0x02 /* mod == 10 */ -#define MODRM_MOD_NOEA 0x03 /* mod == 11 */ -/* 16-bit modrm flags */ -#define MOD16_MOD_NODISP 0 -#define MOD16_MOD_DISP8 1 -#define MOD16_MOD_DISP16 2 -#define MOD16_MOD_REG 3 - -#define MOD16_RM_BXSI 0 -#define MOD16_RM_BXDI 1 -#define MOD16_RM_BPSI 2 -#define MOD16_RM_BPDI 3 -#define MOD16_RM_SI 4 -#define MOD16_RM_DI 5 -#define MOD16_RM_BP 6 -#define MOD16_RM_BX 7 - -/* SIB flags */ -#define SIB_INDEX_NONE 0x04 -#define SIB_BASE_EBP 0x05 -#define SIB_SCALE_NOBASE 0x00 - -/* Convenience struct for modR/M bitfield */ -struct modRM_byte { - unsigned int mod : 2; - unsigned int reg : 3; - unsigned int rm : 3; -}; - -/* Convenience struct for SIB bitfield */ -struct SIB_byte { - unsigned int scale : 2; - unsigned int index : 3; - unsigned int base : 3; -}; - -#ifdef WIN32 -static void byte_decode(unsigned char b, struct modRM_byte *modrm) { -#else -static inline void byte_decode(unsigned char b, struct modRM_byte *modrm) { -#endif - /* generic bitfield-packing routine */ - - modrm->mod = b >> 6; /* top 2 bits */ - modrm->reg = (b & 56) >> 3; /* middle 3 bits */ - modrm->rm = b & 7; /* bottom 3 bits */ -} -static int ia32_invariant_modrm( unsigned char *in, unsigned char *out, - unsigned int mode_16, x86_invariant_op_t *op) { - struct modRM_byte modrm; - struct SIB_byte sib; - unsigned char *c, *cin; - unsigned short *s; - unsigned int *i; - int size = 0; /* modrm byte is already counted */ - - - byte_decode(*in, &modrm); /* get bitfields */ - - out[0] = in[0]; /* save modrm byte */ - cin = &in[1]; - c = &out[1]; - s = (unsigned short *)&out[1]; - i = (unsigned int *)&out[1]; - - op->type = op_expression; - op->flags |= op_pointer; - if ( ! mode_16 && modrm.rm == MODRM_RM_SIB && - modrm.mod != MODRM_MOD_NOEA ) { - size ++; - byte_decode(*cin, (struct modRM_byte *)(void*)&sib); - - out[1] = in[1]; /* save sib byte */ - cin = &in[2]; - c = &out[2]; - s = (unsigned short *)&out[2]; - i = (unsigned int *)&out[2]; - - if ( sib.base == SIB_BASE_EBP && ! modrm.mod ) { - /* disp 32 is variant! */ - memset( i, X86_WILDCARD_BYTE, 4 ); - size += 4; - } - } - - if (! modrm.mod && modrm.rm == 101) { - if ( mode_16 ) { /* straight RVA in disp */ - memset( s, X86_WILDCARD_BYTE, 2 ); - size += 2; - } else { - memset( i, X86_WILDCARD_BYTE, 2 ); - size += 4; - } - } else if (modrm.mod && modrm.mod < 3) { - if (modrm.mod == MODRM_MOD_DISP8) { /* offset in disp */ - *c = *cin; - size += 1; - } else if ( mode_16 ) { - *s = (* ((unsigned short *) cin)); - size += 2; - } else { - *i = (*((unsigned int *) cin)); - size += 4; - } - } else if ( modrm.mod == 3 ) { - op->type = op_register; - op->flags &= ~op_pointer; - } - - return (size); -} - - -static int ia32_decode_invariant( unsigned char *buf, size_t buf_len, - ia32_insn_t *t, unsigned char *out, - unsigned int prefixes, x86_invariant_t *inv) { - - unsigned int addr_size, op_size, mode_16; - unsigned int op_flags[3] = { t->dest_flag, t->src_flag, t->aux_flag }; - int x, type, bytes = 0, size = 0, modrm = 0; - - /* set addressing mode */ - if (ia32_settings.options & opt_16_bit) { - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2; - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2; - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 0 : 1; - } else { - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4; - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4; - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 1 : 0; - } - - for (x = 0; x < 3; x++) { - inv->operands[x].access = (enum x86_op_access) - OP_PERM(op_flags[x]); - inv->operands[x].flags = (enum x86_op_flags) - (OP_FLAGS(op_flags[x]) >> 12); - - switch (op_flags[x] & OPTYPE_MASK) { - case OPTYPE_c: - size = (op_size == 4) ? 2 : 1; - break; - case OPTYPE_a: case OPTYPE_v: - size = (op_size == 4) ? 4 : 2; - break; - case OPTYPE_p: - size = (op_size == 4) ? 6 : 4; - break; - case OPTYPE_b: - size = 1; - break; - case OPTYPE_w: - size = 2; - break; - case OPTYPE_d: case OPTYPE_fs: case OPTYPE_fd: - case OPTYPE_fe: case OPTYPE_fb: case OPTYPE_fv: - case OPTYPE_si: case OPTYPE_fx: - size = 4; - break; - case OPTYPE_s: - size = 6; - break; - case OPTYPE_q: case OPTYPE_pi: - size = 8; - break; - case OPTYPE_dq: case OPTYPE_ps: case OPTYPE_ss: - case OPTYPE_pd: case OPTYPE_sd: - size = 16; - break; - case OPTYPE_m: - size = (addr_size == 4) ? 4 : 2; - break; - default: - break; - } - - type = op_flags[x] & ADDRMETH_MASK; - switch (type) { - case ADDRMETH_E: case ADDRMETH_M: case ADDRMETH_Q: - case ADDRMETH_R: case ADDRMETH_W: - modrm = 1; - bytes += ia32_invariant_modrm( buf, out, - mode_16, &inv->operands[x]); - break; - case ADDRMETH_C: case ADDRMETH_D: case ADDRMETH_G: - case ADDRMETH_P: case ADDRMETH_S: case ADDRMETH_T: - case ADDRMETH_V: - inv->operands[x].type = op_register; - modrm = 1; - break; - case ADDRMETH_A: case ADDRMETH_O: - /* pad with xF4's */ - memset( &out[bytes + modrm], X86_WILDCARD_BYTE, - size ); - bytes += size; - inv->operands[x].type = op_offset; - if ( type == ADDRMETH_O ) { - inv->operands[x].flags |= op_signed | - op_pointer; - } - break; - case ADDRMETH_I: case ADDRMETH_J: - /* grab imm value */ - if ((op_flags[x] & OPTYPE_MASK) == OPTYPE_v) { - /* assume this is an address */ - memset( &out[bytes + modrm], - X86_WILDCARD_BYTE, size ); - } else { - memcpy( &out[bytes + modrm], - &buf[bytes + modrm], size ); - } - - bytes += size; - if ( type == ADDRMETH_J ) { - if ( size == 1 ) { - inv->operands[x].type = - op_relative_near; - } else { - inv->operands[x].type = - op_relative_far; - } - inv->operands[x].flags |= op_signed; - } else { - inv->operands[x].type = op_immediate; - } - break; - case ADDRMETH_F: - inv->operands[x].type = op_register; - break; - case ADDRMETH_X: - inv->operands[x].flags |= op_signed | - op_pointer | op_ds_seg | op_string; - break; - case ADDRMETH_Y: - inv->operands[x].flags |= op_signed | - op_pointer | op_es_seg | op_string; - break; - case ADDRMETH_RR: - inv->operands[x].type = op_register; - break; - case ADDRMETH_II: - inv->operands[x].type = op_immediate; - break; - default: - inv->operands[x].type = op_unused; - break; - } - } - - return (bytes + modrm); -} - -size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len, - x86_invariant_t *inv ) { - ia32_insn_t *raw_insn = NULL; - unsigned int prefixes; - unsigned int type; - size_t size; - - /* Perform recursive table lookup starting with main table (0) */ - size = ia32_table_lookup( buf, buf_len, 0, &raw_insn, &prefixes ); - if ( size == INVALID_INSN || size > buf_len ) { - /* TODO: set errno */ - return 0; - } - - /* copy opcode bytes to buffer */ - memcpy( inv->bytes, buf, size ); - - /* set mnemonic type and group */ - type = raw_insn->mnem_flag & ~INS_FLAG_MASK; - inv->group = (enum x86_insn_group) (INS_GROUP(type)) >> 12; - inv->type = (enum x86_insn_type) INS_TYPE(type); - - /* handle operands */ - size += ia32_decode_invariant( buf + size, buf_len - size, raw_insn, - &buf[size - 1], prefixes, inv ); - - inv->size = size; - - return size; /* return size of instruction in bytes */ -} - -size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) { - x86_invariant_t inv = { {0} }; - return( ia32_disasm_invariant( buf, buf_len, &inv ) ); -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.h deleted file mode 100644 index e1cea60e9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_invariant.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IA32_INVARIANT_H -#define IA32_INVARIANT_H - -#include "libdis.h" - -size_t ia32_disasm_invariant( unsigned char *buf, size_t buf_len, - x86_invariant_t *inv); - -size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.c deleted file mode 100644 index b0fe2ed3d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.c +++ /dev/null @@ -1,310 +0,0 @@ -#include "ia32_modrm.h" -#include "ia32_reg.h" -#include "x86_imm.h" - -/* NOTE: when decoding ModR/M and SIB, we have to add 1 to all register - * values obtained from decoding the ModR/M or SIB byte, since they - * are encoded with eAX = 0 and the tables in ia32_reg.c use eAX = 1. - * ADDENDUM: this is only the case when the register value is used - * directly as an index into the register table, not when it is added to - * a genregs offset. */ - -/* -------------------------------- ModR/M, SIB */ -/* ModR/M flags */ -#define MODRM_RM_SIB 0x04 /* R/M == 100 */ -#define MODRM_RM_NOREG 0x05 /* R/B == 101 */ - -/* if (MODRM.MOD_NODISP && MODRM.RM_NOREG) then just disp32 */ -#define MODRM_MOD_NODISP 0x00 /* mod == 00 */ -#define MODRM_MOD_DISP8 0x01 /* mod == 01 */ -#define MODRM_MOD_DISP32 0x02 /* mod == 10 */ -#define MODRM_MOD_NOEA 0x03 /* mod == 11 */ - -/* 16-bit modrm flags */ -#define MOD16_MOD_NODISP 0 -#define MOD16_MOD_DISP8 1 -#define MOD16_MOD_DISP16 2 -#define MOD16_MOD_REG 3 - -#define MOD16_RM_BXSI 0 -#define MOD16_RM_BXDI 1 -#define MOD16_RM_BPSI 2 -#define MOD16_RM_BPDI 3 -#define MOD16_RM_SI 4 -#define MOD16_RM_DI 5 -#define MOD16_RM_BP 6 -#define MOD16_RM_BX 7 - -/* SIB flags */ -#define SIB_INDEX_NONE 0x04 -#define SIB_BASE_EBP 0x05 -#define SIB_SCALE_NOBASE 0x00 - -/* Convenience struct for modR/M bitfield */ -struct modRM_byte { - unsigned int mod : 2; - unsigned int reg : 3; - unsigned int rm : 3; -}; - -/* Convenience struct for SIB bitfield */ -struct SIB_byte { - unsigned int scale : 2; - unsigned int index : 3; - unsigned int base : 3; -}; - - -#if 0 -int modrm_rm[] = {0,1,2,3,MODRM_RM_SIB,MODRM_MOD_DISP32,6,7}; -int modrm_reg[] = {0, 1, 2, 3, 4, 5, 6, 7}; -int modrm_mod[] = {0, MODRM_MOD_DISP8, MODRM_MOD_DISP32, MODRM_MOD_NOEA}; -int sib_scl[] = {0, 2, 4, 8}; -int sib_idx[] = {0, 1, 2, 3, SIB_INDEX_NONE, 5, 6, 7 }; -int sib_bas[] = {0, 1, 2, 3, 4, SIB_SCALE_NOBASE, 6, 7 }; -#endif - -/* this is needed to replace x86_imm_signsized() which does not sign-extend - * to dest */ -static unsigned int imm32_signsized( unsigned char *buf, size_t buf_len, - int32_t *dest, unsigned int size ) { - if ( size > buf_len ) { - return 0; - } - - switch (size) { - case 1: - *dest = *((signed char *) buf); - break; - case 2: - *dest = *((signed short *) buf); - break; - case 4: - default: - *dest = *((signed int *) buf); - break; - } - - return size; -} - - - -static void byte_decode(unsigned char b, struct modRM_byte *modrm) { - /* generic bitfield-packing routine */ - - modrm->mod = b >> 6; /* top 2 bits */ - modrm->reg = (b & 56) >> 3; /* middle 3 bits */ - modrm->rm = b & 7; /* bottom 3 bits */ -} - - -static size_t sib_decode( unsigned char *buf, size_t buf_len, x86_ea_t *ea, - unsigned int mod ) { - /* set Address Expression fields (scale, index, base, disp) - * according to the contents of the SIB byte. - * b points to the SIB byte in the instruction-stream buffer; the - * byte after b[0] is therefore the byte after the SIB - * returns number of bytes 'used', including the SIB byte */ - size_t size = 1; /* start at 1 for SIB byte */ - struct SIB_byte sib; - - if ( buf_len < 1 ) { - return 0; - } - - byte_decode( *buf, (struct modRM_byte *)(void*)&sib ); /* get bit-fields */ - - if ( sib.base == SIB_BASE_EBP && ! mod ) { /* if base == 101 (ebp) */ - /* IF BASE == EBP, deal with exception */ - /* IF (ModR/M did not create a Disp */ - /* ... create a 32-bit Displacement */ - imm32_signsized( &buf[1], buf_len, &ea->disp, sizeof(int32_t)); - ea->disp_size = sizeof(int32_t); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; /* add sizeof disp to count */ - - } else { - /* ELSE BASE refers to a General Register */ - ia32_handle_register( &ea->base, sib.base + 1 ); - } - - /* set scale to 1, 2, 4, 8 */ - ea->scale = 1 << sib.scale; - - if (sib.index != SIB_INDEX_NONE) { - /* IF INDEX is not 'ESP' (100) */ - ia32_handle_register( &ea->index, sib.index + 1 ); - } - - return (size); /* return number of bytes processed */ -} - -static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, struct modRM_byte *modrm ) { - /* 16-bit mode: hackish, but not as hackish as 32-bit mode ;) */ - size_t size = 1; /* # of bytes decoded [1 for modR/M byte] */ - x86_ea_t * ea = &op->data.expression; - - switch( modrm->rm ) { - case MOD16_RM_BXSI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_BXDI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); - case MOD16_RM_BPSI: - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_BPDI: - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); - break; - case MOD16_RM_SI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_DI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 7); - break; - case MOD16_RM_BP: - if ( modrm->mod != MOD16_MOD_NODISP ) { - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, - REG_WORD_OFFSET + 5); - } - break; - case MOD16_RM_BX: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - break; - } - - /* move to byte after ModR/M */ - ++buf; - --buf_len; - - if ( modrm->mod == MOD16_MOD_DISP8 ) { - imm32_signsized( buf, buf_len, &ea->disp, sizeof(char) ); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - ea->disp_size = sizeof(char); - size += sizeof(char); - } else if ( modrm->mod == MOD16_MOD_DISP16 ) { - imm32_signsized( buf, buf_len, &ea->disp, sizeof(short) ); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - ea->disp_size = sizeof(short); - size += sizeof(short); - } - - return size; -} - -/* TODO : Mark index modes - Use addressing mode flags to imply arrays (index), structure (disp), - two-dimensional arrays [disp + index], classes [ea reg], and so on. -*/ -size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, x86_insn_t *insn, size_t gen_regs ) { - /* create address expression and/or fill operand based on value of - * ModR/M byte. Calls sib_decode as appropriate. - * flags specifies whether Reg or mod+R/M fields are being decoded - * returns the number of bytes in the instruction, including modR/M */ - struct modRM_byte modrm; - size_t size = 1; /* # of bytes decoded [1 for modR/M byte] */ - x86_ea_t * ea; - - - byte_decode(*buf, &modrm); /* get bitfields */ - - /* first, handle the case where the mod field is a register only */ - if ( modrm.mod == MODRM_MOD_NOEA ) { - op->type = op_register; - ia32_handle_register(&op->data.reg, modrm.rm + gen_regs); - /* increase insn size by 1 for modrm byte */ - return 1; - } - - /* then deal with cases where there is an effective address */ - ea = &op->data.expression; - op->type = op_expression; - op->flags |= op_pointer; - - if ( insn->addr_size == 2 ) { - /* gah! 16 bit mode! */ - return modrm_decode16( buf, buf_len, op, &modrm); - } - - /* move to byte after ModR/M */ - ++buf; - --buf_len; - - if (modrm.mod == MODRM_MOD_NODISP) { /* if mod == 00 */ - - /* IF MOD == No displacement, just Indirect Register */ - if (modrm.rm == MODRM_RM_NOREG) { /* if r/m == 101 */ - /* IF RM == No Register, just Displacement */ - /* This is an Intel Moronic Exception TM */ - imm32_signsized( buf, buf_len, &ea->disp, - sizeof(int32_t) ); - ea->disp_size = sizeof(int32_t); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; /* add sizeof disp to count */ - - } else if (modrm.rm == MODRM_RM_SIB) { /* if r/m == 100 */ - /* ELSE IF an SIB byte is present */ - /* TODO: check for 0 retval */ - size += sib_decode( buf, buf_len, ea, modrm.mod); - /* move to byte after SIB for displacement */ - ++buf; - --buf_len; - } else { /* modR/M specifies base register */ - /* ELSE RM encodes a general register */ - ia32_handle_register( &ea->base, modrm.rm + 1 ); - } - } else { /* mod is 01 or 10 */ - if (modrm.rm == MODRM_RM_SIB) { /* rm == 100 */ - /* IF base is an AddrExpr specified by an SIB byte */ - /* TODO: check for 0 retval */ - size += sib_decode( buf, buf_len, ea, modrm.mod); - /* move to byte after SIB for displacement */ - ++buf; - --buf_len; - } else { - /* ELSE base is a general register */ - ia32_handle_register( &ea->base, modrm.rm + 1 ); - } - - /* ELSE mod + r/m specify a disp##[base] or disp##(SIB) */ - if (modrm.mod == MODRM_MOD_DISP8) { /* mod == 01 */ - /* If this is an 8-bit displacement */ - imm32_signsized( buf, buf_len, &ea->disp, - sizeof(char)); - ea->disp_size = sizeof(char); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 1; /* add sizeof disp to count */ - - } else { - /* Displacement is dependent on address size */ - imm32_signsized( buf, buf_len, &ea->disp, - insn->addr_size); - ea->disp_size = insn->addr_size; - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; - } - } - - return size; /* number of bytes found in instruction */ -} - -void ia32_reg_decode( unsigned char byte, x86_op_t *op, size_t gen_regs ) { - struct modRM_byte modrm; - byte_decode( byte, &modrm ); /* get bitfields */ - - /* set operand to register ID */ - op->type = op_register; - ia32_handle_register(&op->data.reg, modrm.reg + gen_regs); - - return; -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.h deleted file mode 100644 index 765cb0833..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_modrm.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef IA32_MODRM_H -#define IA32_MODRM_H - -#include "libdis.h" -#include "ia32_insn.h" - -size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, x86_insn_t *insn, - size_t gen_regs ); - -void ia32_reg_decode( unsigned char byte, x86_op_t *op, size_t gen_regs ); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.c deleted file mode 100644 index ef97c7a35..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.c +++ /dev/null @@ -1,2939 +0,0 @@ -#include "ia32_insn.h" - -#include "ia32_reg.h" - -#include "ia32_opcode_tables.h" - -static ia32_insn_t tbl_Main[] = { /* One-byte Opcodes */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 1, 0, 0, 0 , 33 }, - { idx_0F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, -/* 0x10 */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 2, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 2, 0, 0, 0 , 33 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_SIGNED | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 3, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 3, 0, 0, 0 , 33 }, -/* 0x20 */ - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_ES, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "daa", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_CARRY|INS_SET_PARITY|INS_TEST_CARRY, 12 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_CS | PREFIX_NOTTAKEN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "das", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_CARRY|INS_SET_PARITY|INS_TEST_CARRY, 0 }, -/* 0x30 */ - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_SS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aaa", "", 0, 0, 0, INS_SET_CARRY, 1 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_G | OPTYPE_b | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_DS | PREFIX_TAKEN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aas", "", 0, 0, 0, INS_SET_CARRY, 0 }, -/* 0x40 */ - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 1, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 2, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 3, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 4, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 5, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 6, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 7, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 1, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 2, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 3, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 4, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 5, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 6, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 7, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, -/* 0x50 */ - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 1, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 2, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 3, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 4, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 5, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 6, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 7, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 1, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 2, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 3, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 4, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 5, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 6, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 7, 0, 0, 0 , 33 }, -/* 0x60 */ - { 0, INS_PUSHREGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pusha", "", 0, 0, 0, 0 , 36 }, - { 0, INS_POPREGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "popa", "", 0, 0, 0, 0 , 34 }, - { 0, INS_BOUNDS, INS_NOTE_NONSWAP, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_M | OPTYPE_a | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bound", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R | OP_W, ADDRMETH_G | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "arpl", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_FS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_GS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_66, INS_FLAG_PREFIX | PREFIX_OP_SIZE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_ADDR_SIZE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 0 }, - { 0, INS_IN, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ins", "", 0, 2, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ins", "", 0, 2, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "outs", "", 2, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_X | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "outs", "", 2, 0, 0, 0 , 0 }, -/* 0x70 */ - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ja", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "js", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, -/* 0x80 */ - { idx_80, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_81, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_v, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_82, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_83, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XCHG, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_b | OP_W, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_v | OP_W, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_b | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_w | OP_W, ADDRMETH_S | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_m | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lea", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_S | OPTYPE_w | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_POP, 0, ADDRMETH_E | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, -/* 0x90 */ - { 0, INS_NOP, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "nop", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 1, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 2, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 3, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 4, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 5, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 6, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 7, 0, 0 , 0 }, - { 0, INS_SZCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cwde", "", 0, 0, 0, 0 , 5 }, - { 0, INS_SZCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cdq", "", 0, 0, 0, 0 , 11 }, - { 0, INS_CALL, 0, ADDRMETH_A | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "callf", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "wait", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSHFLAGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pushf", "", 0, 0, 0, 0 , 37 }, - { 0, INS_POPFLAGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "popf", "", 0, 0, 0, 0 , 35 }, - { 0, INS_MOV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sahf", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 43 }, - { 0, INS_MOV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lahf", "", 0, 0, 0, 0 , 24 }, -/* 0xa0 */ - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_O | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_O | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_O | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_O | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRMOV, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRMOV, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_X | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_Y | OPTYPE_b | OP_R, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_X | OPTYPE_v | OP_R, ADDRMETH_Y | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TEST, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_STRSTOR, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "stos", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRSTOR, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v |OP_R, ARG_NONE, cpu_80386 | isa_GP, "stos", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRLOAD, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_X| OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lods", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRLOAD, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_X| OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lods", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_Y | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "scas", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_Y | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "scas", "", 0, 0, 0, 0 , 0 }, -/* 0xb0 */ - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 1, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 2, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 3, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 4, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 5, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 6, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 7, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 1, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 2, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 3, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 4, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 5, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 6, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 7, 0, 0, 0 , 0 }, -/* 0xc0 */ - { idx_C0, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_C1, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_RET, 0, ADDRMETH_I | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ret", "", 0, 0, 0, 0 , 3 }, - { 0, INS_RET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ret", "", 0, 0, 0, 0 , 3 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_R, ARG_NONE, cpu_80386 | isa_GP, "les", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lds", "", 0, 0, 0, 0 , 0 }, - { idx_C6, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_C7, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ENTER, INS_NOTE_NONSWAP, ADDRMETH_I | OPTYPE_w | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "enter", "", 0, 0, 0, 0 , 15 }, - { 0, INS_LEAVE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "leave", "", 0, 0, 0, 0 , 26 }, - { 0, INS_RET, 0, ADDRMETH_I | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "retf", "lret", 0, 0, 0, 0 , 3 }, - { 0, INS_RET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "retf", "lret", 0, 0, 0, 0 , 3 }, - { 0, INS_DEBUG, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "int3", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TRAP, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "int", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OFLOW, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "into", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_TRET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "iret", "", 0, 0, 0, INS_SET_ALL|INS_SET_DIR, 0 }, -/* 0xd0 */ - { idx_D0, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D1, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D2, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D3, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aam", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_BCDCONV, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aad", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 2 }, - { 0, INS_SALC, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "salc", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XLAT, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "xlat", "", 0, 0, 0, 0 , 53 }, - { idx_D8, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_D9, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DA, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DB, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DC, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DD, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DF, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, -/* 0xe0 */ - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loopnz", "", 0, 0, 0, INS_TEST_NZERO, 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loopz", "", 0, 0, 0, INS_TEST_ZERO, 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loop", "", 0, 0, 0, 0 , 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jcxz", "", 0, 0, 0, 0 , 31 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 0, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_I | OPTYPE_b | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_I | OPTYPE_b | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CALL, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 3 }, - { 0, INS_BRANCH, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_A | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_J | OPTYPE_b | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b| OP_W, ADDRMETH_RR | OPTYPE_w| OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 2, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_w| OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 2, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_w| OP_R, ADDRMETH_RR | OPTYPE_b| OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 2, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_w| OP_R, ADDRMETH_RR | OPTYPE_v| OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 2, 0, 0, 0 , 0 }, -/* 0xf0 */ - { 0, INS_FLAG_PREFIX | PREFIX_LOCK, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ICEBP, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "icebp", "", 0, 0, 0, 0 , 0 }, - { idx_F2, INS_FLAG_PREFIX | PREFIX_REPNZ, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_F3, INS_FLAG_PREFIX | PREFIX_REPZ, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_HALT, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "hlt", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TOGCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cmc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { idx_F6, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_F7, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CLEARCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "clc", "", 0, 0, 0, INS_SET_NCARRY, 0 }, - { 0, INS_SETCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "stc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cli", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sti", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CLEARDF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cld", "", 0, 0, 0, INS_SET_NDIR, 0 }, - { 0, INS_SETDF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "std", "", 0, 0, 0, INS_SET_DIR, 0 }, - { idx_FE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_FF, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_66[] = { /* SIMD 66 one-byte Opcodes */ - { idx_660F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_F2[] = { /* SIMD F2 one-byte Opcodes */ - { idx_F20F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_F3[] = { /* SIMD F3 one-byte Opcodes */ - { idx_F30F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pause", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */ - { idx_0F00, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F01, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lar", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lsl", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "clts", "", 0, 0, 0, 0 , 6 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "wbinvd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_UNKNOWN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTPRO | isa_GP, "ud2", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "prefetch", "", 0, 0, 0, 0, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "femms", "", 0, 0, 0, 0, 0 }, - { idx_0F0F, INS_FLAG_SUFFIX, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movups", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movups", "", 0, 0, 0, 0 , 0 }, - { idx_0F12, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "unpcklps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "unpckhps", "", 0, 0, 0, 0 , 0 }, - { idx_0F16, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_q | OP_W, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { idx_0F18, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_C | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_D | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_C | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_D | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_T | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_T | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movaps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movaps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvtpi2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movntps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvttps2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W , ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvtps2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ss | OP_W, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "ucomiss", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ss | OP_W, ARG_NONE, cpu_PENTIUM2 | isa_GP, "comiss", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "wrmsr", "", 0, 0, 0, 0 , 52 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "rdtsc", "", 0, 0, 0, 0 , 40 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "rdmsr", "", 0, 0, 0, 0 , 38 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTPRO | isa_GP, "rdpmc", "", 0, 0, 0, 0 , 39 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sysenter", "", 0, 0, 0, 0 , 50 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sysexit", "", 0, 0, 0, 0 , 51 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmova", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovs", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovp", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnp", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movmskps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sqrtps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "rsqrtps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "rcpps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "andps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "andnps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OR, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "orps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XOR, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "xorps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "addps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "mulps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd, ADDRMETH_W | OPTYPE_q, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtps2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtdq2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "subps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "minps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_DIV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "divps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "maxps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpcklbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpcklwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckldq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packsswb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packuswb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhdq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packssdw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_d | OP_W, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pshufw", "", 0, 0, 0, 0, 0 }, - { idx_0F71, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F72, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F73, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "emms", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_d | OP_W, ADDRMETH_P | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_Q | OPTYPE_q | OP_W, ADDRMETH_P | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ja", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "js", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "seto", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setno", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "seta", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sets", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 4, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 4, 0, 0, 0 , 33 }, - { 0, INS_CPUID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cpuid", "", 0, 0, 0, 0 , 10 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bt", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_80386 | isa_GP, "shld", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - //{ 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OP_R | OPTYPE_b | ADDRMETH_RR, cpu_80386 | isa_GP, "shld", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_RR | OP_R | OPTYPE_b, cpu_80386 | isa_GP, "shld", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 5, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 5, 0, 0, 0 , 33 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "rsm", "", 0, 0, 0, INS_SET_ALL|INS_SET_DIR, 42 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bts", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_80386 | isa_GP, "shrd", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_RR | OP_R | OPTYPE_b , cpu_80386 | isa_GP, "shrd", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { idx_0FAE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, }, - { 0, INS_XCHGCC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W, ARG_NONE, cpu_80486 | isa_GP, "cmpxchg", "", 0, 0, 0, INS_SET_ALL, 8 }, - { 0, INS_XCHGCC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W, ARG_NONE, cpu_80486 | isa_GP, "cmpxchg", "", 0, 0, 0, INS_SET_ALL, 7 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lss", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btr", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lfs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lgs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movzx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movzx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_UNKNOWN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ud1", "", 0, 0, 0, 0 , 0 }, - { idx_0FBA, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_G | OPTYPE_v | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bsf", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_G | OPTYPE_v | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bsr", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movsx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movsx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W, ARG_NONE, cpu_80486 | isa_GP, "xadd", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W, ARG_NONE, cpu_80486 | isa_GP, "xadd", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpps", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_M | OPTYPE_d | OP_W, ADDRMETH_G | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movnti", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pinsrw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pextrw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "shufps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxchg8b", "", 0, 0, 0, 0, 9 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 1, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 2, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 3, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 4, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 5, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 6, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 7, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddq", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmullw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmovmskb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubusb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubusw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pminub", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pand", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddusb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddusw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmaxub", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pandn", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pavgb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pavgw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmulhuw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmulhw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_W | OPTYPE_q | OP_W, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movntq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pminsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OR, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "por", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddsb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmaxsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XOR, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pxor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmaddwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "psadbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_pi | OP_W, ADDRMETH_Q | OPTYPE_pi | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "maskmovq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F[] = { /* SIMD 66 Two-byte Opcodes */ - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movupd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movupd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_M | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "unpcklpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "unpckhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_M | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movapd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movapd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpi2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_M | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movntpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttpd2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "ucomisd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "comisd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movmskpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_FSQRT, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "andpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "andnpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_OR, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "orpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_XOR, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "xorpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtps2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckldq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packsswb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packuswb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packssdw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklqdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhqdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_d | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqa", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufd", "", 0, 0, 0, 0, 0 }, - { idx_660F71, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { idx_660F72, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { idx_660F73, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "haddpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "hsubpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_V | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqa", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmppd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_w | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pinsrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_w | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pextrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "shufpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsubpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrlw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrld", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrlq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmullw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmovmskb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubusb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubusw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pminub", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pand", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddusb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddusw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaxub", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pandn", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pavgb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psraw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrad", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pavgw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmulhuw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmulhw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttpd2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_M | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movntdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubsb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pminsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "por", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddsb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaxsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pxor", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psllw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pslld", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psllq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaddwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psadbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maskmovdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_F20F[] = { /* SIMD F2 Two-byte Opcodes */ - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_sd | OP_R, ADDRMETH_V | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movddup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsi2sd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttsd2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsd2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsd2ss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshuflw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "haddps", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "hsubps", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsubps", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdq2q", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_M | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "lddqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_F30F[] = { /* SIMD F3 Two-byte Opcodes */ - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_ss | OP_R, ADDRMETH_V | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsldup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movshdup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsi2ss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttss2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtss2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "rsqrtss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "rcpss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtss2sd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttps2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufhw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtdq2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F00[] = { /* Group 6 */ - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sldt", "", 0, 0, 0, 0 , 46 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "str", "", 0, 0, 0, 0 , 49 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lldt", "", 0, 0, 0, 0 , 29 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ltr", "", 0, 0, 0, 0 , 32 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "verr", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "verw", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F01[] = { /* Group 7 */ - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F0111, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F0111[] = { /* Monitor/MWait opcode */ - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "monitor", "", 0, 0, 0, 0, 54 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mwait", "", 0, 0, 0, 0, 55 } -}; - - -static ia32_insn_t tbl_0F12[] = { /* Movlps Opcode */ - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_R | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R , ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhlps", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F16[] = { /* Movhps Opcode */ - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_R | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R , ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlhps", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F18[] = { /* Group 16 */ - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F71[] = { /* Group 12 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F71[] = { /* Group 12 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F72[] = { /* Group 13 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F72[] = { /* Group 13 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F73[] = { /* Group 14 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F73[] = { /* Group 14 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrldq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslldq", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0FAE[] = { /* Group 15 */ - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "lfence", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "mfence", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "sfence", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0FBA[] = { /* Group 8 */ - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bt", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bts", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btr", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btc", "", 0, 0, 0 , INS_SET_CARRY, 0 } -}; - - -static ia32_insn_t tbl_0FC7[] = { /* Group 9 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 } -}; - - -static ia32_insn_t tbl_0FB9[] = { /* Group 10 */ - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "fxsave", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_C6[] = { /* Group 11a */ - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_C7[] = { /* Group 11b */ - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_80[] = { /* Group 1a */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_81[] = { /* Group 1b */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_82[] = { /* Group 1c */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_83[] = { /* Group 1d */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_C0[] = { /* Group 2a */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_C1[] = { /* Group 2b */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D0[] = { /* Group 2c */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D1[] = { /* Group 2d */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D2[] = { /* Group 2e */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D3[] = { /* Group 2f */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_F6[] = { /* Group 3a */ - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_NOT, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "not", "", 0, 0, 0, 0 , 0 }, - { 0, INS_NEG, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "neg", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_MUL, 0, OPTYPE_b | ADDRMETH_RR | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 22 }, - { 0, INS_MUL, 0, OPTYPE_b | ADDRMETH_RR | OP_W | OP_SIGNED | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 22 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "div", "", 0, 0, 0, 0 , 13 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "idiv", "", 0, 0, 0 , 0 , 13 } -}; - - -static ia32_insn_t tbl_F7[] = { /* Group 3b */ - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_NOT, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "not", "", 0, 0, 0, 0 , 0 }, - { 0, INS_NEG, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "neg", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_MUL, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 23 }, - { 0, INS_MUL, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 23 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "div", "", 0, 0, 0, 0 , 14 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "idiv", "", 0, 0, 0, 0 , 14 } -}; - - -static ia32_insn_t tbl_FE[] = { /* Group 4 */ - { 0, INS_INC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0 , INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 } -}; - - -static ia32_insn_t tbl_FF[] = { /* Group 5 */ - { 0, INS_INC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_CALL, 0, ADDRMETH_E | OPTYPE_v | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 3 }, - { 0, INS_CALL, 0, ADDRMETH_M | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_E | OPTYPE_v | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_M | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 } -}; - - -static ia32_insn_t tbl_D8[] = { /* FPU D8 */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D8C0[] = { /* FPU D8 C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 7, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D9[] = { /* FPU D9 */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fv|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldenv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldcw", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fv|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstenv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstcw", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D9C0[] = { /* FPU D9 C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnop", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fchs", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fabs", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ftst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fxam", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldl2t", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldl2e", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldpi", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldlg2", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldln2", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldz", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "f2xm1", "", 0, 0, 0 , 0 , 16 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fyl2x", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fptan", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fpatan", "", 0, 0, 0 , 0 , 18 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fxtract", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fprem1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdecstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fincstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fprem", "", 0, 0, 0 , 0 , 19 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fyl2xp1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsqrt", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsincos", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "frndint", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fscale", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsin", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcos", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DA[] = { /* FPU DA */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fiadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fimul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidivr", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DAC0[] = { /* FPU DA C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 0, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 1, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 2, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 3, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 4, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 5, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 6, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 7, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 0, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 1, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 2, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 3, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 4, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 5, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 6, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 7, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 0, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 1, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 2, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 3, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 4, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 5, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 6, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 7, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 0, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 1, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 2, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 3, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 4, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 5, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 6, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 7, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fucompp", "", 0, 0, 0 , 0 , 21 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DB[] = { /* FPU DB */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fist", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fe|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fe|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DBC0[] = { /* FPU DB C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 0, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 1, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 2, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 3, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 4, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 5, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 6, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 7, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 0, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 1, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 2, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 3, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 4, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 5, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 6, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 7, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 0, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 1, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 2, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 3, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 4, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 5, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 6, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 7, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 0, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 1, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 2, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 3, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 4, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 5, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 6, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 7, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnclex", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fninit", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0, }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DC[] = { /* FPU DC */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_DCC0[] = { /* FPU DC C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 7, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DD[] = { /* FPU DD */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_ft|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "frstor", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_ft|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnsave", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstsw", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DDC0[] = { /* FPU DD C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DE[] = { /* FPU DE */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fiadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fimul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidivr", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_DEC0[] = { /* FPU DE C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 0, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 1, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 2, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 3, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 4, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 5, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 6, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 7, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcompp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 7, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DF[] = { /* FPU DF */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fist", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fb|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fbld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fb|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fbstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DFC0[] = { /* FPU DF C0 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RR | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstsw", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_0F0F[] = { /* 3D Now! 0F Suffix */ - /* 00 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CONV, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pi2fd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 10 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CONV, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pf2id", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 20 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 30 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 40 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 50 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 60 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 70 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 80 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpge", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MIN, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmin", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcp", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrsqrt", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfsub", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfadd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpgt", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MAX, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmax", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcpit1", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrsqit1", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfsubr", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfacc", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpeq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmul", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcpit2", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pmulhrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_AVG, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pavgusb", "", 0, 0, 0, 0, 0 } -}; - - - -/* ================== Table of Opcode Tables ================== */ -ia32_table_desc_t ia32_tables[] = { - /* table, prefix table, type, shift, mask, min, max */ - { tbl_Main, tbl_opcode, 0x00, 0xFF, 0x00, 0xFF }, - { tbl_66, tbl_prefix, 0x00, 0xFF, 0x0F, 0x0F }, - { tbl_F2, tbl_prefix, 0x00, 0xFF, 0x0F, 0x0F }, - { tbl_F3, tbl_prefix, 0x00, 0xFF, 0x0F, 0x90 }, - { tbl_0F, tbl_opcode, 0x00, 0xFF, 0x00, 0xFF }, - /* 5 */ - { tbl_660F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_F20F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_F30F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_0F00, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_0F01, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 10 */ - { tbl_0F0111, tbl_ext_ext, 0x00, 0x01, 0x00, 0x01 }, - { tbl_0F12, tbl_extension, 0x06, 0x03, 0x00, 0x03 }, - { tbl_0F16, tbl_extension, 0x06, 0x03, 0x00, 0x03 }, - { tbl_0F18, tbl_extension, 0x03, 0x1F, 0x00, 0x13 }, - { tbl_0F71, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 15 */ - { tbl_660F71, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0F72, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_660F72, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0F73, tbl_extension, 0x00, 0x00, 0x00, 0x00 }, - { tbl_660F73, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 20 */ - { tbl_0FAE, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0FBA, tbl_extension, 0x03, 0x07, 0x04, 0x07 }, - { tbl_0FC7, tbl_extension, 0x03, 0x1F, 0x00, 0x11 }, - { tbl_0FB9, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - { tbl_C6, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - /* 25 */ - { tbl_C7, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - { tbl_80, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_81, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_82, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_83, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - /* 30 */ - { tbl_C0, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_C1, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D0, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D1, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D2, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - /* 35 */ - { tbl_D3, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_F6, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_F7, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_FE, tbl_extension, 0x03, 0x07, 0x00, 0x01 }, - { tbl_FF, tbl_extension, 0x03, 0x07, 0x00, 0x06 }, - /* 40 */ - { tbl_D8, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_D8C0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_D9, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_D9C0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DA, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - /* 45 */ - { tbl_DAC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DB, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DBC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DC, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DCC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - /* 50 */ - { tbl_DD, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DDC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DE, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DEC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DF, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - /* 55 */ - { tbl_DFC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_0F0F, tbl_suffix, 0x00, 0xFF, 0x00, 0xBF } -}; -/* ia32_opcode_tables.h */ -/* Table index constants: -#define idx_Main 0 -#define idx_66 1 -#define idx_F2 2 -#define idx_F3 3 -#define idx_0F 4 -#define idx_660F 5 -#define idx_F20F 6 -#define idx_F30F 7 -#define idx_0F00 8 -#define idx_0F01 9 -#define idx_0F0111 10 -#define idx_0F12 11 -#define idx_0F16 12 -#define idx_0F18 13 -#define idx_0F71 14 -#define idx_660F71 15 -#define idx_0F72 16 -#define idx_660F72 17 -#define idx_0F73 18 -#define idx_660F73 19 -#define idx_0FAE 20 -#define idx_0FBA 21 -#define idx_0FC7 22 -#define idx_0FB9 23 -#define idx_C6 24 -#define idx_C7 25 -#define idx_80 26 -#define idx_81 27 -#define idx_82 28 -#define idx_83 29 -#define idx_C0 30 -#define idx_C1 31 -#define idx_D0 32 -#define idx_D1 33 -#define idx_D2 34 -#define idx_D3 35 -#define idx_F6 36 -#define idx_F7 37 -#define idx_FE 38 -#define idx_FF 39 -#define idx_D8 40 -#define idx_D8C0 41 -#define idx_D9 42 -#define idx_D9C0 43 -#define idx_DA 44 -#define idx_DAC0 45 -#define idx_DB 46 -#define idx_DBC0 47 -#define idx_DC 48 -#define idx_DCC0 49 -#define idx_DD 50 -#define idx_DDC0 51 -#define idx_DE 52 -#define idx_DEC0 53 -#define idx_DF 54 -#define idx_DFC0 55 -#define idx_0F0F 56 -*/ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.h deleted file mode 100644 index bbd4fae9a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_opcode_tables.h +++ /dev/null @@ -1,57 +0,0 @@ -#define idx_Main 0 -#define idx_66 1 -#define idx_F2 2 -#define idx_F3 3 -#define idx_0F 4 -#define idx_660F 5 -#define idx_F20F 6 -#define idx_F30F 7 -#define idx_0F00 8 -#define idx_0F01 9 -#define idx_0F0111 10 -#define idx_0F12 11 -#define idx_0F16 12 -#define idx_0F18 13 -#define idx_0F71 14 -#define idx_660F71 15 -#define idx_0F72 16 -#define idx_660F72 17 -#define idx_0F73 18 -#define idx_660F73 19 -#define idx_0FAE 20 -#define idx_0FBA 21 -#define idx_0FC7 22 -#define idx_0FB9 23 -#define idx_C6 24 -#define idx_C7 25 -#define idx_80 26 -#define idx_81 27 -#define idx_82 28 -#define idx_83 29 -#define idx_C0 30 -#define idx_C1 31 -#define idx_D0 32 -#define idx_D1 33 -#define idx_D2 34 -#define idx_D3 35 -#define idx_F6 36 -#define idx_F7 37 -#define idx_FE 38 -#define idx_FF 39 -#define idx_D8 40 -#define idx_D8C0 41 -#define idx_D9 42 -#define idx_D9C0 43 -#define idx_DA 44 -#define idx_DAC0 45 -#define idx_DB 46 -#define idx_DBC0 47 -#define idx_DC 48 -#define idx_DCC0 49 -#define idx_DD 50 -#define idx_DDC0 51 -#define idx_DE 52 -#define idx_DEC0 53 -#define idx_DF 54 -#define idx_DFC0 55 -#define idx_0F0F 56 diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.c deleted file mode 100644 index 8e7f16a0c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.c +++ /dev/null @@ -1,425 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_operand.h" -#include "ia32_modrm.h" -#include "ia32_reg.h" -#include "x86_imm.h" -#include "x86_operand_list.h" - - - -/* apply segment override to memory operand in insn */ -static void apply_seg( x86_op_t *op, unsigned int prefixes ) { - if (! prefixes ) return; - - /* apply overrides from prefix */ - switch ( prefixes & PREFIX_REG_MASK ) { - case PREFIX_CS: - op->flags |= op_cs_seg; break; - case PREFIX_SS: - op->flags |= op_ss_seg; break; - case PREFIX_DS: - op->flags |= op_ds_seg; break; - case PREFIX_ES: - op->flags |= op_es_seg; break; - case PREFIX_FS: - op->flags |= op_fs_seg; break; - case PREFIX_GS: - op->flags |= op_gs_seg; break; - } - - return; -} - -static size_t decode_operand_value( unsigned char *buf, size_t buf_len, - x86_op_t *op, x86_insn_t *insn, - unsigned int addr_meth, size_t op_size, - unsigned int op_value, unsigned char modrm, - size_t gen_regs ) { - size_t size = 0; - - /* ++ Do Operand Addressing Method / Decode operand ++ */ - switch (addr_meth) { - /* This sets the operand Size based on the Intel Opcode Map - * (Vol 2, Appendix A). Letter encodings are from section - * A.1.1, 'Codes for Addressing Method' */ - - /* ---------------------- Addressing Method -------------- */ - /* Note that decoding mod ModR/M operand adjusts the size of - * the instruction, but decoding the reg operand does not. - * This should not cause any problems, as every 'reg' operand - * has an associated 'mod' operand. - * Goddamn-Intel-Note: - * Some Intel addressing methods [M, R] specify that modR/M - * byte may only refer to a memory address/may only refer to - * a register -- however Intel provides no clues on what to do - * if, say, the modR/M for an M opcode decodes to a register - * rather than a memory address ... returning 0 is out of the - * question, as this would be an Immediate or a RelOffset, so - * instead these modR/Ms are decoded with total disregard to - * the M, R constraints. */ - - /* MODRM -- mod operand. sets size to at least 1! */ - case ADDRMETH_E: /* ModR/M present, Gen reg or memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_M: /* ModR/M only refers to memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_Q: /* ModR/M present, MMX or Memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - REG_MMX_OFFSET ); - break; - case ADDRMETH_R: /* ModR/M mod == gen reg */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_W: /* ModR/M present, mem or SIMD reg */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - REG_SIMD_OFFSET ); - break; - - /* MODRM -- reg operand. does not effect size! */ - case ADDRMETH_C: /* ModR/M reg == control reg */ - ia32_reg_decode( modrm, op, REG_CTRL_OFFSET ); - break; - case ADDRMETH_D: /* ModR/M reg == debug reg */ - ia32_reg_decode( modrm, op, REG_DEBUG_OFFSET ); - break; - case ADDRMETH_G: /* ModR/M reg == gen-purpose reg */ - ia32_reg_decode( modrm, op, gen_regs ); - break; - case ADDRMETH_P: /* ModR/M reg == qword MMX reg */ - ia32_reg_decode( modrm, op, REG_MMX_OFFSET ); - break; - case ADDRMETH_S: /* ModR/M reg == segment reg */ - ia32_reg_decode( modrm, op, REG_SEG_OFFSET ); - break; - case ADDRMETH_T: /* ModR/M reg == test reg */ - ia32_reg_decode( modrm, op, REG_TEST_OFFSET ); - break; - case ADDRMETH_V: /* ModR/M reg == SIMD reg */ - ia32_reg_decode( modrm, op, REG_SIMD_OFFSET ); - break; - - /* No MODRM : note these set operand type explicitly */ - case ADDRMETH_A: /* No modR/M -- direct addr */ - op->type = op_absolute; - - /* segment:offset address used in far calls */ - x86_imm_sized( buf, buf_len, - &op->data.absolute.segment, 2 ); - if ( insn->addr_size == 4 ) { - x86_imm_sized( buf, buf_len, - &op->data.absolute.offset.off32, 4 ); - size = 6; - } else { - x86_imm_sized( buf, buf_len, - &op->data.absolute.offset.off16, 2 ); - size = 4; - } - - break; - case ADDRMETH_I: /* Immediate val */ - op->type = op_immediate; - /* if it ever becomes legal to have imm as dest and - * there is a src ModR/M operand, we are screwed! */ - if ( op->flags & op_signed ) { - x86_imm_signsized(buf, buf_len, &op->data.byte, - op_size); - } else { - x86_imm_sized(buf, buf_len, &op->data.byte, - op_size); - } - size = op_size; - break; - case ADDRMETH_J: /* Rel offset to add to IP [jmp] */ - /* this fills op->data.near_offset or - op->data.far_offset depending on the size of - the operand */ - op->flags |= op_signed; - if ( op_size == 1 ) { - /* one-byte near offset */ - op->type = op_relative_near; - x86_imm_signsized(buf, buf_len, - &op->data.relative_near, 1); - } else { - /* far offset...is this truly signed? */ - op->type = op_relative_far; - x86_imm_signsized(buf, buf_len, - &op->data.relative_far, op_size ); - } - size = op_size; - break; - case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ - /* NOTE: these are actually RVAs not offsets to seg!! */ - /* note bene: 'O' ADDR_METH uses addr_size to - determine operand size */ - op->type = op_offset; - op->flags |= op_pointer; - x86_imm_sized( buf, buf_len, &op->data.offset, - insn->addr_size ); - - size = insn->addr_size; - break; - - /* Hard-coded: these are specified in the insn definition */ - case ADDRMETH_F: /* EFLAGS register */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, REG_FLAGS_INDEX ); - break; - case ADDRMETH_X: /* Memory addressed by DS:SI [string] */ - op->type = op_expression; - op->flags |= op_hardcode; - op->flags |= op_ds_seg | op_pointer | op_string; - ia32_handle_register( &op->data.expression.base, - REG_DWORD_OFFSET + 6 ); - break; - case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */ - op->type = op_expression; - op->flags |= op_hardcode; - op->flags |= op_es_seg | op_pointer | op_string; - ia32_handle_register( &op->data.expression.base, - REG_DWORD_OFFSET + 7 ); - break; - case ADDRMETH_RR: /* Gen Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + gen_regs ); - break; - case ADDRMETH_RS: /* Seg Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_SEG_OFFSET ); - break; - case ADDRMETH_RF: /* FPU Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_FPU_OFFSET ); - break; - case ADDRMETH_RT: /* TST Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_TEST_OFFSET ); - break; - case ADDRMETH_II: /* Immediate hard-coded in opcode */ - op->type = op_immediate; - op->data.dword = op_value; - op->flags |= op_hardcode; - break; - - case 0: /* Operand is not used */ - default: - /* ignore -- operand not used in this insn */ - op->type = op_unused; /* this shouldn't happen! */ - break; - } - - return size; -} - -static size_t decode_operand_size( unsigned int op_type, x86_insn_t *insn, - x86_op_t *op ){ - size_t size; - - /* ++ Do Operand Type ++ */ - switch (op_type) { - /* This sets the operand Size based on the Intel Opcode Map - * (Vol 2, Appendix A). Letter encodings are from section - * A.1.2, 'Codes for Operand Type' */ - /* NOTE: in this routines, 'size' refers to the size - * of the operand in the raw (encoded) instruction; - * 'datatype' stores the actual size and datatype - * of the operand */ - - /* ------------------------ Operand Type ----------------- */ - case OPTYPE_c: /* byte or word [op size attr] */ - size = (insn->op_size == 4) ? 2 : 1; - op->datatype = (size == 4) ? op_word : op_byte; - break; - case OPTYPE_a: /* 2 word or 2 dword [op size attr] */ - /* pointer to a 16:16 or 32:32 BOUNDS operand */ - size = (insn->op_size == 4) ? 8 : 4; - op->datatype = (size == 4) ? op_bounds32 : op_bounds16; - break; - case OPTYPE_v: /* word or dword [op size attr] */ - size = (insn->op_size == 4) ? 4 : 2; - op->datatype = (size == 4) ? op_dword : op_word; - break; - case OPTYPE_p: /* 32/48-bit ptr [op size attr] */ - /* technically these flags are not accurate: the - * value s a 16:16 pointer or a 16:32 pointer, where - * the first '16' is a segment */ - size = (insn->addr_size == 4) ? 6 : 4; - op->datatype = (size == 4) ? op_descr32 : op_descr16; - break; - case OPTYPE_b: /* byte, ignore op-size */ - size = 1; - op->datatype = op_byte; - break; - case OPTYPE_w: /* word, ignore op-size */ - size = 2; - op->datatype = op_word; - break; - case OPTYPE_d: /* dword , ignore op-size */ - size = 4; - op->datatype = op_dword; - break; - case OPTYPE_s: /* 6-byte psuedo-descriptor */ - /* ptr to 6-byte value which is 32:16 in 32-bit - * mode, or 8:24:16 in 16-bit mode. The high byte - * is ignored in 16-bit mode. */ - size = 6; - op->datatype = (insn->addr_size == 4) ? - op_pdescr32 : op_pdescr16; - break; - case OPTYPE_q: /* qword, ignore op-size */ - size = 8; - op->datatype = op_qword; - break; - case OPTYPE_dq: /* d-qword, ignore op-size */ - size = 16; - op->datatype = op_dqword; - break; - case OPTYPE_ps: /* 128-bit FP data */ - size = 16; - /* really this is 4 packed SP FP values */ - op->datatype = op_ssimd; - break; - case OPTYPE_pd: /* 128-bit FP data */ - size = 16; - /* really this is 2 packed DP FP values */ - op->datatype = op_dsimd; - break; - case OPTYPE_ss: /* Scalar elem of 128-bit FP data */ - size = 16; - /* this only looks at the low dword (4 bytes) - * of the xmmm register passed as a param. - * This is a 16-byte register where only 4 bytes - * are used in the insn. Painful, ain't it? */ - op->datatype = op_sssimd; - break; - case OPTYPE_sd: /* Scalar elem of 128-bit FP data */ - size = 16; - /* this only looks at the low qword (8 bytes) - * of the xmmm register passed as a param. - * This is a 16-byte register where only 8 bytes - * are used in the insn. Painful, again... */ - op->datatype = op_sdsimd; - break; - case OPTYPE_pi: /* qword mmx register */ - size = 8; - op->datatype = op_qword; - break; - case OPTYPE_si: /* dword integer register */ - size = 4; - op->datatype = op_dword; - break; - case OPTYPE_fs: /* single-real */ - size = 4; - op->datatype = op_sreal; - break; - case OPTYPE_fd: /* double real */ - size = 8; - op->datatype = op_dreal; - break; - case OPTYPE_fe: /* extended real */ - size = 10; - op->datatype = op_extreal; - break; - case OPTYPE_fb: /* packed BCD */ - size = 10; - op->datatype = op_bcd; - break; - case OPTYPE_fv: /* pointer to FPU env: 14 or 28-bytes */ - size = (insn->addr_size == 4)? 28 : 14; - op->datatype = (size == 28)? op_fpuenv32: op_fpuenv16; - break; - case OPTYPE_ft: /* pointer to FPU env: 94 or 108 bytes */ - size = (insn->addr_size == 4)? 108 : 94; - op->datatype = (size == 108)? - op_fpustate32: op_fpustate16; - break; - case OPTYPE_fx: /* 512-byte register stack */ - size = 512; - op->datatype = op_fpregset; - break; - case OPTYPE_fp: /* floating point register */ - size = 10; /* double extended precision */ - op->datatype = op_fpreg; - break; - case OPTYPE_m: /* fake operand type used for "lea Gv, M" */ - size = insn->addr_size; - op->datatype = (size == 4) ? op_dword : op_word; - break; - case OPTYPE_none: /* handle weird instructions that have no encoding but use a dword datatype, like invlpg */ - size = 0; - op->datatype = op_none; - break; - case 0: - default: - size = insn->op_size; - op->datatype = (size == 4) ? op_dword : op_word; - break; - } - return size; -} - -size_t ia32_decode_operand( unsigned char *buf, size_t buf_len, - x86_insn_t *insn, unsigned int raw_op, - unsigned int raw_flags, unsigned int prefixes, - unsigned char modrm ) { - unsigned int addr_meth, op_type, op_size, gen_regs; - x86_op_t *op; - size_t size; - - /* ++ Yank optype and addr mode out of operand flags */ - addr_meth = raw_flags & ADDRMETH_MASK; - op_type = raw_flags & OPTYPE_MASK; - - if ( raw_flags == ARG_NONE ) { - /* operand is not used in this instruction */ - return 0; - } - - /* allocate a new operand */ - op = x86_operand_new( insn ); - - /* ++ Copy flags from opcode table to x86_insn_t */ - op->access = (enum x86_op_access) OP_PERM(raw_flags); - op->flags = (enum x86_op_flags) (OP_FLAGS(raw_flags) >> 12); - - /* Get size (for decoding) and datatype of operand */ - op_size = decode_operand_size(op_type, insn, op); - - /* override default register set based on Operand Type */ - /* this allows mixing of 8, 16, and 32 bit regs in insn */ - if (op_size == 1) { - gen_regs = REG_BYTE_OFFSET; - } else if (op_size == 2) { - gen_regs = REG_WORD_OFFSET; - } else { - gen_regs = REG_DWORD_OFFSET; - } - - size = decode_operand_value( buf, buf_len, op, insn, addr_meth, - op_size, raw_op, modrm, gen_regs ); - - /* if operand is an address, apply any segment override prefixes */ - if ( op->type == op_expression || op->type == op_offset ) { - apply_seg(op, prefixes); - } - - return size; /* return number of bytes in instruction */ -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.h deleted file mode 100644 index 08c3074cd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_operand.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IA32_OPERAND_H -#define IA32_OPERAND_H - -#include "libdis.h" -#include "ia32_insn.h" - -size_t ia32_decode_operand( unsigned char *buf, size_t buf_len, - x86_insn_t *insn, unsigned int raw_op, - unsigned int raw_flags, unsigned int prefixes, - unsigned char modrm ); -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.c deleted file mode 100644 index f270c1f34..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.c +++ /dev/null @@ -1,234 +0,0 @@ -#include -#include - -#include "ia32_reg.h" -#include "ia32_insn.h" - -#define NUM_X86_REGS 92 - -/* register sizes */ -#define REG_DWORD_SIZE 4 -#define REG_WORD_SIZE 2 -#define REG_BYTE_SIZE 1 -#define REG_MMX_SIZE 8 -#define REG_SIMD_SIZE 16 -#define REG_DEBUG_SIZE 4 -#define REG_CTRL_SIZE 4 -#define REG_TEST_SIZE 4 -#define REG_SEG_SIZE 2 -#define REG_FPU_SIZE 10 -#define REG_FLAGS_SIZE 4 -#define REG_FPCTRL_SIZE 2 -#define REG_FPSTATUS_SIZE 2 -#define REG_FPTAG_SIZE 2 -#define REG_EIP_SIZE 4 -#define REG_IP_SIZE 2 - -/* REGISTER ALIAS TABLE: - * - * NOTE: the MMX register mapping is fixed to the physical registers - * used by the FPU. The floating FP stack does not effect the location - * of the MMX registers, so this aliasing is not 100% accurate. - * */ -static struct { - unsigned char alias; /* id of register this is an alias for */ - unsigned char shift; /* # of bits register must be shifted */ -} ia32_reg_aliases[] = { - { 0,0 }, - { REG_DWORD_OFFSET, 0 }, /* al : 1 */ - { REG_DWORD_OFFSET, 8 }, /* ah : 2 */ - { REG_DWORD_OFFSET, 0 }, /* ax : 3 */ - { REG_DWORD_OFFSET + 1, 0 }, /* cl : 4 */ - { REG_DWORD_OFFSET + 1, 8 }, /* ch : 5 */ - { REG_DWORD_OFFSET + 1, 0 }, /* cx : 6 */ - { REG_DWORD_OFFSET + 2, 0 }, /* dl : 7 */ - { REG_DWORD_OFFSET + 2, 8 }, /* dh : 8 */ - { REG_DWORD_OFFSET + 2, 0 }, /* dx : 9 */ - { REG_DWORD_OFFSET + 3, 0 }, /* bl : 10 */ - { REG_DWORD_OFFSET + 3, 8 }, /* bh : 11 */ - { REG_DWORD_OFFSET + 3, 0 }, /* bx : 12 */ - { REG_DWORD_OFFSET + 4, 0 }, /* sp : 13 */ - { REG_DWORD_OFFSET + 5, 0 }, /* bp : 14 */ - { REG_DWORD_OFFSET + 6, 0 }, /* si : 15 */ - { REG_DWORD_OFFSET + 7, 0 }, /* di : 16 */ - { REG_EIP_INDEX, 0 }, /* ip : 17 */ - { REG_FPU_OFFSET, 0 }, /* mm0 : 18 */ - { REG_FPU_OFFSET + 1, 0 }, /* mm1 : 19 */ - { REG_FPU_OFFSET + 2, 0 }, /* mm2 : 20 */ - { REG_FPU_OFFSET + 3, 0 }, /* mm3 : 21 */ - { REG_FPU_OFFSET + 4, 0 }, /* mm4 : 22 */ - { REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */ - { REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */ - { REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */ - }; - -/* REGISTER TABLE: size, type, and name of every register in the - * CPU. Does not include MSRs since the are, after all, - * model specific. */ -static struct { - unsigned int size; - enum x86_reg_type type; - unsigned int alias; - char mnemonic[8]; -} ia32_reg_table[NUM_X86_REGS + 2] = { - { 0, 0, 0, "" }, - /* REG_DWORD_OFFSET */ - { REG_DWORD_SIZE, reg_gen | reg_ret, 0, "eax" }, - { REG_DWORD_SIZE, reg_gen | reg_count, 0, "ecx" }, - { REG_DWORD_SIZE, reg_gen, 0, "edx" }, - { REG_DWORD_SIZE, reg_gen, 0, "ebx" }, - /* REG_ESP_INDEX */ - { REG_DWORD_SIZE, reg_gen | reg_sp, 0, "esp" }, - { REG_DWORD_SIZE, reg_gen | reg_fp, 0, "ebp" }, - { REG_DWORD_SIZE, reg_gen | reg_src, 0, "esi" }, - { REG_DWORD_SIZE, reg_gen | reg_dest, 0, "edi" }, - /* REG_WORD_OFFSET */ - { REG_WORD_SIZE, reg_gen | reg_ret, 3, "ax" }, - { REG_WORD_SIZE, reg_gen | reg_count, 6, "cx" }, - { REG_WORD_SIZE, reg_gen, 9, "dx" }, - { REG_WORD_SIZE, reg_gen, 12, "bx" }, - { REG_WORD_SIZE, reg_gen | reg_sp, 13, "sp" }, - { REG_WORD_SIZE, reg_gen | reg_fp, 14, "bp" }, - { REG_WORD_SIZE, reg_gen | reg_src, 15, "si" }, - { REG_WORD_SIZE, reg_gen | reg_dest, 16, "di" }, - /* REG_BYTE_OFFSET */ - { REG_BYTE_SIZE, reg_gen, 1, "al" }, - { REG_BYTE_SIZE, reg_gen, 4, "cl" }, - { REG_BYTE_SIZE, reg_gen, 7, "dl" }, - { REG_BYTE_SIZE, reg_gen, 10, "bl" }, - { REG_BYTE_SIZE, reg_gen, 2, "ah" }, - { REG_BYTE_SIZE, reg_gen, 5, "ch" }, - { REG_BYTE_SIZE, reg_gen, 8, "dh" }, - { REG_BYTE_SIZE, reg_gen, 11, "bh" }, - /* REG_MMX_OFFSET */ - { REG_MMX_SIZE, reg_simd, 18, "mm0" }, - { REG_MMX_SIZE, reg_simd, 19, "mm1" }, - { REG_MMX_SIZE, reg_simd, 20, "mm2" }, - { REG_MMX_SIZE, reg_simd, 21, "mm3" }, - { REG_MMX_SIZE, reg_simd, 22, "mm4" }, - { REG_MMX_SIZE, reg_simd, 23, "mm5" }, - { REG_MMX_SIZE, reg_simd, 24, "mm6" }, - { REG_MMX_SIZE, reg_simd, 25, "mm7" }, - /* REG_SIMD_OFFSET */ - { REG_SIMD_SIZE, reg_simd, 0, "xmm0" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm1" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm2" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm3" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm4" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm5" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm6" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm7" }, - /* REG_DEBUG_OFFSET */ - { REG_DEBUG_SIZE, reg_sys, 0, "dr0" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr1" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr2" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr3" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr4" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr5" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr6" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr7" }, - /* REG_CTRL_OFFSET */ - { REG_CTRL_SIZE, reg_sys, 0, "cr0" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr1" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr2" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr3" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr4" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr5" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr6" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr7" }, - /* REG_TEST_OFFSET */ - { REG_TEST_SIZE, reg_sys, 0, "tr0" }, - { REG_TEST_SIZE, reg_sys, 0, "tr1" }, - { REG_TEST_SIZE, reg_sys, 0, "tr2" }, - { REG_TEST_SIZE, reg_sys, 0, "tr3" }, - { REG_TEST_SIZE, reg_sys, 0, "tr4" }, - { REG_TEST_SIZE, reg_sys, 0, "tr5" }, - { REG_TEST_SIZE, reg_sys, 0, "tr6" }, - { REG_TEST_SIZE, reg_sys, 0, "tr7" }, - /* REG_SEG_OFFSET */ - { REG_SEG_SIZE, reg_seg, 0, "es" }, - { REG_SEG_SIZE, reg_seg, 0, "cs" }, - { REG_SEG_SIZE, reg_seg, 0, "ss" }, - { REG_SEG_SIZE, reg_seg, 0, "ds" }, - { REG_SEG_SIZE, reg_seg, 0, "fs" }, - { REG_SEG_SIZE, reg_seg, 0, "gs" }, - /* REG_LDTR_INDEX */ - { REG_DWORD_SIZE, reg_sys, 0, "ldtr" }, - /* REG_GDTR_INDEX */ - { REG_DWORD_SIZE, reg_sys, 0, "gdtr" }, - /* REG_FPU_OFFSET */ - { REG_FPU_SIZE, reg_fpu, 0, "st(0)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(1)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(2)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(3)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(4)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(5)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(6)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(7)" }, - /* REG_FLAGS_INDEX : 81 */ - { REG_FLAGS_SIZE, reg_cond, 0, "eflags" }, - /* REG_FPCTRL_INDEX : 82*/ - { REG_FPCTRL_SIZE, reg_fpu | reg_sys, 0, "fpctrl" }, - /* REG_FPSTATUS_INDEX : 83*/ - { REG_FPSTATUS_SIZE, reg_fpu | reg_sys, 0, "fpstat" }, - /* REG_FPTAG_INDEX : 84 */ - { REG_FPTAG_SIZE, reg_fpu | reg_sys, 0, "fptag" }, - /* REG_EIP_INDEX : 85 */ - { REG_EIP_SIZE, reg_pc, 0, "eip" }, - /* REG_IP_INDEX : 86 */ - { REG_IP_SIZE, reg_pc, 17, "ip" }, - /* REG_IDTR_INDEX : 87 */ - { REG_DWORD_SIZE, reg_sys, 0, "idtr" }, - /* REG_MXCSG_INDEX : SSE Control Reg : 88 */ - { REG_DWORD_SIZE, reg_sys | reg_simd, 0, "mxcsr" }, - /* REG_TR_INDEX : Task Register : 89 */ - { 16 + 64, reg_sys, 0, "tr" }, - /* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */ - { REG_DWORD_SIZE, reg_sys, 0, "cs_msr" }, - /* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */ - { REG_DWORD_SIZE, reg_sys, 0, "esp_msr" }, - /* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */ - { REG_DWORD_SIZE, reg_sys, 0, "eip_msr" }, - { 0 } - }; - - -static size_t sz_regtable = NUM_X86_REGS + 1; - - -void ia32_handle_register( x86_reg_t *reg, size_t id ) { - unsigned int alias; - if (! id || id > sz_regtable ) { - return; - } - - memset( reg, 0, sizeof(x86_reg_t) ); - - strncpy( reg->name, ia32_reg_table[id].mnemonic, MAX_REGNAME ); - - reg->type = ia32_reg_table[id].type; - reg->size = ia32_reg_table[id].size; - - alias = ia32_reg_table[id].alias; - if ( alias ) { - reg->alias = ia32_reg_aliases[alias].alias; - reg->shift = ia32_reg_aliases[alias].shift; - } - reg->id = id; - - return; -} - -size_t ia32_true_register_id( size_t id ) { - size_t reg; - - if (! id || id > sz_regtable ) { - return 0; - } - - reg = id; - if (ia32_reg_table[reg].alias) { - reg = ia32_reg_aliases[ia32_reg_table[reg].alias].alias; - } - return reg; -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.h deleted file mode 100644 index fbbc77a17..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_reg.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef IA32_REG_H -#define IA32_REG_H - -#include /* for size_t */ -#include "libdis.h" /* for x86_reg_t */ - -/* NOTE these are used in opcode tables for hard-coded registers */ -#define REG_DWORD_OFFSET 1 /* 0 + 1 */ -#define REG_ECX_INDEX 2 /* 0 + 1 + 1 */ -#define REG_ESP_INDEX 5 /* 0 + 4 + 1 */ -#define REG_EBP_INDEX 6 /* 0 + 5 + 1 */ -#define REG_ESI_INDEX 7 /* 0 + 6 + 1 */ -#define REG_EDI_INDEX 8 /* 0 + 7 + 1 */ -#define REG_WORD_OFFSET 9 /* 1 * 8 + 1 */ -#define REG_BYTE_OFFSET 17 /* 2 * 8 + 1 */ -#define REG_MMX_OFFSET 25 /* 3 * 8 + 1 */ -#define REG_SIMD_OFFSET 33 /* 4 * 8 + 1 */ -#define REG_DEBUG_OFFSET 41 /* 5 * 8 + 1 */ -#define REG_CTRL_OFFSET 49 /* 6 * 8 + 1 */ -#define REG_TEST_OFFSET 57 /* 7 * 8 + 1 */ -#define REG_SEG_OFFSET 65 /* 8 * 8 + 1 */ -#define REG_LDTR_INDEX 71 /* 8 * 8 + 1 + 1 */ -#define REG_GDTR_INDEX 72 /* 8 * 8 + 2 + 1 */ -#define REG_FPU_OFFSET 73 /* 9 * 8 + 1 */ -#define REG_FLAGS_INDEX 81 /* 10 * 8 + 1 */ -#define REG_FPCTRL_INDEX 82 /* 10 * 8 + 1 + 1 */ -#define REG_FPSTATUS_INDEX 83 /* 10 * 8 + 2 + 1 */ -#define REG_FPTAG_INDEX 84 /* 10 * 8 + 3 + 1 */ -#define REG_EIP_INDEX 85 /* 10 * 8 + 4 + 1 */ -#define REG_IP_INDEX 86 /* 10 * 8 + 5 + 1 */ -#define REG_IDTR_INDEX 87 /* 10 * 8 + 6 + 1 */ -#define REG_MXCSG_INDEX 88 /* 10 * 8 + 7 + 1 */ -#define REG_TR_INDEX 89 /* 10 * 8 + 8 + 1 */ -#define REG_CSMSR_INDEX 90 /* 10 * 8 + 9 + 1 */ -#define REG_ESPMSR_INDEX 91 /* 10 * 8 + 10 + 1 */ -#define REG_EIPMSR_INDEX 92 /* 10 * 8 + 11 + 1 */ - -void ia32_handle_register( x86_reg_t *reg, size_t id ); -size_t ia32_true_register_id( size_t id ); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.c deleted file mode 100644 index b578e3448..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libdis.h" -#include "ia32_settings.h" -#include "ia32_reg.h" -#include "ia32_insn.h" - -ia32_settings_t ia32_settings = { - 1, 0xF4, - MAX_INSTRUCTION_SIZE, - 4, 4, 8, 4, 8, - REG_ESP_INDEX, REG_EBP_INDEX, REG_EIP_INDEX, REG_FLAGS_INDEX, - REG_DWORD_OFFSET, REG_SEG_OFFSET, REG_FPU_OFFSET, - opt_none -}; diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.h deleted file mode 100644 index 769c0e9fa..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_settings.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef IA32_SETTINGS_H -#define IA32_SETTINGS_H - -#include "libdis.h" - -typedef struct { - /* options */ - unsigned char endian, /* 0 = big, 1 = little */ - wc_byte, /* wildcard byte */ - max_insn, /* max insn size */ - sz_addr, /* default address size */ - sz_oper, /* default operand size */ - sz_byte, /* # bits in byte */ - sz_word, /* # bytes in machine word */ - sz_dword; /* # bytes in machine dword */ - unsigned int id_sp_reg, /* id of stack pointer */ - id_fp_reg, /* id of frame pointer */ - id_ip_reg, /* id of instruction pointer */ - id_flag_reg, /* id of flags register */ - offset_gen_regs, /* start of general regs */ - offset_seg_regs, /* start of segment regs */ - offset_fpu_regs; /* start of floating point regs */ - /* user-controlled settings */ - enum x86_options options; -} ia32_settings_t; - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdis.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdis.h deleted file mode 100644 index 83a88612a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdis.h +++ /dev/null @@ -1,832 +0,0 @@ -#ifndef LIBDISASM_H -#define LIBDISASM_H - -#include - -/* 'NEW" types - * __________________________________________________________________________*/ -#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */ - #define LIBDISASM_QWORD_H - #ifdef _MSC_VER - typedef __int64 qword_t; - #else - typedef int64_t qword_t; - #endif -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* 'NEW" x86 API - * __________________________________________________________________________*/ - - -/* ========================================= Error Reporting */ -/* REPORT CODES - * These are passed to a reporter function passed at initialization. - * Each code determines the type of the argument passed to the reporter; - * this allows the report to recover from errors, or just log them. - */ -enum x86_report_codes { - report_disasm_bounds, /* RVA OUT OF BOUNDS : The disassembler could - not disassemble the supplied RVA as it is - out of the range of the buffer. The - application should store the address and - attempt to determine what section of the - binary it is in, then disassemble the - address from the bytes in that section. - data: uint32_t rva */ - report_insn_bounds, /* INSTRUCTION OUT OF BOUNDS: The disassembler - could not disassemble the instruction as - the instruction would require bytes beyond - the end of the current buffer. This usually - indicated garbage bytes at the end of a - buffer, or an incorrectly-sized buffer. - data: uint32_t rva */ - report_invalid_insn, /* INVALID INSTRUCTION: The disassembler could - not disassemble the instruction as it has an - invalid combination of opcodes and operands. - This will stop automated disassembly; the - application can restart the disassembly - after the invalid instruction. - data: uint32_t rva */ - report_unknown -}; - -/* 'arg' is optional arbitrary data provided by the code passing the - * callback -- for example, it could be 'this' or 'self' in OOP code. - * 'code' is provided by libdisasm, it is one of the above - * 'data' is provided by libdisasm and is context-specific, per the enums */ -typedef void (*DISASM_REPORTER)( enum x86_report_codes code, - void *data, void *arg ); - - -/* x86_report_error : Call the register reporter to report an error */ -void x86_report_error( enum x86_report_codes code, void *data ); - -/* ========================================= Libdisasm Management Routines */ -enum x86_options { /* these can be ORed together */ - opt_none= 0, - opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */ - opt_16_bit=2, /* 16-bit/DOS disassembly */ - opt_att_mnemonics=4, /* use AT&T syntax names for alternate opcode mnemonics */ -}; - -/* management routines */ -/* 'arg' is caller-specific data which is passed as the first argument - * to the reporter callback routine */ -int x86_init( enum x86_options options, DISASM_REPORTER reporter, void *arg); -void x86_set_reporter( DISASM_REPORTER reporter, void *arg); -void x86_set_options( enum x86_options options ); -enum x86_options x86_get_options( void ); -int x86_cleanup(void); - - -/* ========================================= Instruction Representation */ -/* these defines are only intended for use in the array decl's */ -#define MAX_REGNAME 8 - -#define MAX_PREFIX_STR 32 -#define MAX_MNEM_STR 16 -#define MAX_INSN_SIZE 20 /* same as in i386.h */ -#define MAX_OP_STRING 32 /* max possible operand size in string form */ -#define MAX_OP_RAW_STRING 64 /* max possible operand size in raw form */ -#define MAX_OP_XML_STRING 256 /* max possible operand size in xml form */ -#define MAX_NUM_OPERANDS 8 /* max # implicit and explicit operands */ -/* in these, the '2 *' is arbitrary: the max # of operands should require - * more space than the rest of the insn */ -#define MAX_INSN_STRING 512 /* 2 * 8 * MAX_OP_STRING */ -#define MAX_INSN_RAW_STRING 1024 /* 2 * 8 * MAX_OP_RAW_STRING */ -#define MAX_INSN_XML_STRING 4096 /* 2 * 8 * MAX_OP_XML_STRING */ - -enum x86_reg_type { /* NOTE: these may be ORed together */ - reg_gen = 0x00001, /* general purpose */ - reg_in = 0x00002, /* incoming args, ala RISC */ - reg_out = 0x00004, /* args to calls, ala RISC */ - reg_local = 0x00008, /* local vars, ala RISC */ - reg_fpu = 0x00010, /* FPU data register */ - reg_seg = 0x00020, /* segment register */ - reg_simd = 0x00040, /* SIMD/MMX reg */ - reg_sys = 0x00080, /* restricted/system register */ - reg_sp = 0x00100, /* stack pointer */ - reg_fp = 0x00200, /* frame pointer */ - reg_pc = 0x00400, /* program counter */ - reg_retaddr = 0x00800, /* return addr for func */ - reg_cond = 0x01000, /* condition code / flags */ - reg_zero = 0x02000, /* zero register, ala RISC */ - reg_ret = 0x04000, /* return value */ - reg_src = 0x10000, /* array/rep source */ - reg_dest = 0x20000, /* array/rep destination */ - reg_count = 0x40000 /* array/rep/loop counter */ -}; - -/* x86_reg_t : an X86 CPU register */ -typedef struct { - char name[MAX_REGNAME]; - enum x86_reg_type type; /* what register is used for */ - unsigned int size; /* size of register in bytes */ - unsigned int id; /* register ID #, for quick compares */ - unsigned int alias; /* ID of reg this is an alias for */ - unsigned int shift; /* amount to shift aliased reg by */ -} x86_reg_t; - -/* x86_ea_t : an X86 effective address (address expression) */ -typedef struct { - unsigned int scale; /* scale factor */ - x86_reg_t index, base; /* index, base registers */ - int32_t disp; /* displacement */ - char disp_sign; /* is negative? 1/0 */ - char disp_size; /* 0, 1, 2, 4 */ -} x86_ea_t; - -/* x86_absolute_t : an X86 segment:offset address (descriptor) */ -typedef struct { - unsigned short segment; /* loaded directly into CS */ - union { - unsigned short off16; /* loaded directly into IP */ - uint32_t off32; /* loaded directly into EIP */ - } offset; -} x86_absolute_t; - -enum x86_op_type { /* mutually exclusive */ - op_unused = 0, /* empty/unused operand: should never occur */ - op_register = 1, /* CPU register */ - op_immediate = 2, /* Immediate Value */ - op_relative_near = 3, /* Relative offset from IP */ - op_relative_far = 4, /* Relative offset from IP */ - op_absolute = 5, /* Absolute address (ptr16:32) */ - op_expression = 6, /* Address expression (scale/index/base/disp) */ - op_offset = 7, /* Offset from start of segment (m32) */ - op_unknown -}; - -#define x86_optype_is_address( optype ) \ - ( optype == op_absolute || optype == op_offset ) -#define x86_optype_is_relative( optype ) \ - ( optype == op_relative_near || optype == op_relative_far ) -#define x86_optype_is_memory( optype ) \ - ( optype > op_immediate && optype < op_unknown ) - -enum x86_op_datatype { /* these use Intel's lame terminology */ - op_byte = 1, /* 1 byte integer */ - op_word = 2, /* 2 byte integer */ - op_dword = 3, /* 4 byte integer */ - op_qword = 4, /* 8 byte integer */ - op_dqword = 5, /* 16 byte integer */ - op_sreal = 6, /* 4 byte real (single real) */ - op_dreal = 7, /* 8 byte real (double real) */ - op_extreal = 8, /* 10 byte real (extended real) */ - op_bcd = 9, /* 10 byte binary-coded decimal */ - op_ssimd = 10, /* 16 byte : 4 packed single FP (SIMD, MMX) */ - op_dsimd = 11, /* 16 byte : 2 packed double FP (SIMD, MMX) */ - op_sssimd = 12, /* 4 byte : scalar single FP (SIMD, MMX) */ - op_sdsimd = 13, /* 8 byte : scalar double FP (SIMD, MMX) */ - op_descr32 = 14, /* 6 byte Intel descriptor 2:4 */ - op_descr16 = 15, /* 4 byte Intel descriptor 2:2 */ - op_pdescr32 = 16, /* 6 byte Intel pseudo-descriptor 32:16 */ - op_pdescr16 = 17, /* 6 byte Intel pseudo-descriptor 8:24:16 */ - op_bounds16 = 18, /* signed 16:16 lower:upper bounds */ - op_bounds32 = 19, /* signed 32:32 lower:upper bounds */ - op_fpuenv16 = 20, /* 14 byte FPU control/environment data */ - op_fpuenv32 = 21, /* 28 byte FPU control/environment data */ - op_fpustate16 = 22, /* 94 byte FPU state (env & reg stack) */ - op_fpustate32 = 23, /* 108 byte FPU state (env & reg stack) */ - op_fpregset = 24, /* 512 bytes: register set */ - op_fpreg = 25, /* FPU register */ - op_none = 0xFF, /* operand without a datatype (INVLPG) */ -}; - -enum x86_op_access { /* ORed together */ - op_read = 1, - op_write = 2, - op_execute = 4 -}; - -enum x86_op_flags { /* ORed together, but segs are mutually exclusive */ - op_signed = 1, /* signed integer */ - op_string = 2, /* possible string or array */ - op_constant = 4, /* symbolic constant */ - op_pointer = 8, /* operand points to a memory address */ - op_sysref = 0x010, /* operand is a syscall number */ - op_implied = 0x020, /* operand is implicit in the insn */ - op_hardcode = 0x40, /* operand is hardcoded in insn definition */ - /* NOTE: an 'implied' operand is one which can be considered a side - * effect of the insn, e.g. %esp being modified by PUSH or POP. A - * 'hard-coded' operand is one which is specified in the instruction - * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference - * is that hard-coded operands are printed by disassemblers and are - * required to re-assemble, while implicit operands are invisible. */ - op_es_seg = 0x100, /* ES segment override */ - op_cs_seg = 0x200, /* CS segment override */ - op_ss_seg = 0x300, /* SS segment override */ - op_ds_seg = 0x400, /* DS segment override */ - op_fs_seg = 0x500, /* FS segment override */ - op_gs_seg = 0x600 /* GS segment override */ -}; - -/* x86_op_t : an X86 instruction operand */ -typedef struct { - enum x86_op_type type; /* operand type */ - enum x86_op_datatype datatype; /* operand size */ - enum x86_op_access access; /* operand access [RWX] */ - enum x86_op_flags flags; /* misc flags */ - union { - /* sizeof will have to work on these union members! */ - /* immediate values */ - char sbyte; - short sword; - int32_t sdword; - qword_t sqword; - unsigned char byte; - unsigned short word; - uint32_t dword; - qword_t qword; - float sreal; - double dreal; - /* misc large/non-native types */ - unsigned char extreal[10]; - unsigned char bcd[10]; - qword_t dqword[2]; - unsigned char simd[16]; - unsigned char fpuenv[28]; - /* offset from segment */ - uint32_t offset; - /* ID of CPU register */ - x86_reg_t reg; - /* offsets from current insn */ - char relative_near; - int32_t relative_far; - /* segment:offset */ - x86_absolute_t absolute; - /* effective address [expression] */ - x86_ea_t expression; - } data; - /* this is needed to make formatting operands more sane */ - void * insn; /* pointer to x86_insn_t owning operand */ -} x86_op_t; - -/* Linked list of x86_op_t; provided for manual traversal of the operand - * list in an insn. Users wishing to add operands to this list, e.g. to add - * implicit operands, should use x86_operand_new in x86_operand_list.h */ -typedef struct x86_operand_list { - x86_op_t op; - struct x86_operand_list *next; -} x86_oplist_t; - -enum x86_insn_group { - insn_none = 0, /* invalid instruction */ - insn_controlflow = 1, - insn_arithmetic = 2, - insn_logic = 3, - insn_stack = 4, - insn_comparison = 5, - insn_move = 6, - insn_string = 7, - insn_bit_manip = 8, - insn_flag_manip = 9, - insn_fpu = 10, - insn_interrupt = 13, - insn_system = 14, - insn_other = 15 -}; - -enum x86_insn_type { - insn_invalid = 0, /* invalid instruction */ - /* insn_controlflow */ - insn_jmp = 0x1001, - insn_jcc = 0x1002, - insn_call = 0x1003, - insn_callcc = 0x1004, - insn_return = 0x1005, - /* insn_arithmetic */ - insn_add = 0x2001, - insn_sub = 0x2002, - insn_mul = 0x2003, - insn_div = 0x2004, - insn_inc = 0x2005, - insn_dec = 0x2006, - insn_shl = 0x2007, - insn_shr = 0x2008, - insn_rol = 0x2009, - insn_ror = 0x200A, - /* insn_logic */ - insn_and = 0x3001, - insn_or = 0x3002, - insn_xor = 0x3003, - insn_not = 0x3004, - insn_neg = 0x3005, - /* insn_stack */ - insn_push = 0x4001, - insn_pop = 0x4002, - insn_pushregs = 0x4003, - insn_popregs = 0x4004, - insn_pushflags = 0x4005, - insn_popflags = 0x4006, - insn_enter = 0x4007, - insn_leave = 0x4008, - /* insn_comparison */ - insn_test = 0x5001, - insn_cmp = 0x5002, - /* insn_move */ - insn_mov = 0x6001, /* move */ - insn_movcc = 0x6002, /* conditional move */ - insn_xchg = 0x6003, /* exchange */ - insn_xchgcc = 0x6004, /* conditional exchange */ - /* insn_string */ - insn_strcmp = 0x7001, - insn_strload = 0x7002, - insn_strmov = 0x7003, - insn_strstore = 0x7004, - insn_translate = 0x7005, /* xlat */ - /* insn_bit_manip */ - insn_bittest = 0x8001, - insn_bitset = 0x8002, - insn_bitclear = 0x8003, - /* insn_flag_manip */ - insn_clear_carry = 0x9001, - insn_clear_zero = 0x9002, - insn_clear_oflow = 0x9003, - insn_clear_dir = 0x9004, - insn_clear_sign = 0x9005, - insn_clear_parity = 0x9006, - insn_set_carry = 0x9007, - insn_set_zero = 0x9008, - insn_set_oflow = 0x9009, - insn_set_dir = 0x900A, - insn_set_sign = 0x900B, - insn_set_parity = 0x900C, - insn_tog_carry = 0x9010, - insn_tog_zero = 0x9020, - insn_tog_oflow = 0x9030, - insn_tog_dir = 0x9040, - insn_tog_sign = 0x9050, - insn_tog_parity = 0x9060, - /* insn_fpu */ - insn_fmov = 0xA001, - insn_fmovcc = 0xA002, - insn_fneg = 0xA003, - insn_fabs = 0xA004, - insn_fadd = 0xA005, - insn_fsub = 0xA006, - insn_fmul = 0xA007, - insn_fdiv = 0xA008, - insn_fsqrt = 0xA009, - insn_fcmp = 0xA00A, - insn_fcos = 0xA00C, - insn_fldpi = 0xA00D, - insn_fldz = 0xA00E, - insn_ftan = 0xA00F, - insn_fsine = 0xA010, - insn_fsys = 0xA020, - /* insn_interrupt */ - insn_int = 0xD001, - insn_intcc = 0xD002, /* not present in x86 ISA */ - insn_iret = 0xD003, - insn_bound = 0xD004, - insn_debug = 0xD005, - insn_trace = 0xD006, - insn_invalid_op = 0xD007, - insn_oflow = 0xD008, - /* insn_system */ - insn_halt = 0xE001, - insn_in = 0xE002, /* input from port/bus */ - insn_out = 0xE003, /* output to port/bus */ - insn_cpuid = 0xE004, - /* insn_other */ - insn_nop = 0xF001, - insn_bcdconv = 0xF002, /* convert to or from BCD */ - insn_szconv = 0xF003 /* change size of operand */ -}; - -/* These flags specify special characteristics of the instruction, such as - * whether the inatruction is privileged or whether it serializes the - * pipeline. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_note { - insn_note_ring0 = 1, /* Only available in ring 0 */ - insn_note_smm = 2, /* "" in System Management Mode */ - insn_note_serial = 4, /* Serializing instruction */ - insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */ - insn_note_nosuffix = 16, /* Does not have size suffix in att-style formatting */ -}; - -/* This specifies what effects the instruction has on the %eflags register */ -enum x86_flag_status { - insn_carry_set = 0x1, /* CF */ - insn_zero_set = 0x2, /* ZF */ - insn_oflow_set = 0x4, /* OF */ - insn_dir_set = 0x8, /* DF */ - insn_sign_set = 0x10, /* SF */ - insn_parity_set = 0x20, /* PF */ - insn_carry_or_zero_set = 0x40, - insn_zero_set_or_sign_ne_oflow = 0x80, - insn_carry_clear = 0x100, - insn_zero_clear = 0x200, - insn_oflow_clear = 0x400, - insn_dir_clear = 0x800, - insn_sign_clear = 0x1000, - insn_parity_clear = 0x2000, - insn_sign_eq_oflow = 0x4000, - insn_sign_ne_oflow = 0x8000 -}; - -/* The CPU model in which the insturction first appeared; this can be used - * to mask out instructions appearing in earlier or later models or to - * check the portability of a binary. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_cpu { - cpu_8086 = 1, /* Intel */ - cpu_80286 = 2, - cpu_80386 = 3, - cpu_80387 = 4, - cpu_80486 = 5, - cpu_pentium = 6, - cpu_pentiumpro = 7, - cpu_pentium2 = 8, - cpu_pentium3 = 9, - cpu_pentium4 = 10, - cpu_k6 = 16, /* AMD */ - cpu_k7 = 32, - cpu_athlon = 48 -}; - -/* CPU ISA subsets: These are derived from the Instruction Groups in - * Intel Vol 1 Chapter 5; they represent subsets of the IA32 ISA but - * do not reflect the 'type' of the instruction in the same way that - * x86_insn_group does. In short, these are AMD/Intel's somewhat useless - * designations. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_isa { - isa_gp = 1, /* general purpose */ - isa_fp = 2, /* floating point */ - isa_fpumgt = 3, /* FPU/SIMD management */ - isa_mmx = 4, /* Intel MMX */ - isa_sse1 = 5, /* Intel SSE SIMD */ - isa_sse2 = 6, /* Intel SSE2 SIMD */ - isa_sse3 = 7, /* Intel SSE3 SIMD */ - isa_3dnow = 8, /* AMD 3DNow! SIMD */ - isa_sys = 9 /* system instructions */ -}; - -enum x86_insn_prefix { - insn_no_prefix = 0, - insn_rep_zero = 1, /* REPZ and REPE */ - insn_rep_notzero = 2, /* REPNZ and REPNZ */ - insn_lock = 4 /* LOCK: */ -}; - -/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */ -/* x86_insn_t : an X86 instruction */ -typedef struct { - /* information about the instruction */ - uint32_t addr; /* load address */ - uint32_t offset; /* offset into file/buffer */ - enum x86_insn_group group; /* meta-type, e.g. INS_EXEC */ - enum x86_insn_type type; /* type, e.g. INS_BRANCH */ - enum x86_insn_note note; /* note, e.g. RING0 */ - unsigned char bytes[MAX_INSN_SIZE]; - unsigned char size; /* size of insn in bytes */ - /* 16/32-bit mode settings */ - unsigned char addr_size; /* default address size : 2 or 4 */ - unsigned char op_size; /* default operand size : 2 or 4 */ - /* CPU/instruction set */ - enum x86_insn_cpu cpu; - enum x86_insn_isa isa; - /* flags */ - enum x86_flag_status flags_set; /* flags set or tested by insn */ - enum x86_flag_status flags_tested; - /* stack */ - unsigned char stack_mod; /* 0 or 1 : is the stack modified? */ - int32_t stack_mod_val; /* val stack is modified by if known */ - - /* the instruction proper */ - enum x86_insn_prefix prefix; /* prefixes ORed together */ - char prefix_string[MAX_PREFIX_STR]; /* prefixes [might be truncated] */ - char mnemonic[MAX_MNEM_STR]; - x86_oplist_t *operands; /* list of explicit/implicit operands */ - size_t operand_count; /* total number of operands */ - size_t explicit_count; /* number of explicit operands */ - /* convenience fields for user */ - void *block; /* code block containing this insn */ - void *function; /* function containing this insn */ - int tag; /* tag the insn as seen/processed */ -} x86_insn_t; - - -/* returns 0 if an instruction is invalid, 1 if valid */ -int x86_insn_is_valid( x86_insn_t *insn ); - -/* DISASSEMBLY ROUTINES - * Canonical order of arguments is - * (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func) - * ...but of course all of these are not used at the same time. - */ - - -/* Function prototype for caller-supplied callback routine - * These callbacks are intended to process 'insn' further, e.g. by - * adding it to a linked list, database, etc */ -typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg ); - -/* Function prototype for caller-supplied address resolver. - * This routine is used to determine the rva to disassemble next, given - * the 'dest' operand of a jump/call. This allows the caller to resolve - * jump/call targets stored in a register or on the stack, and also allows - * the caller to prevent endless loops by checking if an address has - * already been disassembled. If an address cannot be resolved from the - * operand, or if the address has already been disassembled, this routine - * should return -1; in all other cases the RVA to be disassembled next - * should be returned. */ -typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn, - void *arg ); - - -/* x86_disasm: Disassemble a single instruction from a buffer of bytes. - * Returns size of instruction in bytes. - * Caller is responsible for calling x86_oplist_free() on - * a reused "insn" to avoid leaking memory when calling this - * function repeatedly. - * buf : Buffer of bytes to disassemble - * buf_len : Length of the buffer - * buf_rva : Load address of the start of the buffer - * offset : Offset in buffer to disassemble - * insn : Structure to fill with disassembled instruction - */ -unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - x86_insn_t * insn ); - -/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer, - * invoking a callback function each time an instruction - * is successfully disassembled. The 'range' refers to the - * bytes between 'offset' and 'offset + len' in the buffer; - * 'len' is assumed to be less than the length of the buffer. - * Returns number of instructions processed. - * buf : Buffer of bytes to disassemble (e.g. .text section) - * buf_rva : Load address of buffer (e.g. ELF Virtual Address) - * offset : Offset in buffer to start disassembly at - * len : Number of bytes to disassemble - * func : Callback function to invoke (may be NULL) - * arg : Arbitrary data to pass to callback (may be NULL) - */ -unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva, - unsigned int offset, unsigned int len, - DISASM_CALLBACK func, void *arg ); - -/* x86_disasm_forward: Flow-of-execution disassembly of the bytes in a buffer, - * invoking a callback function each time an instruction - * is successfully disassembled. - * buf : Buffer to disassemble (e.g. .text section) - * buf_len : Number of bytes in buffer - * buf_rva : Load address of buffer (e.g. ELF Virtual Address) - * offset : Offset in buffer to start disassembly at (e.g. entry point) - * func : Callback function to invoke (may be NULL) - * arg : Arbitrary data to pass to callback (may be NULL) - * resolver: Caller-supplied address resolver. If no resolver is - * supplied, a default internal one is used -- however the - * internal resolver does NOT catch loops and could end up - * disassembling forever.. - * r_arg : Arbitrary data to pass to resolver (may be NULL) - */ -unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - DISASM_CALLBACK func, void *arg, - DISASM_RESOLVER resolver, void *r_arg ); - -/* Instruction operands: these are stored as a list of explicit and - * implicit operands. It is recommended that the 'foreach' routines - * be used to when examining operands for purposes of data flow analysis */ - -/* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the - * foreach routine, 'insn' is the x86_insn_t whose operands are being - * iterated over, and 'op' is the current x86_op_t */ -typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg); - -/* FOREACH types: these are used to limit the foreach results to - * operands which match a certain "type" (implicit or explicit) - * or which are accessed in certain ways (e.g. read or write). Note - * that this operates on the operand list of single instruction, so - * specifying the 'real' operand type (register, memory, etc) is not - * useful. Note also that by definition Execute Access implies Read - * Access and implies Not Write Access. - * The "type" (implicit or explicit) and the access method can - * be ORed together, e.g. op_wo | op_explicit */ -enum x86_op_foreach_type { - op_any = 0, /* ALL operands (explicit, implicit, rwx) */ - op_dest = 1, /* operands with Write access */ - op_src = 2, /* operands with Read access */ - op_ro = 3, /* operands with Read but not Write access */ - op_wo = 4, /* operands with Write but not Read access */ - op_xo = 5, /* operands with Execute access */ - op_rw = 6, /* operands with Read AND Write access */ - op_implicit = 0x10, /* operands that are implied by the opcode */ - op_explicit = 0x20 /* operands that are not side-effects */ -}; - - -/* free the operand list associated with an instruction -- useful for - * preventing memory leaks when free()ing an x86_insn_t */ -void x86_oplist_free( x86_insn_t *insn ); - -/* Operand foreach: invokes 'func' with 'insn' and 'arg' as arguments. The - * 'type' parameter is used to select only operands matching specific - * criteria. */ -int x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg, - enum x86_op_foreach_type type); - -/* convenience routine: returns count of operands matching 'type' */ -size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type ); - -/* accessor functions for the operands */ -x86_op_t * x86_operand_1st( x86_insn_t *insn ); -x86_op_t * x86_operand_2nd( x86_insn_t *insn ); -x86_op_t * x86_operand_3rd( x86_insn_t *insn ); - -/* these allow libdisasm 2.0 accessor functions to still be used */ -#define x86_get_dest_operand( insn ) x86_operand_1st( insn ) -#define x86_get_src_operand( insn ) x86_operand_2nd( insn ) -#define x86_get_imm_operand( insn ) x86_operand_3rd( insn ) - -/* get size of operand data in bytes */ -unsigned int x86_operand_size( x86_op_t *op ); - -/* Operand Convenience Routines: the following three routines are common - * operations on operands, intended to ease the burden of the programmer. */ - -/* Get Address: return the value of an offset operand, or the offset of - * a segment:offset absolute address */ -uint32_t x86_get_address( x86_insn_t *insn ); - -/* Get Relative Offset: return as a sign-extended int32_t the near or far - * relative offset operand, or 0 if there is none. There can be only one - * relaive offset operand in an instruction. */ -int32_t x86_get_rel_offset( x86_insn_t *insn ); - -/* Get Branch Target: return the x86_op_t containing the target of - * a jump or call operand, or NULL if there is no branch target. - * Internally, a 'branch target' is defined as any operand with - * Execute Access set. There can be only one branch target per instruction. */ -x86_op_t * x86_get_branch_target( x86_insn_t *insn ); - -/* Get Immediate: return the x86_op_t containing the immediate operand - * for this instruction, or NULL if there is no immediate operand. There - * can be only one immediate operand per instruction */ -x86_op_t * x86_get_imm( x86_insn_t *insn ); - -/* Get Raw Immediate Data: returns a pointer to the immediate data encoded - * in the instruction. This is useful for large data types [>32 bits] currently - * not supported by libdisasm, or for determining if the disassembler - * screwed up the conversion of the immediate data. Note that 'imm' in this - * context refers to immediate data encoded at the end of an instruction as - * detailed in the Intel Manual Vol II Chapter 2; it does not refer to the - * 'op_imm' operand (the third operand in instructions like 'mul' */ -unsigned char * x86_get_raw_imm( x86_insn_t *insn ); - - -/* More accessor fuctions, this time for user-defined info... */ -/* set the address (usually RVA) of the insn */ -void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ); - -/* set the offset (usually offset into file) of the insn */ -void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ); - -/* set a pointer to the function owning the instruction. The - * type of 'func' is user-defined; libdisasm does not use the func field. */ -void x86_set_insn_function( x86_insn_t *insn, void * func ); - -/* set a pointer to the block of code owning the instruction. The - * type of 'block' is user-defined; libdisasm does not use the block field. */ -void x86_set_insn_block( x86_insn_t *insn, void * block ); - -/* instruction tagging: these routines allow the programmer to mark - * instructions as "seen" in a DFS, for example. libdisasm does not use - * the tag field.*/ -/* set insn->tag to 1 */ -void x86_tag_insn( x86_insn_t *insn ); -/* set insn->tag to 0 */ -void x86_untag_insn( x86_insn_t *insn ); -/* return insn->tag */ -int x86_insn_is_tagged( x86_insn_t *insn ); - - -/* Disassembly formats: - * AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm" - * Intel is standard MASM/NASM/TASM: "mnemonic\tdest,src, imm" - * Native is tab-delimited: "RVA\tbytes\tmnemonic\tdest\tsrc\timm" - * XML is your typical ... - * Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7 - */ -enum x86_asm_format { - unknown_syntax = 0, /* never use! */ - native_syntax, /* header: 35 bytes */ - intel_syntax, /* header: 23 bytes */ - att_syntax, /* header: 23 bytes */ - xml_syntax, /* header: 679 bytes */ - raw_syntax /* header: 172 bytes */ -}; - -/* format (sprintf) an operand into 'buf' using specified syntax */ -int x86_format_operand(x86_op_t *op, char *buf, int len, - enum x86_asm_format format); - -/* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */ -int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format); - -/* format (sprintf) an instruction into 'buf' using specified syntax; - * this includes formatting all operands */ -int x86_format_insn(x86_insn_t *insn, char *buf, int len, enum x86_asm_format); - -/* fill 'buf' with a description of the format's syntax */ -int x86_format_header( char *buf, int len, enum x86_asm_format format); - -/* Endianness of an x86 CPU : 0 is big, 1 is little; always returns 1 */ -unsigned int x86_endian(void); - -/* Default address and operand size in bytes */ -unsigned int x86_addr_size(void); -unsigned int x86_op_size(void); - -/* Size of a machine word in bytes */ -unsigned int x86_word_size(void); - -/* maximum size of a code instruction */ -#define x86_max_inst_size(x) x86_max_insn_size(x) -unsigned int x86_max_insn_size(void); - -/* register IDs of Stack, Frame, Instruction pointer and Flags register */ -unsigned int x86_sp_reg(void); -unsigned int x86_fp_reg(void); -unsigned int x86_ip_reg(void); -unsigned int x86_flag_reg(void); - -/* fill 'reg' struct with details of register 'id' */ -void x86_reg_from_id( unsigned int id, x86_reg_t * reg ); - -/* convenience macro demonstrating how to get an aliased register; proto is - * void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg ) - * where 'alias_reg' is a reg operand and 'output_reg' is filled with the - * register that the operand is an alias for */ -#define x86_get_aliased_reg( alias_reg, output_reg ) \ - x86_reg_from_id( alias_reg->alias, output_reg ) - - -/* ================================== Invariant Instruction Representation */ -/* Invariant instructions are used for generating binary signatures; - * the instruction is modified so that all variant bytes in an instruction - * are replaced with a wildcard byte. - * - * A 'variant byte' is one that is expected to be modified by either the - * static or the dynamic linker: for example, an address encoded in an - * instruction. - * - * By comparing the invariant representation of one instruction [or of a - * sequence of instructions] with the invariant representation of another, - * one determine whether the two invariant representations are from the same - * relocatable object [.o] file. Thus one can use binary signatures [which - * are just sequences of invariant instruction representations] to look for - * library routines which have been statically-linked into a binary. - * - * The invariant routines are faster and smaller than the disassembly - * routines; they can be used to determine the size of an instruction - * without all of the overhead of a full instruction disassembly. - */ - -/* This byte is used to replace variant bytes */ -#define X86_WILDCARD_BYTE 0xF4 - -typedef struct { - enum x86_op_type type; /* operand type */ - enum x86_op_datatype datatype; /* operand size */ - enum x86_op_access access; /* operand access [RWX] */ - enum x86_op_flags flags; /* misc flags */ -} x86_invariant_op_t; - -typedef struct { - unsigned char bytes[64]; /* invariant representation */ - unsigned int size; /* number of bytes in insn */ - enum x86_insn_group group; /* meta-type, e.g. INS_EXEC */ - enum x86_insn_type type; /* type, e.g. INS_BRANCH */ - x86_invariant_op_t operands[3]; /* operands: dest, src, imm */ -} x86_invariant_t; - - -/* return a version of the instruction with the variant bytes masked out */ -size_t x86_invariant_disasm( unsigned char *buf, int buf_len, - x86_invariant_t *inv ); -/* return the size in bytes of the intruction pointed to by 'buf'; - * this used x86_invariant_disasm since it faster than x86_disasm */ -size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdisasm.gyp b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdisasm.gyp deleted file mode 100644 index 5c8dc4586..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/libdisasm.gyp +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'libdisasm', - 'type': 'static_library', - 'sources': [ - 'ia32_implicit.c', - 'ia32_implicit.h', - 'ia32_insn.c', - 'ia32_insn.h', - 'ia32_invariant.c', - 'ia32_invariant.h', - 'ia32_modrm.c', - 'ia32_modrm.h', - 'ia32_opcode_tables.c', - 'ia32_opcode_tables.h', - 'ia32_operand.c', - 'ia32_operand.h', - 'ia32_reg.c', - 'ia32_reg.h', - 'ia32_settings.c', - 'ia32_settings.h', - 'libdis.h', - 'qword.h', - 'x86_disasm.c', - 'x86_format.c', - 'x86_imm.c', - 'x86_imm.h', - 'x86_insn.c', - 'x86_misc.c', - 'x86_operand_list.c', - 'x86_operand_list.h', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/qword.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/qword.h deleted file mode 100644 index 5f0e803c9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/qword.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LIBDISASM_QWORD_H -#define LIBDISASM_QWORD_H - -#include - -/* platform independent data types */ - -#ifdef _MSC_VER - typedef __int64 qword_t; -#else - typedef int64_t qword_t; -#endif - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/Makefile b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/Makefile deleted file mode 100644 index 44ef486b6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# change these values if you need to -SWIG = swig # apt-get install swig ! -GCC = gcc - -CC_FLAGS = -c -fPIC -LD_FLAGS = -shared -L../.. -ldisasm - -BASE_NAME = x86disasm - -export INTERFACE_FILE BASE_NAME SWIG GCC CC_FLAGS LD_FLAGS - -#==================================================== -# TARGETS - -all: swig -dummy: swig swig-python swig-ruby swig-perl swig-tcl install uninstall clean - -swig: swig-python swig-perl -# swig-rub swig-tcl - -swig-python: - cd python && make -f Makefile-swig - -swig-ruby: - cd ruby && make -f Makefile-swig - -swig-perl: - cd perl && make -f Makefile-swig - -swig-tcl: - cd tcl && make -f Makefile-swig - -# ================================================================== -install: install-python install-perl -# install-ruby install-tcl - -install-python: - cd python && sudo make -f Makefile-swig install - -install-ruby: - cd ruby && sudo make -f Makefile-swig install - -install-perl: - cd perl && sudo make -f Makefile-swig install - -install-tcl: - cd tcl && sudo make -f Makefile-swig install - -# ================================================================== -uninstall: uninstall-python -#uninstall-ruby uninstall-perl uninstall-tcl - -uninstall-python: - cd python && sudo make -f Makefile-swig uninstall - -uninstall-ruby: - cd ruby && sudo make -f Makefile-swig uninstall - -uninstall-perl: - cd perl && sudo make -f Makefile-swig uninstall - -uninstall-tcl: - cd tcl && sudo make -f Makefile-swig uninstall - -# ================================================================== -clean: - cd python && make -f Makefile-swig clean - cd ruby && make -f Makefile-swig clean - cd perl && make -f Makefile-swig clean - cd tcl && make -f Makefile-swig clean diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/README b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/README deleted file mode 100644 index a9fa79ec2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/README +++ /dev/null @@ -1,128 +0,0 @@ - Libdisasm SWIG README - -The SWIG utility (www.swig.org) can be used to generate - - -Building SWIG Modules ---------------------- - - make - make install - -Make and Install both build Python, Perl, Ruby, and Tcl modules. If you -do not have one of these languages installed, comment out the relevant -target in the main Makefile. - -Install uses 'sudo' to put files in the correct locations; if you -do not have sudo installed, change the install targets. - -The Module API --------------- - -The OOP API ------------ - - -The Python Module ------------------ - -To test that the module loads: - - bash# python - >>> import x86disasm - >>> x86disasm.version_string() - '0.21-pre' - >>>^D - bash# - - >>> import x86disasm - >>> import array - >>> disasm = x86disasm.X86_Disasm( ) - >>> tgt = open( "/tmp/a.out", "rb" ) - >>> tgt.seek( 0, 2 ) - >>> size = tgt.tell() - >>> tgt.seek( 0, 0 ) - >>> buf = array.array( 'B' ) - >>> buf.fromfile( tgt, size ) - >>> tgt.close() - >>> data = x86disasm.byteArray( size ) - >>> for i in range( size ): - ... data[i] = buf.pop(0) - ... - >>> del buf - >>> del tgt - >>> insn = disasm.disasm( data, size - 1, 0, 0 ) - >>> insn.format( x86disasm.att_syntax ) - 'jg\t0x00000047' - >>> insn.format( x86disasm.raw_syntax ) - '0x00000000|0x00000000|2|7F 45 |||controlflow|jcc|jg|80386|General Purpose|||zero_clear sign_eq_oflow |0|0|relative|sbyte|00000047|' - >>> ops = insn.operand_list() - >>> node = ops.first() - >>> while node is not None: - ... s = node.op.format(x86disasm.raw_syntax) - ... print s - ... node = ops.next() - ... - relative|sbyte|00000047| - - - - - - -The Perl Module ---------------- - -To test that the module loads: - - bash# perl - use x86disasm; - print x86disasm::version_string() . "\n"; - ^D - 0.21-pre - bash# - -The Ruby Module ---------------- - -To test that the module loads: - - bash# irb - irb(main):001:0> require 'x86disasm' - => true - irb(main):002:0> X86disasm.version_string() - => "0.21-pre" - irb(main):003:0> x = X86disasm::X86_Disasm.new - => # - irb(main):004:0> x.max_register_string() - => 8 - irb(main):003:0> ^D - bash# - -The Tcl Module ---------------- - -To test that the module loads: - - bash# tclsh - % load /usr/lib/tcl8.3/x86disasm.so X86disasm - % version_string - 0.21-pre - % ^D - bash# - - % x86_init 0 NULL NULL - OR - % x86disasm dis - _486b0708_p_x86disasm - % puts "[dis cget -last_error]" - 0 - - - - -The Interface Files -------------------- - - libdisasm.i -- interface file without shadow classes - libdisasm_oop.i -- interface file with shadow classes diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm.i b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm.i deleted file mode 100644 index ec1204175..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm.i +++ /dev/null @@ -1,508 +0,0 @@ -%module x86disasm -%{ -#include "../../libdis.h" -#include "../../../config.h" -%} - -%rename(version_string) x86_version_string; -%include "../../libdis.h" -#include "../../../config.h" - -%inline %{ - const char * x86_version_string( void ) { - return PACKAGE_VERSION; - } -%} - -%rename(report_codes) x86_report_codes; -%rename(report_error) x86_report_error; -%rename(options) x86_options; -%rename(init) x86_init; -%rename(set_reporter) x86_set_reporter; -%rename(set_options) x86_set_options; -%rename(options) x86_get_options; -%rename(cleanup) x86_cleanup; -%rename(reg_type) x86_reg_type; -%rename(reg) x86_reg_t; -%rename(eaddr) x86_ea_t; -%rename(op_type) x86_op_type; -%rename(optype_is_address) x86_optype_is_address; -%rename(optype_is_relative) x86_optype_is_relative; -%rename(op_datatype) x86_op_datatype; -%rename(op_access) x86_op_access; -%rename(op_flags) x86_op_flags; -%rename(operand) x86_op_t; -%rename(insn_group) x86_insn_group; -%rename(insn_type) x86_insn_type; -%rename(insn_note) x86_insn_note ; -%rename(flag_status) x86_flag_status; -%rename(insn_cpu) x86_insn_cpu ; -%rename(insn_isa) x86_insn_isa ; -%rename(insn_prefix) x86_insn_prefix ; -%rename(insn) x86_insn_t; -%rename(insn_is_valid) x86_insn_is_valid; -%rename(i_disasm) x86_disasm; -%rename(i_disasm_range) x86_disasm_range; -%rename(i_disasm_forward) x86_disasm_forward; -%rename(insn_operand_count) x86_operand_count; -%rename(insn_operand_1st) x86_operand_1st; -%rename(insn_operand_2nd) x86_operand_2nd; -%rename(insn_operand_3rd) x86_operand_3rd; -%rename(insn_dest_operand) x86_get_dest_operand; -%rename(insn_src_operand) x86_get_src_operand; -%rename(insn_imm_operand) x86_get_imm_operand; -%rename(operand_size) x86_operand_size; -%rename(insn_rel_offset) x86_get_rel_offset; -%rename(insn_branch_target) x86_get_branch_target; -%rename(insn_imm) x86_get_imm; -%rename(insn_raw_imm) x86_get_raw_imm; -%rename(insn_set_addr) x86_set_insn_addr; -%rename(insn_set_offset) x86_set_insn_offset; -%rename(insn_set_function) x86_set_insn_function; -%rename(insn_set_block) x86_set_insn_block; -%rename(insn_tag) x86_tag_insn; -%rename(insn_untag) x86_untag_insn; -%rename(insn_is_tagged) x86_insn_is_tagged; -%rename(asm_format) x86_asm_format; -%rename(operand_format) x86_format_operand; -%rename(insn_format_mnemonic) x86_format_mnemonic; -%rename(insn_format) x86_format_insn; -%rename(header_format) x86_format_header; -%rename(endian) x86_endian; -%rename(size_default_address) x86_addr_size; -%rename(size_default_operand) x86_op_size; -%rename(size_machine_word) x86_word_size; -%rename(size_max_insn) x86_max_insn_size; -%rename(reg_sp) x86_sp_reg; -%rename(reg_fp) x86_fp_reg; -%rename(reg_ip) x86_ip_reg; -%rename(reg_from_id) x86_reg_from_id; -%rename(reg_from_alias) x86_get_aliased_reg; -%rename(invariant_op) x86_invariant_op_t; -%rename(invariant) x86_invariant_t; -%rename(disasm_invariant) x86_invariant_disasm; -%rename(disasm_size) x86_size_disasm; - -%include "carrays.i" - -%array_class( unsigned char, byteArray ); - - -%apply (unsigned char *STRING, int LENGTH) { - (unsigned char *buf, size_t buf_len) -}; - - -%newobject x86_op_copy; -%inline %{ - x86_op_t * x86_op_copy( x86_op_t * src ) { - x86_op_t *op; - - if (! src ) { - return NULL; - } - - op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 ); - if ( op ) { - memcpy( op, src, sizeof(x86_op_t) ); - } - - return op; - } - - typedef struct x86_op_list_node { - x86_op_t *op; - struct x86_op_list_node *next, *prev; - } x86_op_list_node; - - typedef struct x86_op_list { - size_t count; - x86_op_list_node *head, *tail, *curr; - } x86_op_list; - - x86_op_list * x86_op_list_new () { - x86_op_list *list = (x86_op_list *) - calloc( sizeof(x86_op_list), 1 ); - list->count = 0; - return list; - } - - void x86_op_list_free(x86_op_list *list) { - x86_op_list_node *node, *next; - - node = list->head; - while ( node ) { - next = node->next; - /* free( node->insn ); */ - free( node ); - node = next; - } - - free( list ); - } - - x86_op_list_node * x86_op_list_first(x86_op_list *list) { - return list->head; - } - - x86_op_list_node * x86_op_list_last(x86_op_list *list) { - return list->tail; - } - - x86_op_list_node * x86_op_list_next(x86_op_list *list) { - if (! list->curr ) { - list->curr = list->head; - return list->head; - } - - list->curr = list->curr->next; - return list->curr; - } - - x86_op_list_node * x86_op_list_prev(x86_op_list *list) { - if (! list->curr ) { - list->curr = list->tail; - return list->tail; - } - - list->curr = list->curr->prev; - return list->curr; - } - -%} - -%newobject x86_op_list_append; - -%inline %{ - void x86_op_list_append( x86_op_list * list, x86_op_t *op ) { - x86_op_list_node *node = (x86_op_list_node *) - calloc( sizeof(x86_op_list_node) , 1 ); - if (! node ) { - return; - } - - list->count++; - if ( ! list->tail ) { - list->head = list->tail = node; - } else { - list->tail->next = node; - node->prev = list->tail; - list->tail = node; - } - - node->op = x86_op_copy( op ); - } - - x86_oplist_t * x86_op_list_node_copy( x86_oplist_t * list ) { - x86_oplist_t *ptr; - ptr = (x86_oplist_t *) calloc( sizeof(x86_oplist_t), 1 ); - if ( ptr ) { - memcpy( &ptr->op, &list->op, sizeof(x86_op_t) ); - } - - return ptr; - } - - x86_insn_t * x86_insn_new() { - x86_insn_t *insn = (x86_insn_t *) - calloc( sizeof(x86_insn_t), 1 ); - return insn; - } - - void x86_insn_free( x86_insn_t *insn ) { - x86_oplist_free( insn ); - free( insn ); - } -%} - -%newobject x86_insn_copy; - -%inline %{ - x86_insn_t * x86_insn_copy( x86_insn_t *src) { - x86_oplist_t *ptr, *list, *last = NULL; - x86_insn_t *insn = (x86_insn_t *) - calloc( sizeof(x86_insn_t), 1 ); - - if ( insn ) { - memcpy( insn, src, sizeof(x86_insn_t) ); - insn->operands = NULL; - insn->block = NULL; - insn->function = NULL; - - /* copy operand list */ - for ( list = src->operands; list; list = list->next ) { - ptr = x86_op_list_node_copy( list ); - - if (! ptr ) { - continue; - } - - if ( insn->operands ) { - last->next = ptr; - } else { - insn->operands = ptr; - } - last = ptr; - } - } - - return insn; - } - - x86_op_list * x86_insn_op_list( x86_insn_t *insn ) { - x86_oplist_t *list = insn->operands; - x86_op_list *op_list = x86_op_list_new(); - - for ( list = insn->operands; list; list = list->next ) { - x86_op_list_append( op_list, &list->op ); - } - - return op_list; - } - - typedef struct x86_insn_list_node { - x86_insn_t *insn; - struct x86_insn_list_node *next, *prev; - } x86_insn_list_node; - - typedef struct x86_insn_list { - size_t count; - x86_insn_list_node *head, *tail, *curr; - } x86_insn_list; - -%} - -%newobject x86_insn_list_new; - -%inline %{ - x86_insn_list * x86_insn_list_new () { - x86_insn_list *list = (x86_insn_list *) - calloc( sizeof(x86_insn_list), 1 ); - list->count = 0; - return list; - } - - void x86_insn_list_free( x86_insn_list * list ) { - x86_insn_list_node *node, *next; - - if (! list ) { - return; - } - - node = list->head; - while ( node ) { - next = node->next; - /* free( node->insn ); */ - free( node ); - node = next; - } - - free( list ); - } - - x86_insn_list_node * x86_insn_list_first( x86_insn_list *list ) { - if (! list ) { - return NULL; - } - return list->head; - } - - x86_insn_list_node * x86_insn_list_last( x86_insn_list *list ) { - if (! list ) { - return NULL; - } - return list->tail; - } - - x86_insn_list_node * x86_insn_list_next( x86_insn_list *list ) { - if (! list ) { - return NULL; - } - if (! list->curr ) { - list->curr = list->head; - return list->head; - } - - list->curr = list->curr->next; - return list->curr; - } - - x86_insn_list_node * x86_insn_list_prev( x86_insn_list *list ) { - if (! list ) { - return NULL; - } - if (! list->curr ) { - list->curr = list->tail; - return list->tail; - } - - list->curr = list->curr->prev; - return list->curr; - } - -%} - -%newobject x86_insn_list_append; - -%inline %{ - void x86_insn_list_append( x86_insn_list *list, x86_insn_t *insn ) { - x86_insn_list_node *node; - if (! list ) { - return; - } - - node = (x86_insn_list_node *) - calloc( sizeof(x86_insn_list_node) , 1 ); - - if (! node ) { - return; - } - - list->count++; - if ( ! list->tail ) { - list->head = list->tail = node; - } else { - list->tail->next = node; - node->prev = list->tail; - list->tail = node; - } - - node->insn = x86_insn_copy( insn ); - } - - typedef struct { - enum x86_report_codes last_error; - void * last_error_data; - void * disasm_callback; - void * disasm_resolver; - } x86disasm; - - void x86_default_reporter( enum x86_report_codes code, - void *data, void *arg ) { - x86disasm *dis = (x86disasm *) arg; - if ( dis ) { - dis->last_error = code; - dis->last_error_data = data; - } - } - - void x86_default_callback( x86_insn_t *insn, void *arg ) { - x86_insn_list *list = (x86_insn_list *) arg; - if ( list ) { - x86_insn_list_append( list, insn ); - } - } - - /* TODO: resolver stack, maybe a callback */ - long x86_default_resolver( x86_op_t *op, x86_insn_t *insn, void *arg ) { - x86disasm *dis = (x86disasm *) arg; - if ( dis ) { - //return dis->resolver( op, insn ); - return 0; - } - - return 0; - } - - -%} - -%newobject x86disasm_new; - -%inline %{ - x86disasm * x86disasm_new ( enum x86_options options ) { - x86disasm * dis = (x86disasm *) - calloc( sizeof( x86disasm ), 1 ); - x86_init( options, x86_default_reporter, dis ); - return dis; - } - - void x86disasm_free( x86disasm * dis ) { - x86_cleanup(); - free( dis ); - } -%} - -%newobject x86_disasm; - -%inline %{ - x86_insn_t * disasm( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset ) { - x86_insn_t *insn = calloc( sizeof( x86_insn_t ), 1 ); - x86_disasm( buf, buf_len, buf_rva, offset, insn ); - return insn; - } - - int disasm_range( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset, - unsigned int len ) { - - x86_insn_list *list = x86_insn_list_new(); - - if ( len > buf_len ) { - len = buf_len; - } - - return x86_disasm_range( buf, buf_rva, offset, len, - x86_default_callback, list ); - } - - int disasm_forward( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset ) { - x86_insn_list *list = x86_insn_list_new(); - - /* use default resolver: damn SWIG callbacks! */ - return x86_disasm_forward( buf, buf_len, buf_rva, offset, - x86_default_callback, list, - x86_default_resolver, NULL ); - } - - size_t disasm_invariant( unsigned char *buf, size_t buf_len, - x86_invariant_t *inv ) { - return x86_invariant_disasm( buf, buf_len, inv ); - } - - size_t disasm_size( unsigned char *buf, size_t buf_len ) { - return x86_size_disasm( buf, buf_len ); - } - - int x86_max_operand_string( enum x86_asm_format format ) { - switch ( format ) { - case xml_syntax: - return MAX_OP_XML_STRING; - break; - case raw_syntax: - return MAX_OP_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - return MAX_OP_STRING; - break; - } - } - - - int x86_max_insn_string( enum x86_asm_format format ) { - switch ( format ) { - case xml_syntax: - return MAX_INSN_XML_STRING; - break; - case raw_syntax: - return MAX_INSN_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - return MAX_INSN_STRING; - break; - } - } - - int x86_max_num_operands( ) { return MAX_NUM_OPERANDS; } -%} - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm_oop.i b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm_oop.i deleted file mode 100644 index 973a47e27..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/libdisasm_oop.i +++ /dev/null @@ -1,1114 +0,0 @@ -%module x86disasm -%{ -#ifdef _MSC_VER - typedef __int64 qword; -#else - typedef long long qword; -#endif - -#include - -#define MAX_REGNAME 8 -#define MAX_PREFIX_STR 32 -#define MAX_MNEM_STR 16 -#define MAX_INSN_SIZE 20 -#define MAX_OP_STRING 32 -#define MAX_OP_RAW_STRING 64 -#define MAX_OP_XML_STRING 256 -#define MAX_NUM_OPERANDS 8 -#define MAX_INSN_STRING 512 -#define MAX_INSN_RAW_STRING 1024 -#define MAX_INSN_XML_STRING 4096 - -#include "../../../config.h" - - -const char * version_string( void ) { - return PACKAGE_VERSION; -} - -%} - -const char * version_string( void ); - -%rename(X86_Register) x86_reg_t; -%rename(X86_EAddr) x86_ea_t; -%rename(X86_Operand) x86_op_t; -//%rename(X86_OpList) x86_oplist_t; -%rename(X86_Insn) x86_insn_t; -%rename(X86_InvOperand) x86_invariant_op_t; -%rename(X86_Invariant) x86_invariant_t; - -%include "carrays.i" - -%array_class( unsigned char, byteArray ); - - -%apply (unsigned char *STRING, int LENGTH) { - (unsigned char *buf, size_t buf_len) -}; - - -%inline %{ - - -enum x86_asm_format { - unknown_syntax = 0, /* never use! */ - native_syntax, /* header: 35 bytes */ - intel_syntax, /* header: 23 bytes */ - att_syntax, /* header: 23 bytes */ - xml_syntax, /* header: 679 bytes */ - raw_syntax /* header: 172 bytes */ -}; -%} - -/* ================================================================== */ -/* operand class */ -%inline %{ - enum x86_reg_type { - reg_gen = 0x00001, reg_in = 0x00002, - reg_out = 0x00004, reg_local = 0x00008, - reg_fpu = 0x00010, reg_seg = 0x00020, - reg_simd = 0x00040, reg_sys = 0x00080, - reg_sp = 0x00100, reg_fp = 0x00200, - reg_pc = 0x00400, reg_retaddr = 0x00800, - reg_cond = 0x01000, reg_zero = 0x02000, - reg_ret = 0x04000, reg_src = 0x10000, - reg_dest = 0x20000, reg_count = 0x40000 - }; - - typedef struct { - char name[MAX_REGNAME]; - enum x86_reg_type type; - unsigned int size; - unsigned int id; - unsigned int alias; - unsigned int shift; - } x86_reg_t; - - void x86_reg_from_id( unsigned int id, x86_reg_t * reg ); - - typedef struct { - unsigned int scale; - x86_reg_t index, base; - long disp; - char disp_sign; - char disp_size; - } x86_ea_t; - - enum x86_op_type { - op_unused = 0, - op_register = 1, - op_immediate = 2, - op_relative_near = 3, - op_relative_far = 4, - op_absolute = 5, - op_expression = 6, - op_offset = 7, - op_unknown - }; - - enum x86_op_datatype { - op_byte = 1, op_word = 2, - op_dword = 3, op_qword = 4, - op_dqword = 5, op_sreal = 6, - op_dreal = 7, op_extreal = 8, - op_bcd = 9, op_ssimd = 10, - op_dsimd = 11, op_sssimd = 12, - op_sdsimd = 13, op_descr32 = 14, - op_descr16 = 15, op_pdescr32 = 16, - op_pdescr16 = 17, op_fpuenv = 18, - op_fpregset = 19, - }; - - enum x86_op_access { - op_read = 1, - op_write = 2, - op_execute = 4 - }; - - enum x86_op_flags { - op_signed = 1, op_string = 2, - op_constant = 4, op_pointer = 8, - op_sysref = 0x010, op_implied = 0x020, - op_hardcode = 0x40, op_es_seg = 0x100, - op_cs_seg = 0x200, op_ss_seg = 0x300, - op_ds_seg = 0x400, op_fs_seg = 0x500, - op_gs_seg = 0x600 - }; - - typedef struct { - enum x86_op_type type; - enum x86_op_datatype datatype; - enum x86_op_access access; - enum x86_op_flags flags; - union { - char sbyte; - short sword; - long sdword; - qword sqword; - unsigned char byte; - unsigned short word; - unsigned long dword; - qword qword; - float sreal; - double dreal; - unsigned char extreal[10]; - unsigned char bcd[10]; - qword dqword[2]; - unsigned char simd[16]; - unsigned char fpuenv[28]; - void * address; - unsigned long offset; - x86_reg_t reg; - char relative_near; - long relative_far; - x86_ea_t expression; - } data; - void * insn; - } x86_op_t; - - unsigned int x86_operand_size( x86_op_t *op ); - - int x86_format_operand(x86_op_t *op, char *buf, int len, - enum x86_asm_format format); -%} - -%extend x86_reg_t{ - x86_reg_t * aliased_reg( ) { - x86_reg_t * reg = (x86_reg_t * ) - calloc( sizeof(x86_reg_t), 1 ); - x86_reg_from_id( self->id, reg ); - return reg; - } -} - -%extend x86_op_t{ - size_t size() { - return x86_operand_size( self ); - } - char * format( enum x86_asm_format format ) { - char *buf, *str; - size_t len; - - switch ( format ) { - case xml_syntax: - len = MAX_OP_XML_STRING; - break; - case raw_syntax: - len = MAX_OP_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - len = MAX_OP_STRING; - break; - } - - buf = (char * ) calloc( len + 1, 1 ); - x86_format_operand( self, buf, len, format ); - - /* drop buffer down to a reasonable size */ - str = strdup( buf ); - free(buf); - return str; - } - - int is_address( ) { - if ( self->type == op_absolute || - self->type == op_offset ) { - return 1; - } - - return 0; - } - - int is_relative( ) { - if ( self->type == op_relative_near || - self->type == op_relative_far ) { - return 1; - } - - return 0; - } - - %newobject copy; - x86_op_t * copy() { - x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 ); - - if ( op ) { - memcpy( op, self, sizeof(x86_op_t) ); - } - - return op; - } -} - -/* ================================================================== */ -/* operand list class */ -%inline %{ - typedef struct X86_OpListNode { - x86_op_t *op; - struct X86_OpListNode *next, *prev; - } X86_OpListNode; - - typedef struct X86_OpList { - size_t count; - X86_OpListNode *head, *tail, *curr; - } X86_OpList; -%} - -%extend X86_OpList { - X86_OpList () { - X86_OpList *list = (X86_OpList *) - calloc( sizeof(X86_OpList), 1 ); - list->count = 0; - return list; - } - - ~X86_OpList() { - X86_OpListNode *node, *next; - - node = self->head; - while ( node ) { - next = node->next; - /* free( node->insn ); */ - free( node ); - node = next; - } - - free( self ); - } - - X86_OpListNode * first() { - self->curr = self->head; - return self->head; - } - - X86_OpListNode * last() { - self->curr = self->tail; - return self->tail; - } - - X86_OpListNode * next() { - if (! self->curr ) { - self->curr = self->head; - return self->head; - } - - self->curr = self->curr->next; - return self->curr; - } - - X86_OpListNode * prev() { - if (! self->curr ) { - self->curr = self->tail; - return self->tail; - } - - self->curr = self->curr->prev; - return self->curr; - } - - %newobject append; - void append( x86_op_t *op ) { - X86_OpListNode *node = (X86_OpListNode *) - calloc( sizeof(X86_OpListNode) , 1 ); - if (! node ) { - return; - } - - self->count++; - if ( ! self->tail ) { - self->head = self->tail = node; - } else { - self->tail->next = node; - node->prev = self->tail; - self->tail = node; - } - - node->op = x86_op_t_copy( op ); - } -} - -%inline %{ - typedef struct x86_operand_list { - x86_op_t op; - struct x86_operand_list *next; - } x86_oplist_t; -%} - -%extend x86_oplist_t { - %newobject x86_oplist_node_copy; -} - -/* ================================================================== */ -/* instruction class */ -%inline %{ - x86_oplist_t * x86_oplist_node_copy( x86_oplist_t * list ) { - x86_oplist_t *ptr; - ptr = (x86_oplist_t *) calloc( sizeof(x86_oplist_t), 1 ); - if ( ptr ) { - memcpy( &ptr->op, &list->op, sizeof(x86_op_t) ); - } - - return ptr; - } - - enum x86_insn_group { - insn_none = 0, insn_controlflow = 1, - insn_arithmetic = 2, insn_logic = 3, - insn_stack = 4, insn_comparison = 5, - insn_move = 6, insn_string = 7, - insn_bit_manip = 8, insn_flag_manip = 9, - insn_fpu = 10, insn_interrupt = 13, - insn_system = 14, insn_other = 15 - }; - - enum x86_insn_type { - insn_invalid = 0, insn_jmp = 0x1001, - insn_jcc = 0x1002, insn_call = 0x1003, - insn_callcc = 0x1004, insn_return = 0x1005, - insn_add = 0x2001, insn_sub = 0x2002, - insn_mul = 0x2003, insn_div = 0x2004, - insn_inc = 0x2005, insn_dec = 0x2006, - insn_shl = 0x2007, insn_shr = 0x2008, - insn_rol = 0x2009, insn_ror = 0x200A, - insn_and = 0x3001, insn_or = 0x3002, - insn_xor = 0x3003, insn_not = 0x3004, - insn_neg = 0x3005, insn_push = 0x4001, - insn_pop = 0x4002, insn_pushregs = 0x4003, - insn_popregs = 0x4004, insn_pushflags = 0x4005, - insn_popflags = 0x4006, insn_enter = 0x4007, - insn_leave = 0x4008, insn_test = 0x5001, - insn_cmp = 0x5002, insn_mov = 0x6001, - insn_movcc = 0x6002, insn_xchg = 0x6003, - insn_xchgcc = 0x6004, insn_strcmp = 0x7001, - insn_strload = 0x7002, insn_strmov = 0x7003, - insn_strstore = 0x7004, insn_translate = 0x7005, - insn_bittest = 0x8001, insn_bitset = 0x8002, - insn_bitclear = 0x8003, insn_clear_carry = 0x9001, - insn_clear_zero = 0x9002, insn_clear_oflow = 0x9003, - insn_clear_dir = 0x9004, insn_clear_sign = 0x9005, - insn_clear_parity = 0x9006, insn_set_carry = 0x9007, - insn_set_zero = 0x9008, insn_set_oflow = 0x9009, - insn_set_dir = 0x900A, insn_set_sign = 0x900B, - insn_set_parity = 0x900C, insn_tog_carry = 0x9010, - insn_tog_zero = 0x9020, insn_tog_oflow = 0x9030, - insn_tog_dir = 0x9040, insn_tog_sign = 0x9050, - insn_tog_parity = 0x9060, insn_fmov = 0xA001, - insn_fmovcc = 0xA002, insn_fneg = 0xA003, - insn_fabs = 0xA004, insn_fadd = 0xA005, - insn_fsub = 0xA006, insn_fmul = 0xA007, - insn_fdiv = 0xA008, insn_fsqrt = 0xA009, - insn_fcmp = 0xA00A, insn_fcos = 0xA00C, - insn_fldpi = 0xA00D, insn_fldz = 0xA00E, - insn_ftan = 0xA00F, insn_fsine = 0xA010, - insn_fsys = 0xA020, insn_int = 0xD001, - insn_intcc = 0xD002, insn_iret = 0xD003, - insn_bound = 0xD004, insn_debug = 0xD005, - insn_trace = 0xD006, insn_invalid_op = 0xD007, - insn_oflow = 0xD008, insn_halt = 0xE001, - insn_in = 0xE002, insn_out = 0xE003, - insn_cpuid = 0xE004, insn_nop = 0xF001, - insn_bcdconv = 0xF002, insn_szconv = 0xF003 - }; - - enum x86_insn_note { - insn_note_ring0 = 1, - insn_note_smm = 2, - insn_note_serial = 4 - }; - - enum x86_flag_status { - insn_carry_set = 0x1, - insn_zero_set = 0x2, - insn_oflow_set = 0x4, - insn_dir_set = 0x8, - insn_sign_set = 0x10, - insn_parity_set = 0x20, - insn_carry_or_zero_set = 0x40, - insn_zero_set_or_sign_ne_oflow = 0x80, - insn_carry_clear = 0x100, - insn_zero_clear = 0x200, - insn_oflow_clear = 0x400, - insn_dir_clear = 0x800, - insn_sign_clear = 0x1000, - insn_parity_clear = 0x2000, - insn_sign_eq_oflow = 0x4000, - insn_sign_ne_oflow = 0x8000 - }; - - enum x86_insn_cpu { - cpu_8086 = 1, cpu_80286 = 2, - cpu_80386 = 3, cpu_80387 = 4, - cpu_80486 = 5, cpu_pentium = 6, - cpu_pentiumpro = 7, cpu_pentium2 = 8, - cpu_pentium3 = 9, cpu_pentium4 = 10, - cpu_k6 = 16, cpu_k7 = 32, - cpu_athlon = 48 - }; - - enum x86_insn_isa { - isa_gp = 1, isa_fp = 2, - isa_fpumgt = 3, isa_mmx = 4, - isa_sse1 = 5, isa_sse2 = 6, - isa_sse3 = 7, isa_3dnow = 8, - isa_sys = 9 - }; - - enum x86_insn_prefix { - insn_no_prefix = 0, - insn_rep_zero = 1, - insn_rep_notzero = 2, - insn_lock = 4 - }; - - - typedef struct { - unsigned long addr; - unsigned long offset; - enum x86_insn_group group; - enum x86_insn_type type; - enum x86_insn_note note; - unsigned char bytes[MAX_INSN_SIZE]; - unsigned char size; - unsigned char addr_size; - unsigned char op_size; - enum x86_insn_cpu cpu; - enum x86_insn_isa isa; - enum x86_flag_status flags_set; - enum x86_flag_status flags_tested; - unsigned char stack_mod; - long stack_mod_val; - enum x86_insn_prefix prefix; - char prefix_string[MAX_PREFIX_STR]; - char mnemonic[MAX_MNEM_STR]; - x86_oplist_t *operands; - size_t operand_count; - size_t explicit_count; - void *block; - void *function; - int tag; - } x86_insn_t; - - typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, - void *arg); - - enum x86_op_foreach_type { - op_any = 0, - op_dest = 1, - op_src = 2, - op_ro = 3, - op_wo = 4, - op_xo = 5, - op_rw = 6, - op_implicit = 0x10, - op_explicit = 0x20 - }; - - size_t x86_operand_count( x86_insn_t *insn, - enum x86_op_foreach_type type ); - x86_op_t * x86_operand_1st( x86_insn_t *insn ); - x86_op_t * x86_operand_2nd( x86_insn_t *insn ); - x86_op_t * x86_operand_3rd( x86_insn_t *insn ); - long x86_get_rel_offset( x86_insn_t *insn ); - x86_op_t * x86_get_branch_target( x86_insn_t *insn ); - x86_op_t * x86_get_imm( x86_insn_t *insn ); - unsigned char * x86_get_raw_imm( x86_insn_t *insn ); - void x86_set_insn_addr( x86_insn_t *insn, unsigned long addr ); - int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format); - int x86_format_insn(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format); - void x86_oplist_free( x86_insn_t *insn ); - int x86_insn_is_valid( x86_insn_t *insn ); -%} - -%extend x86_insn_t { - x86_insn_t() { - x86_insn_t *insn = (x86_insn_t *) - calloc( sizeof(x86_insn_t), 1 ); - return insn; - } - ~x86_insn_t() { - x86_oplist_free( self ); - free( self ); - } - - int is_valid( ) { - return x86_insn_is_valid( self ); - } - - x86_op_t * operand_1st() { - return x86_operand_1st( self ); - } - - x86_op_t * operand_2nd() { - return x86_operand_2nd( self ); - } - - x86_op_t * operand_3rd() { - return x86_operand_3rd( self ); - } - - x86_op_t * operand_dest() { - return x86_operand_1st( self ); - } - - x86_op_t * operand_src() { - return x86_operand_2nd( self ); - } - - size_t num_operands( enum x86_op_foreach_type type ) { - return x86_operand_count( self, type ); - } - - long rel_offset() { - return x86_get_rel_offset( self ); - } - - x86_op_t * branch_target() { - return x86_get_branch_target( self ); - } - - x86_op_t * imm() { - return x86_get_imm( self ); - } - - unsigned char * raw_imm() { - return x86_get_raw_imm( self ); - } - - %newobject format; - char * format( enum x86_asm_format format ) { - char *buf, *str; - size_t len; - - switch ( format ) { - case xml_syntax: - len = MAX_INSN_XML_STRING; - break; - case raw_syntax: - len = MAX_INSN_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - len = MAX_INSN_STRING; - break; - } - - buf = (char * ) calloc( len + 1, 1 ); - x86_format_insn( self, buf, len, format ); - - /* drop buffer down to a reasonable size */ - str = strdup( buf ); - free(buf); - return str; - } - - %newobject format_mnemonic; - char * format_mnemonic( enum x86_asm_format format ) { - char *buf, *str; - size_t len = MAX_MNEM_STR + MAX_PREFIX_STR + 4; - - buf = (char * ) calloc( len, 1 ); - x86_format_mnemonic( self, buf, len, format ); - - /* drop buffer down to a reasonable size */ - str = strdup( buf ); - free(buf); - - return str; - } - - %newobject copy; - x86_insn_t * copy() { - x86_oplist_t *ptr, *list, *last = NULL; - x86_insn_t *insn = (x86_insn_t *) - calloc( sizeof(x86_insn_t), 1 ); - - if ( insn ) { - memcpy( insn, self, sizeof(x86_insn_t) ); - insn->operands = NULL; - insn->block = NULL; - insn->function = NULL; - - /* copy operand list */ - for ( list = self->operands; list; list = list->next ) { - ptr = x86_oplist_node_copy( list ); - - if (! ptr ) { - continue; - } - - if ( insn->operands ) { - last->next = ptr; - } else { - insn->operands = ptr; - } - last = ptr; - } - } - - return insn; - } - - X86_OpList * operand_list( ) { - x86_oplist_t *list = self->operands; - X86_OpList *op_list = new_X86_OpList(); - - for ( list = self->operands; list; list = list->next ) { - X86_OpList_append( op_list, &list->op ); - } - - return op_list; - } -} - -/* ================================================================== */ -/* invariant instruction class */ -%inline %{ - #define X86_WILDCARD_BYTE 0xF4 - - typedef struct { - enum x86_op_type type; - enum x86_op_datatype datatype; - enum x86_op_access access; - enum x86_op_flags flags; - } x86_invariant_op_t; - - typedef struct { - unsigned char bytes[64]; - unsigned int size; - enum x86_insn_group group; - enum x86_insn_type type; - x86_invariant_op_t operands[3]; - } x86_invariant_t; -%} - -%extend x86_invariant_t { - - x86_invariant_t() { - x86_invariant_t *inv = (x86_invariant_t *) - calloc( sizeof(x86_invariant_t), 1 ); - return inv; - } - - ~x86_invariant_t() { - free( self ); - } -} - -/* ================================================================== */ -/* instruction list class */ -%inline %{ - typedef struct X86_InsnListNode { - x86_insn_t *insn; - struct X86_InsnListNode *next, *prev; - } X86_InsnListNode; - - typedef struct X86_InsnList { - size_t count; - X86_InsnListNode *head, *tail, *curr; - } X86_InsnList; -%} - -%extend X86_InsnList { - X86_InsnList () { - X86_InsnList *list = (X86_InsnList *) - calloc( sizeof(X86_InsnList), 1 ); - list->count = 0; - return list; - } - - ~X86_InsnList() { - X86_InsnListNode *node, *next; - - node = self->head; - while ( node ) { - next = node->next; - /* free( node->insn ); */ - free( node ); - node = next; - } - - free( self ); - } - - X86_InsnListNode * first() { return self->head; } - - X86_InsnListNode * last() { return self->tail; } - - X86_InsnListNode * next() { - if (! self->curr ) { - self->curr = self->head; - return self->head; - } - - self->curr = self->curr->next; - return self->curr; - } - - X86_InsnListNode * prev() { - if (! self->curr ) { - self->curr = self->tail; - return self->tail; - } - - self->curr = self->curr->prev; - return self->curr; - } - - %newobject append; - void append( x86_insn_t *insn ) { - X86_InsnListNode *node = (X86_InsnListNode *) - calloc( sizeof(X86_InsnListNode) , 1 ); - if (! node ) { - return; - } - - self->count++; - if ( ! self->tail ) { - self->head = self->tail = node; - } else { - self->tail->next = node; - node->prev = self->tail; - self->tail = node; - } - - node->insn = x86_insn_t_copy( insn ); - } -} - -/* ================================================================== */ -/* address table class */ -/* slight TODO */ - -/* ================================================================== */ -/* Main disassembler class */ -%inline %{ - - enum x86_options { - opt_none= 0, - opt_ignore_nulls=1, - opt_16_bit=2 - }; - enum x86_report_codes { - report_disasm_bounds, - report_insn_bounds, - report_invalid_insn, - report_unknown - }; - - - typedef struct { - enum x86_report_codes last_error; - void * last_error_data; - void * disasm_callback; - void * disasm_resolver; - } X86_Disasm; - - typedef void (*DISASM_REPORTER)( enum x86_report_codes code, - void *data, void *arg ); - typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg ); - typedef long (*DISASM_RESOLVER)( x86_op_t *op, - x86_insn_t * current_insn, - void *arg ); - - void x86_report_error( enum x86_report_codes code, void *data ); - int x86_init( enum x86_options options, DISASM_REPORTER reporter, - void *arg); - void x86_set_reporter( DISASM_REPORTER reporter, void *arg); - void x86_set_options( enum x86_options options ); - enum x86_options x86_get_options( void ); - int x86_cleanup(void); - int x86_format_header( char *buf, int len, enum x86_asm_format format); - unsigned int x86_endian(void); - unsigned int x86_addr_size(void); - unsigned int x86_op_size(void); - unsigned int x86_word_size(void); - unsigned int x86_max_insn_size(void); - unsigned int x86_sp_reg(void); - unsigned int x86_fp_reg(void); - unsigned int x86_ip_reg(void); - size_t x86_invariant_disasm( unsigned char *buf, int buf_len, - x86_invariant_t *inv ); - size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ); - int x86_disasm( unsigned char *buf, unsigned int buf_len, - unsigned long buf_rva, unsigned int offset, - x86_insn_t * insn ); - int x86_disasm_range( unsigned char *buf, unsigned long buf_rva, - unsigned int offset, unsigned int len, - DISASM_CALLBACK func, void *arg ); - int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, - unsigned long buf_rva, unsigned int offset, - DISASM_CALLBACK func, void *arg, - DISASM_RESOLVER resolver, void *r_arg ); - - void x86_default_reporter( enum x86_report_codes code, - void *data, void *arg ) { - X86_Disasm *dis = (X86_Disasm *) arg; - if ( dis ) { - dis->last_error = code; - dis->last_error_data = data; - } - } - - void x86_default_callback( x86_insn_t *insn, void *arg ) { - X86_InsnList *list = (X86_InsnList *) arg; - if ( list ) { - X86_InsnList_append( list, insn ); - } - } - - /* TODO: resolver stack, maybe a callback */ - long x86_default_resolver( x86_op_t *op, x86_insn_t *insn, void *arg ) { - X86_Disasm *dis = (X86_Disasm *) arg; - if ( dis ) { - //return dis->resolver( op, insn ); - return 0; - } - - return 0; - } - -%} - -%extend X86_Disasm { - - X86_Disasm( ) { - X86_Disasm * dis = (X86_Disasm *) - calloc( sizeof( X86_Disasm ), 1 ); - x86_init( opt_none, x86_default_reporter, dis ); - return dis; - } - - X86_Disasm( enum x86_options options ) { - X86_Disasm * dis = (X86_Disasm *) - calloc( sizeof( X86_Disasm ), 1 ); - x86_init( options, x86_default_reporter, dis ); - return dis; - } - - X86_Disasm( enum x86_options options, DISASM_REPORTER reporter ) { - X86_Disasm * dis = (X86_Disasm *) - calloc( sizeof( X86_Disasm ), 1 ); - x86_init( options, reporter, NULL ); - return dis; - } - - X86_Disasm( enum x86_options options, DISASM_REPORTER reporter, - void * arg ) { - X86_Disasm * dis = (X86_Disasm *) - calloc( sizeof( X86_Disasm ), 1 ); - x86_init( options, reporter, arg ); - return dis; - } - - ~X86_Disasm() { - x86_cleanup(); - free( self ); - } - - void set_options( enum x86_options options ) { - return x86_set_options( options ); - } - - enum x86_options options() { - return x86_get_options(); - } - - void set_callback( void * callback ) { - self->disasm_callback = callback; - } - - void set_resolver( void * callback ) { - self->disasm_resolver = callback; - } - - void report_error( enum x86_report_codes code ) { - x86_report_error( code, NULL ); - } - - %newobject disasm; - x86_insn_t * disasm( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset ) { - x86_insn_t *insn = calloc( sizeof( x86_insn_t ), 1 ); - x86_disasm( buf, buf_len, buf_rva, offset, insn ); - return insn; - } - - int disasm_range( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset, - unsigned int len ) { - - X86_InsnList *list = new_X86_InsnList(); - - if ( len > buf_len ) { - len = buf_len; - } - - return x86_disasm_range( buf, buf_rva, offset, len, - x86_default_callback, list ); - } - - int disasm_forward( unsigned char *buf, size_t buf_len, - unsigned long buf_rva, unsigned int offset ) { - X86_InsnList *list = new_X86_InsnList(); - - /* use default resolver: damn SWIG callbacks! */ - return x86_disasm_forward( buf, buf_len, buf_rva, offset, - x86_default_callback, list, - x86_default_resolver, NULL ); - } - - size_t disasm_invariant( unsigned char *buf, size_t buf_len, - x86_invariant_t *inv ) { - return x86_invariant_disasm( buf, buf_len, inv ); - } - - size_t disasm_size( unsigned char *buf, size_t buf_len ) { - return x86_size_disasm( buf, buf_len ); - } - - %newobject format_header; - char * format_header( enum x86_asm_format format) { - char *buf, *str; - size_t len; - - switch ( format ) { - /* these were obtained from x86_format.c */ - case xml_syntax: - len = 679; break; - case raw_syntax: - len = 172; break; - case native_syntax: - len = 35; break; - case intel_syntax: - len = 23; break; - case att_syntax: - len = 23; break; - case unknown_syntax: - default: - len = 23; break; - } - - buf = (char * ) calloc( len + 1, 1 ); - x86_format_header( buf, len, format ); - - return buf; - } - - unsigned int endian() { - return x86_endian(); - } - - unsigned int addr_size() { - return x86_addr_size(); - } - - unsigned int op_size() { - return x86_op_size(); - } - - unsigned int word_size() { - return x86_word_size(); - } - - unsigned int max_insn_size() { - return x86_max_insn_size(); - } - - unsigned int sp_reg() { - return x86_sp_reg(); - } - - unsigned int fp_reg() { - return x86_fp_reg(); - } - - unsigned int ip_reg() { - return x86_ip_reg(); - } - - %newobject reg_from_id; - x86_reg_t * reg_from_id( unsigned int id ) { - x86_reg_t * reg = calloc( sizeof(x86_reg_t), 1 ); - x86_reg_from_id( id, reg ); - return reg; - } - - unsigned char wildcard_byte() { return X86_WILDCARD_BYTE; } - - int max_register_string() { return MAX_REGNAME; } - - int max_prefix_string() { return MAX_PREFIX_STR; } - - int max_mnemonic_string() { return MAX_MNEM_STR; } - - int max_operand_string( enum x86_asm_format format ) { - switch ( format ) { - case xml_syntax: - return MAX_OP_XML_STRING; - break; - case raw_syntax: - return MAX_OP_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - return MAX_OP_STRING; - break; - } - } - - - int max_insn_string( enum x86_asm_format format ) { - switch ( format ) { - case xml_syntax: - return MAX_INSN_XML_STRING; - break; - case raw_syntax: - return MAX_INSN_RAW_STRING; - break; - case native_syntax: - case intel_syntax: - case att_syntax: - case unknown_syntax: - default: - return MAX_INSN_STRING; - break; - } - } - - int max_num_operands( ) { return MAX_NUM_OPERANDS; } -} - -/* python callback, per the manual */ -/*%typemap(python,in) PyObject *pyfunc { - if (!PyCallable_Check($source)) { - PyErr_SetString(PyExc_TypeError, "Need a callable object!"); - return NULL; - } - $target = $source; -}*/ - -/* python FILE * callback, per the manual */ -/* -%typemap(python,in) FILE * { - if (!PyFile_Check($source)) { - PyErr_SetString(PyExc_TypeError, "Need a file!"); - return NULL; - } - $target = PyFile_AsFile($source); -}*/ - - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile-swig b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile-swig deleted file mode 100644 index 9f3a64573..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile-swig +++ /dev/null @@ -1,65 +0,0 @@ -ifndef BASE_NAME -BASE_NAME = x86disasm -endif - -ifndef SWIG -SWIG = swig # apt-get install swig ! -endif - -ifndef GCC -GCC = gcc -endif - -ifndef CC_FLAGS -CC_FLAGS = -c -fPIC -endif - -ifndef LD_FLAGS -LD_FLAGS = -shared -L.. -ldisasm -endif - -INTERFACE_FILE = libdisasm_oop.i - -SWIG_INTERFACE = ../$(INTERFACE_FILE) - -# PERL rules -PERL_MOD = blib/arch/auto/$(BASE_NAME)/$(BASE_NAME).so -PERL_SHADOW = $(BASE_NAME)_wrap.c -PERL_SWIG = $(BASE_NAME).pl -PERL_OBJ = $(BASE_NAME)_wrap.o -PERL_INC = `perl -e 'use Config; print $$Config{archlib};'`/CORE -PERL_CC_FLAGS = `perl -e 'use Config; print $$Config{ccflags};'` - -#==================================================== -# TARGETS - -all: swig-perl - -dummy: swig-perl install uninstall clean - -swig-perl: $(PERL_MOD) - -$(PERL_MOD): $(PERL_OBJ) - perl Makefile.PL - make - #$(GCC) $(LD_FLAGS) $(PERL_OBJ) -o $@ - -$(PERL_OBJ): $(PERL_SHADOW) - $(GCC) $(CC_FLAGS) $(PERL_CC_FLAGS) -I$(PERL_INC) -o $@ $< - -$(PERL_SHADOW): $(SWIG_INTERFACE) - swig -perl -shadow -o $(PERL_SHADOW) -outdir . $< - -# ================================================================== -install: $(PERL_MOD) - make install - -# ================================================================== -uninstall: - -# ================================================================== -clean: - rm $(PERL_MOD) $(PERL_OBJ) - rm $(PERL_SHADOW) - rm -rf Makefile blib pm_to_blib - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile.PL b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile.PL deleted file mode 100644 index 6e625df18..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/perl/Makefile.PL +++ /dev/null @@ -1,7 +0,0 @@ -use ExtUtils::MakeMaker; - -WriteMakefile( - 'NAME' => 'x86disasm', - 'LIBS' => ['-ldisasm'], - 'OBJECT' => 'x86disasm_wrap.o' -); diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/python/Makefile-swig b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/python/Makefile-swig deleted file mode 100644 index 544681a13..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/python/Makefile-swig +++ /dev/null @@ -1,64 +0,0 @@ -ifndef BASE_NAME -BASE_NAME = x86disasm -endif - -ifndef SWIG -SWIG = swig # apt-get install swig ! -endif - -ifndef GCC -GCC = gcc -endif - -ifndef CC_FLAGS -CC_FLAGS = -c -fPIC -endif - -ifndef LD_FLAGS -LD_FLAGS = -shared -L.. -ldisasm -endif - -INTERFACE_FILE = libdisasm_oop.i - -SWIG_INTERFACE = ../$(INTERFACE_FILE) - -# PYTHON rules -PYTHON_MOD = $(BASE_NAME)-python.so -PYTHON_SHADOW = $(BASE_NAME)_wrap.c -PYTHON_SWIG = $(BASE_NAME).py -PYTHON_OBJ = $(BASE_NAME)_wrap.o -PYTHON_INC = `/bin/echo -e 'import sys\nprint sys.prefix + "/include/python" + sys.version[:3]' | python` -PYTHON_LIB = `/bin/echo -e 'import sys\nprint sys.prefix + "/lib/python" + sys.version[:3]' | python` -PYTHON_DEST = $(PYTHON_LIB)/lib-dynload/_$(BASE_NAME).so - -#==================================================== -# TARGETS - -all: swig-python - -dummy: swig-python install uninstall clean - -swig-python: $(PYTHON_MOD) - -$(PYTHON_MOD): $(PYTHON_OBJ) - $(GCC) $(LD_FLAGS) $(PYTHON_OBJ) -o $@ - -$(PYTHON_OBJ): $(PYTHON_SHADOW) - $(GCC) $(CC_FLAGS) -I$(PYTHON_INC) -I.. -o $@ $< - -$(PYTHON_SHADOW): $(SWIG_INTERFACE) - swig -python -shadow -o $(PYTHON_SHADOW) -outdir . $< - -# ================================================================== -install: $(PYTHON_MOD) - sudo cp $(PYTHON_MOD) $(PYTHON_DEST) - sudo cp $(PYTHON_SWIG) $(PYTHON_LIB) - -# ================================================================== -uninstall: - -# ================================================================== -clean: - rm $(PYTHON_MOD) $(PYTHON_SWIG) $(PYTHON_OBJ) - rm $(PYTHON_SHADOW) - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/Makefile-swig b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/Makefile-swig deleted file mode 100644 index ee4800232..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/Makefile-swig +++ /dev/null @@ -1,68 +0,0 @@ -ifndef BASE_NAME -BASE_NAME = x86disasm -endif - -ifndef SWIG -SWIG = swig # apt-get install swig ! -endif - -ifndef GCC -GCC = gcc -endif - -ifndef CC_FLAGS -CC_FLAGS = -c -fPIC -endif - -ifndef LD_FLAGS -LD_FLAGS = -shared -L../.. -ldisasm -endif - -LIBDISASM_DIR = ../.. - -INTERFACE_FILE = libdisasm_oop.i - -SWIG_INTERFACE = ../$(INTERFACE_FILE) - -# RUBY rules -RUBY_MAKEFILE = Makefile -RUBY_MOD = $(BASE_NAME).so -RUBY_SHADOW = $(BASE_NAME)_wrap.c -#RUBY_SWIG = $(BASE_NAME).rb -RUBY_OBJ = $(BASE_NAME)_wrap.o -RUBY_INC = `ruby -e 'puts $$:.join("\n")' | tail -2 | head -1` -#RUBY_LIB = -#RUBY_DEST = - -#==================================================== -# TARGETS - -all: swig-ruby - -dummy: swig-ruby install uninstall clean - -swig-ruby: $(RUBY_MOD) - -$(RUBY_MOD): $(RUBY_MAKEFILE) - make - -$(RUBY_MAKEFILE): $(RUBY_OBJ) - ruby extconf.rb - -$(RUBY_OBJ):$(RUBY_SHADOW) - $(GCC) $(CC_FLAGS) -I$(RUBY_INC) -I.. -o $@ $< - -$(RUBY_SHADOW): $(SWIG_INTERFACE) - swig -ruby -o $(RUBY_SHADOW) -outdir . $< - -# ================================================================== -install: $(RUBY_MOD) - make install - -# ================================================================== -uninstall: - -# ================================================================== -clean: - make clean || true - rm $(RUBY_SHADOW) $(RUBY_MAKEFILE) $(RUBY_MOD) $(RUBY_OBJ) diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/extconf.rb b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/extconf.rb deleted file mode 100644 index 4e7432643..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/ruby/extconf.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'mkmf' -find_library('disasm', 'x86_init', "/usr/local/lib", "../..") -create_makefile('x86disasm') - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/tcl/Makefile-swig b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/tcl/Makefile-swig deleted file mode 100644 index 5145a8293..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/swig/tcl/Makefile-swig +++ /dev/null @@ -1,63 +0,0 @@ -ifndef BASE_NAME -BASE_NAME = x86disasm -endif - -ifndef SWIG -SWIG = swig # apt-get install swig ! -endif - -ifndef GCC -GCC = gcc -endif - -ifndef CC_FLAGS -CC_FLAGS = -c -fPIC -endif - -ifndef LD_FLAGS -LD_FLAGS = -shared -L../.. -ldisasm -endif - -INTERFACE_FILE = libdisasm.i - -SWIG_INTERFACE = ../$(INTERFACE_FILE) - -# TCL rules -TCL_VERSION = 8.3 -TCL_MOD = $(BASE_NAME)-tcl.so -TCL_SHADOW = $(BASE_NAME)_wrap.c -TCL_OBJ = $(BASE_NAME)_wrap.o -TCL_INC = /usr/include/tcl$(TCL_VERSION) -TCL_LIB = /usr/lib/tcl$(TCL_VERSION) -TCL_DEST = $(TCL_LIB)/$(BASE_NAME).so - -#==================================================== -# TARGETS - -all: swig-tcl - -dummy: swig-tcl install uninstall clean - -swig-tcl: $(TCL_MOD) - -$(TCL_MOD): $(TCL_OBJ) - $(GCC) $(LD_FLAGS) $(TCL_OBJ) -o $@ - -$(TCL_OBJ): $(TCL_SHADOW) - $(GCC) $(CC_FLAGS) -I$(TCL_INC) -I.. -o $@ $< - -$(TCL_SHADOW): $(SWIG_INTERFACE) - swig -tcl -o $(TCL_SHADOW) -outdir . $< - -# ================================================================== -install: $(TCL_MOD) - sudo cp $(TCL_MOD) $(TCL_DEST) - -# ================================================================== -uninstall: - -# ================================================================== -clean: - rm $(TCL_MOD) $(TCL_SWIG) $(TCL_OBJ) - rm $(TCL_SHADOW) - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_disasm.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_disasm.c deleted file mode 100644 index 1b82f4e66..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_disasm.c +++ /dev/null @@ -1,210 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_invariant.h" -#include "x86_operand_list.h" - - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - -unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - x86_insn_t *insn ){ - int len, size; - unsigned char bytes[MAX_INSTRUCTION_SIZE]; - - if ( ! buf || ! insn || ! buf_len ) { - /* caller screwed up somehow */ - return 0; - } - - - /* ensure we are all NULLed up */ - memset( insn, 0, sizeof(x86_insn_t) ); - insn->addr = buf_rva + offset; - insn->offset = offset; - /* default to invalid insn */ - insn->type = insn_invalid; - insn->group = insn_none; - - if ( offset >= buf_len ) { - /* another caller screwup ;) */ - x86_report_error(report_disasm_bounds, (void*)(long)(buf_rva+offset)); - return 0; - } - - len = buf_len - offset; - - /* copy enough bytes for disassembly into buffer : this - * helps prevent buffer overruns at the end of a file */ - memset( bytes, 0, MAX_INSTRUCTION_SIZE ); - memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len : - MAX_INSTRUCTION_SIZE ); - - /* actually do the disassembly */ - /* TODO: allow switching when more disassemblers are added */ - size = ia32_disasm_addr( bytes, len, insn); - - /* check and see if we had an invalid instruction */ - if (! size ) { - x86_report_error(report_invalid_insn, (void*)(long)(buf_rva+offset)); - return 0; - } - - /* check if we overran the end of the buffer */ - if ( size > len ) { - x86_report_error( report_insn_bounds, (void*)(long)(buf_rva + offset)); - MAKE_INVALID( insn, bytes ); - return 0; - } - - /* fill bytes field of insn */ - memcpy( insn->bytes, bytes, size ); - - return size; -} - -unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva, - unsigned int offset, unsigned int len, - DISASM_CALLBACK func, void *arg ) { - x86_insn_t insn; - unsigned int buf_len, size, count = 0, bytes = 0; - - /* buf_len is implied by the arguments */ - buf_len = len + offset; - - while ( bytes < len ) { - size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, - &insn ); - if ( size ) { - /* invoke callback if it exists */ - if ( func ) { - (*func)( &insn, arg ); - } - bytes += size; - count ++; - } else { - /* error */ - bytes++; /* try next byte */ - } - - x86_oplist_free( &insn ); - } - - return( count ); -} - -static inline int follow_insn_dest( x86_insn_t *insn ) { - if ( insn->type == insn_jmp || insn->type == insn_jcc || - insn->type == insn_call || insn->type == insn_callcc ) { - return(1); - } - return(0); -} - -static inline int insn_doesnt_return( x86_insn_t *insn ) { - return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 ); -} - -static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){ - int32_t next_addr = -1; - if ( x86_optype_is_address(op->type) ) { - next_addr = op->data.sdword; - } else if ( op->type == op_relative_near ) { - next_addr = insn->addr + insn->size + op->data.relative_near; - } else if ( op->type == op_relative_far ) { - next_addr = insn->addr + insn->size + op->data.relative_far; - } - return( next_addr ); -} - -unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - DISASM_CALLBACK func, void *arg, - DISASM_RESOLVER resolver, void *r_arg ){ - x86_insn_t insn; - x86_op_t *op; - int32_t next_addr; - uint32_t next_offset; - unsigned int size, count = 0, bytes = 0, cont = 1; - - while ( cont && bytes < buf_len ) { - size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, - &insn ); - - if ( size ) { - /* invoke callback if it exists */ - if ( func ) { - (*func)( &insn, arg ); - } - bytes += size; - count ++; - } else { - /* error */ - bytes++; /* try next byte */ - } - - if ( follow_insn_dest(&insn) ) { - op = x86_get_dest_operand( &insn ); - next_addr = -1; - - /* if caller supplied a resolver, use it to determine - * the address to disassemble */ - if ( resolver ) { - next_addr = resolver(op, &insn, r_arg); - } else { - next_addr = internal_resolver(op, &insn); - } - - if (next_addr != -1 ) { - next_offset = next_addr - buf_rva; - /* if offset is in this buffer... */ - if ( (uint32_t)next_addr >= buf_rva && - next_offset < buf_len ) { - /* go ahead and disassemble */ - count += x86_disasm_forward( buf, - buf_len, - buf_rva, - next_offset, - func, arg, - resolver, r_arg ); - } else { - /* report unresolved address */ - x86_report_error( report_disasm_bounds, - (void*)(long)next_addr ); - } - } - } /* end follow_insn */ - - if ( insn_doesnt_return(&insn) ) { - /* stop disassembling */ - cont = 0; - } - - x86_oplist_free( &insn ); - } - return( count ); -} - -/* invariant instruction representation */ -size_t x86_invariant_disasm( unsigned char *buf, int buf_len, - x86_invariant_t *inv ){ - if (! buf || ! buf_len || ! inv ) { - return(0); - } - - return ia32_disasm_invariant(buf, buf_len, inv); -} -size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) { - if (! buf || ! buf_len ) { - return(0); - } - - return ia32_disasm_size(buf, buf_len); -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_format.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_format.c deleted file mode 100644 index 0ec960dc8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_format.c +++ /dev/null @@ -1,1430 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - - -/* - * concatenation macros. STRNCATF concatenates a format string, buf - * only with one argument. - */ -#define STRNCAT( buf, str, len ) do { \ - int _i = strlen(str), _blen = strlen(buf), _len = len - 1; \ - if ( len ) { \ - strncat( buf, str, _len ); \ - if ( _len <= _i ) { \ - buf[_blen+_len] = '\0'; \ - len = 0; \ - } else { \ - len -= _i; \ - } \ - } \ -} while( 0 ) - -#define STRNCATF( buf, fmt, data, len ) do { \ - char _tmp[MAX_OP_STRING]; \ - \ - snprintf( _tmp, sizeof _tmp, fmt, data ); \ - STRNCAT( buf, _tmp, len ); \ -} while( 0 ) - - -#define PRINT_DISPLACEMENT( ea ) do { \ - if ( ea->disp_size && ea->disp ) { \ - if ( ea->disp_sign ) { \ - STRNCATF( buf, "-0x%" PRIX32, -ea->disp, len ); \ - } else { \ - STRNCATF( buf, "0x%" PRIX32, ea->disp, len ); \ - } \ - } \ -} while( 0 ) - -static const char *prefix_strings[] = { - "", /* no prefix */ - "repz ", /* the trailing spaces make it easy to prepend to mnemonic */ - "repnz ", - "lock ", - "branch delay " /* unused in x86 */ -}; - -static int format_insn_prefix_str( enum x86_insn_prefix prefix, char *buf, - int len ) { - - int len_orig = len; - - /* concat all prefix strings */ - if ( prefix & 1 ) { STRNCAT( buf, prefix_strings[1], len ); } - if ( prefix & 2 ) { STRNCAT( buf, prefix_strings[2], len ); } - if ( prefix & 4 ) { STRNCAT( buf, prefix_strings[3], len ); } - if ( prefix & 8 ) { STRNCAT( buf, prefix_strings[4], len ); } - - /* return the number of characters added */ - return (len_orig - len); -} - -/* - * sprint's an operand's data to string str. - */ -static void get_operand_data_str( x86_op_t *op, char *str, int len ){ - - if ( op->flags & op_signed ) { - switch ( op->datatype ) { - case op_byte: - snprintf( str, len, "%" PRId8, op->data.sbyte ); - return; - case op_word: - snprintf( str, len, "%" PRId16, op->data.sword ); - return; - case op_qword: - snprintf( str, len, "%" PRId64, op->data.sqword ); - return; - default: - snprintf( str, len, "%" PRId32, op->data.sdword ); - return; - } - } - - //else - switch ( op->datatype ) { - case op_byte: - snprintf( str, len, "0x%02" PRIX8, op->data.byte ); - return; - case op_word: - snprintf( str, len, "0x%04" PRIX16, op->data.word ); - return; - case op_qword: - snprintf( str, len, "0x%08" PRIX64,op->data.sqword ); - return; - default: - snprintf( str, len, "0x%08" PRIX32, op->data.dword ); - return; - } -} - -/* - * sprints register types to a string. the register types can be ORed - * together. - */ -static void get_operand_regtype_str( int regtype, char *str, int len ) -{ - static struct { - const char *name; - int value; - } operand_regtypes[] = { - {"reg_gen" , 0x00001}, - {"reg_in" , 0x00002}, - {"reg_out" , 0x00004}, - {"reg_local" , 0x00008}, - {"reg_fpu" , 0x00010}, - {"reg_seg" , 0x00020}, - {"reg_simd" , 0x00040}, - {"reg_sys" , 0x00080}, - {"reg_sp" , 0x00100}, - {"reg_fp" , 0x00200}, - {"reg_pc" , 0x00400}, - {"reg_retaddr", 0x00800}, - {"reg_cond" , 0x01000}, - {"reg_zero" , 0x02000}, - {"reg_ret" , 0x04000}, - {"reg_src" , 0x10000}, - {"reg_dest" , 0x20000}, - {"reg_count" , 0x40000}, - {NULL, 0}, //end - }; - - unsigned int i; - - memset( str, 0, len ); - - //go thru every type in the enum - for ( i = 0; operand_regtypes[i].name; i++ ) { - //skip if type is not set - if(! (regtype & operand_regtypes[i].value) ) - continue; - - //not the first time around - if( str[0] ) { - STRNCAT( str, " ", len ); - } - - STRNCAT(str, operand_regtypes[i].name, len ); - } -} - -static int format_expr( x86_ea_t *ea, char *buf, int len, - enum x86_asm_format format ) { - char str[MAX_OP_STRING]; - - if ( format == att_syntax ) { - if (ea->base.name[0] || ea->index.name[0] || ea->scale) { - PRINT_DISPLACEMENT(ea); - STRNCAT( buf, "(", len ); - - if ( ea->base.name[0]) { - STRNCATF( buf, "%%%s", ea->base.name, len ); - } - if ( ea->index.name[0]) { - STRNCATF( buf, ",%%%s", ea->index.name, len ); - if ( ea->scale > 1 ) { - STRNCATF( buf, ",%d", ea->scale, len ); - } - } - /* handle the syntactic exception */ - if ( ! ea->base.name[0] && - ! ea->index.name[0] ) { - STRNCATF( buf, ",%d", ea->scale, len ); - } - - STRNCAT( buf, ")", len ); - } else - STRNCATF( buf, "0x%" PRIX32, ea->disp, len ); - - } else if ( format == xml_syntax ){ - - if ( ea->base.name[0]) { - STRNCAT (buf, "\t\t\t\n", len); - - get_operand_regtype_str (ea->base.type, str, - sizeof str); - STRNCAT (buf, "\t\t\t\tbase.name, len); - STRNCATF (buf, "type=\"%s\" ", str, len); - STRNCATF (buf, "size=%d/>\n", ea->base.size, len); - - STRNCAT (buf, "\t\t\t\n", len); - } - - if ( ea->index.name[0]) { - STRNCAT (buf, "\t\t\t\n", len); - - get_operand_regtype_str (ea->index.type, str, - sizeof str); - - STRNCAT (buf, "\t\t\t\tindex.name, len); - STRNCATF (buf, "type=\"%s\" ", str, len); - STRNCATF (buf, "size=%d/>\n", ea->index.size, len); - - STRNCAT (buf, "\t\t\t\n", len); - } - - //scale - STRNCAT (buf, "\t\t\t\n", len); - STRNCAT (buf, "\t\t\t\t\n", ea->scale, len); - STRNCAT (buf, "\t\t\t\n", len); - - if ( ea->disp_size ) { - - STRNCAT (buf, "\t\t\t\n", len); - - if ( ea->disp_size > 1 && ! ea->disp_sign ) { - STRNCAT (buf, "\t\t\t\t
\n", ea->disp, - len); - } else { - STRNCAT (buf, "\t\t\t\t\n", ea->disp, len); - } - - STRNCAT (buf, "\t\t\t\n", len); - } - - } else if ( format == raw_syntax ) { - - PRINT_DISPLACEMENT(ea); - STRNCAT( buf, "(", len ); - - STRNCATF( buf, "%s,", ea->base.name, len ); - STRNCATF( buf, "%s,", ea->index.name, len ); - STRNCATF( buf, "%d", ea->scale, len ); - STRNCAT( buf, ")", len ); - - } else { - - STRNCAT( buf, "[", len ); - - if ( ea->base.name[0] ) { - STRNCAT( buf, ea->base.name, len ); - if ( ea->index.name[0] || - (ea->disp_size && ! ea->disp_sign) ) { - STRNCAT( buf, "+", len ); - } - } - if ( ea->index.name[0] ) { - STRNCAT( buf, ea->index.name, len ); - if ( ea->scale > 1 ) - { - STRNCATF( buf, "*%" PRId32, ea->scale, len ); - } - if ( ea->disp_size && ! ea->disp_sign ) - { - STRNCAT( buf, "+", len ); - } - } - - if ( ea->disp_size || (! ea->index.name[0] && - ! ea->base.name[0] ) ) - { - PRINT_DISPLACEMENT(ea); - } - - STRNCAT( buf, "]", len ); - } - - return( strlen(buf) ); -} - -static int format_seg( x86_op_t *op, char *buf, int len, - enum x86_asm_format format ) { - int len_orig = len; - const char *reg = ""; - - if (! op || ! buf || ! len || ! op->flags) { - return(0); - } - if ( op->type != op_offset && op->type != op_expression ){ - return(0); - } - if (! ((int) op->flags & 0xF00) ) { - return(0); - } - - switch (op->flags & 0xF00) { - case op_es_seg: reg = "es"; break; - case op_cs_seg: reg = "cs"; break; - case op_ss_seg: reg = "ss"; break; - case op_ds_seg: reg = "ds"; break; - case op_fs_seg: reg = "fs"; break; - case op_gs_seg: reg = "gs"; break; - default: - break; - } - - if (! reg[0] ) { - return( 0 ); - } - - switch( format ) { - case xml_syntax: - STRNCAT( buf, "\t\t\t\n", reg, len ); - break; - case att_syntax: - STRNCATF( buf, "%%%s:", reg, len ); - break; - - default: - STRNCATF( buf, "%s:", reg, len ); - break; - } - - return( len_orig - len ); /* return length of appended string */ -} - -static const char *get_operand_datatype_str( x86_op_t *op ){ - - static const char *types[] = { - "sbyte", /* 0 */ - "sword", - "sqword", - "sdword", - "sdqword", /* 4 */ - "byte", - "word", - "qword", - "dword", /* 8 */ - "dqword", - "sreal", - "dreal", - "extreal", /* 12 */ - "bcd", - "ssimd", - "dsimd", - "sssimd", /* 16 */ - "sdsimd", - "descr32", - "descr16", - "pdescr32", /* 20 */ - "pdescr16", - "bounds16", - "bounds32", - "fpu_env16", - "fpu_env32", /* 25 */ - "fpu_state16", - "fpu_state32", - "fp_reg_set" - }; - - /* handle signed values first */ - if ( op->flags & op_signed ) { - switch (op->datatype) { - case op_byte: return types[0]; - case op_word: return types[1]; - case op_qword: return types[2]; - case op_dqword: return types[4]; - default: return types[3]; - } - } - - switch (op->datatype) { - case op_byte: return types[5]; - case op_word: return types[6]; - case op_qword: return types[7]; - case op_dqword: return types[9]; - case op_sreal: return types[10]; - case op_dreal: return types[11]; - case op_extreal: return types[12]; - case op_bcd: return types[13]; - case op_ssimd: return types[14]; - case op_dsimd: return types[15]; - case op_sssimd: return types[16]; - case op_sdsimd: return types[17]; - case op_descr32: return types[18]; - case op_descr16: return types[19]; - case op_pdescr32: return types[20]; - case op_pdescr16: return types[21]; - case op_bounds16: return types[22]; - case op_bounds32: return types[23]; - case op_fpustate16: return types[24]; - case op_fpustate32: return types[25]; - case op_fpuenv16: return types[26]; - case op_fpuenv32: return types[27]; - case op_fpregset: return types[28]; - default: return types[8]; - } -} - -static int format_insn_eflags_str( enum x86_flag_status flags, char *buf, - int len) { - - static struct { - const char *name; - int value; - } insn_flags[] = { - { "carry_set ", 0x0001 }, - { "zero_set ", 0x0002 }, - { "oflow_set ", 0x0004 }, - { "dir_set ", 0x0008 }, - { "sign_set ", 0x0010 }, - { "parity_set ", 0x0020 }, - { "carry_or_zero_set ", 0x0040 }, - { "zero_set_or_sign_ne_oflow ", 0x0080 }, - { "carry_clear ", 0x0100 }, - { "zero_clear ", 0x0200 }, - { "oflow_clear ", 0x0400 }, - { "dir_clear ", 0x0800 }, - { "sign_clear ", 0x1000 }, - { "parity_clear ", 0x2000 }, - { "sign_eq_oflow ", 0x4000 }, - { "sign_ne_oflow ", 0x8000 }, - { NULL, 0x0000 }, //end - }; - - unsigned int i; - int len_orig = len; - - for (i = 0; insn_flags[i].name; i++) { - if (! (flags & insn_flags[i].value) ) - continue; - - STRNCAT( buf, insn_flags[i].name, len ); - } - - return( len_orig - len ); -} - -static const char *get_insn_group_str( enum x86_insn_group gp ) { - - static const char *types[] = { - "", // 0 - "controlflow",// 1 - "arithmetic", // 2 - "logic", // 3 - "stack", // 4 - "comparison", // 5 - "move", // 6 - "string", // 7 - "bit_manip", // 8 - "flag_manip", // 9 - "fpu", // 10 - "", // 11 - "", // 12 - "interrupt", // 13 - "system", // 14 - "other", // 15 - }; - - if ( gp > sizeof (types)/sizeof(types[0]) ) - return ""; - - return types[gp]; -} - -static const char *get_insn_type_str( enum x86_insn_type type ) { - - static struct { - const char *name; - int value; - } types[] = { - /* insn_controlflow */ - { "jmp", 0x1001 }, - { "jcc", 0x1002 }, - { "call", 0x1003 }, - { "callcc", 0x1004 }, - { "return", 0x1005 }, - { "loop", 0x1006 }, - /* insn_arithmetic */ - { "add", 0x2001 }, - { "sub", 0x2002 }, - { "mul", 0x2003 }, - { "div", 0x2004 }, - { "inc", 0x2005 }, - { "dec", 0x2006 }, - { "shl", 0x2007 }, - { "shr", 0x2008 }, - { "rol", 0x2009 }, - { "ror", 0x200A }, - /* insn_logic */ - { "and", 0x3001 }, - { "or", 0x3002 }, - { "xor", 0x3003 }, - { "not", 0x3004 }, - { "neg", 0x3005 }, - /* insn_stack */ - { "push", 0x4001 }, - { "pop", 0x4002 }, - { "pushregs", 0x4003 }, - { "popregs", 0x4004 }, - { "pushflags", 0x4005 }, - { "popflags", 0x4006 }, - { "enter", 0x4007 }, - { "leave", 0x4008 }, - /* insn_comparison */ - { "test", 0x5001 }, - { "cmp", 0x5002 }, - /* insn_move */ - { "mov", 0x6001 }, /* move */ - { "movcc", 0x6002 }, /* conditional move */ - { "xchg", 0x6003 }, /* exchange */ - { "xchgcc", 0x6004 }, /* conditional exchange */ - /* insn_string */ - { "strcmp", 0x7001 }, - { "strload", 0x7002 }, - { "strmov", 0x7003 }, - { "strstore", 0x7004 }, - { "translate", 0x7005 }, /* xlat */ - /* insn_bit_manip */ - { "bittest", 0x8001 }, - { "bitset", 0x8002 }, - { "bitclear", 0x8003 }, - /* insn_flag_manip */ - { "clear_carry", 0x9001 }, - { "clear_zero", 0x9002 }, - { "clear_oflow", 0x9003 }, - { "clear_dir", 0x9004 }, - { "clear_sign", 0x9005 }, - { "clear_parity", 0x9006 }, - { "set_carry", 0x9007 }, - { "set_zero", 0x9008 }, - { "set_oflow", 0x9009 }, - { "set_dir", 0x900A }, - { "set_sign", 0x900B }, - { "set_parity", 0x900C }, - { "tog_carry", 0x9010 }, - { "tog_zero", 0x9020 }, - { "tog_oflow", 0x9030 }, - { "tog_dir", 0x9040 }, - { "tog_sign", 0x9050 }, - { "tog_parity", 0x9060 }, - /* insn_fpu */ - { "fmov", 0xA001 }, - { "fmovcc", 0xA002 }, - { "fneg", 0xA003 }, - { "fabs", 0xA004 }, - { "fadd", 0xA005 }, - { "fsub", 0xA006 }, - { "fmul", 0xA007 }, - { "fdiv", 0xA008 }, - { "fsqrt", 0xA009 }, - { "fcmp", 0xA00A }, - { "fcos", 0xA00C }, - { "fldpi", 0xA00D }, - { "fldz", 0xA00E }, - { "ftan", 0xA00F }, - { "fsine", 0xA010 }, - { "fsys", 0xA020 }, - /* insn_interrupt */ - { "int", 0xD001 }, - { "intcc", 0xD002 }, /* not present in x86 ISA */ - { "iret", 0xD003 }, - { "bound", 0xD004 }, - { "debug", 0xD005 }, - { "trace", 0xD006 }, - { "invalid_op", 0xD007 }, - { "oflow", 0xD008 }, - /* insn_system */ - { "halt", 0xE001 }, - { "in", 0xE002 }, /* input from port/bus */ - { "out", 0xE003 }, /* output to port/bus */ - { "cpuid", 0xE004 }, - /* insn_other */ - { "nop", 0xF001 }, - { "bcdconv", 0xF002 }, /* convert to or from BCD */ - { "szconv", 0xF003 }, /* change size of operand */ - { NULL, 0 }, //end - }; - - unsigned int i; - - //go thru every type in the enum - for ( i = 0; types[i].name; i++ ) { - if ( types[i].value == type ) - return types[i].name; - } - - return ""; -} - -static const char *get_insn_cpu_str( enum x86_insn_cpu cpu ) { - static const char *intel[] = { - "", // 0 - "8086", // 1 - "80286", // 2 - "80386", // 3 - "80387", // 4 - "80486", // 5 - "Pentium", // 6 - "Pentium Pro", // 7 - "Pentium 2", // 8 - "Pentium 3", // 9 - "Pentium 4" // 10 - }; - - if ( cpu < sizeof(intel)/sizeof(intel[0]) ) { - return intel[cpu]; - } else if ( cpu == 16 ) { - return "K6"; - } else if ( cpu == 32 ) { - return "K7"; - } else if ( cpu == 48 ) { - return "Athlon"; - } - - return ""; -} - -static const char *get_insn_isa_str( enum x86_insn_isa isa ) { - static const char *subset[] = { - NULL, // 0 - "General Purpose", // 1 - "Floating Point", // 2 - "FPU Management", // 3 - "MMX", // 4 - "SSE", // 5 - "SSE2", // 6 - "SSE3", // 7 - "3DNow!", // 8 - "System" // 9 - }; - - if ( isa > sizeof (subset)/sizeof(subset[0]) ) { - return ""; - } - - return subset[isa]; -} - -static int format_operand_att( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING]; - - memset (str, 0, sizeof str); - - switch ( op->type ) { - case op_register: - STRNCATF( buf, "%%%s", op->data.reg.name, len ); - break; - - case op_immediate: - get_operand_data_str( op, str, sizeof str ); - STRNCATF( buf, "$%s", str, len ); - break; - - case op_relative_near: - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - if (op->datatype == op_word) { - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sword + - insn->addr + insn->size), len ); - } else { - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sdword + - insn->addr + insn->size), len ); - } - break; - - case op_absolute: - /* ATT uses the syntax $section, $offset */ - STRNCATF( buf, "$0x%04" PRIX16 ", ", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "$0x%04" PRIX16, - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "$0x%08" PRIX32, - op->data.absolute.offset.off32, len ); - } - break; - case op_offset: - /* ATT requires a '*' before JMP/CALL ops */ - if (insn->type == insn_jmp || insn->type == insn_call) - STRNCAT( buf, "*", len ); - - len -= format_seg( op, buf, len, att_syntax ); - STRNCATF( buf, "0x%08" PRIX32, op->data.sdword, len ); - break; - - case op_expression: - /* ATT requires a '*' before JMP/CALL ops */ - if (insn->type == insn_jmp || insn->type == insn_call) - STRNCAT( buf, "*", len ); - - len -= format_seg( op, buf, len, att_syntax ); - len -= format_expr( &op->data.expression, buf, len, - att_syntax ); - break; - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return ( strlen( buf ) ); -} - -static int format_operand_native( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING]; - - switch (op->type) { - case op_register: - STRNCAT( buf, op->data.reg.name, len ); - break; - - case op_immediate: - get_operand_data_str( op, str, sizeof str ); - STRNCAT( buf, str, len ); - break; - - case op_relative_near: - STRNCATF( buf, "0x%08" PRIX32, - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - if ( op->datatype == op_word ) { - STRNCATF( buf, "0x%08" PRIX32, - (unsigned int)(op->data.sword + - insn->addr + insn->size), len ); - break; - } else { - STRNCATF( buf, "0x%08" PRIX32, op->data.sdword + - insn->addr + insn->size, len ); - } - break; - - case op_absolute: - STRNCATF( buf, "$0x%04" PRIX16 ":", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "0x%04" PRIX16, - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "0x%08" PRIX32, - op->data.absolute.offset.off32, len ); - } - break; - - case op_offset: - len -= format_seg( op, buf, len, native_syntax ); - STRNCATF( buf, "[0x%08" PRIX32 "]", op->data.sdword, len ); - break; - - case op_expression: - len -= format_seg( op, buf, len, native_syntax ); - len -= format_expr( &op->data.expression, buf, len, - native_syntax ); - break; - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING] = "\0"; - - switch (op->type) { - case op_register: - - get_operand_regtype_str( op->data.reg.type, str, - sizeof str ); - - STRNCAT( buf, "\t\tdata.reg.name, len ); - STRNCATF( buf, "type=\"%s\" ", str, len ); - STRNCATF( buf, "size=%d/>\n", op->data.reg.size, len ); - break; - - case op_immediate: - - get_operand_data_str( op, str, sizeof str ); - - STRNCAT( buf, "\t\t\n", str, len ); - break; - - case op_relative_near: - STRNCAT( buf, "\t\t\n", - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - STRNCAT( buf, "\t\tdatatype == op_word) { - STRNCATF( buf, "value=\"0x%08" PRIX32 "\"/>\n", - (unsigned int)(op->data.sword + - insn->addr + insn->size), len); - break; - } else { - - STRNCATF( buf, "value=\"0x%08" PRIX32 "\"/>\n", - op->data.sdword + insn->addr + insn->size, - len ); - } - break; - - case op_absolute: - - STRNCATF( buf, - "\t\tdata.absolute.segment, len ); - - if (op->datatype == op_descr16) { - STRNCATF( buf, "offset=\"0x%04" PRIX16 "\">", - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "offset=\"0x%08" PRIX32 "\">", - op->data.absolute.offset.off32, len ); - } - - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_expression: - - - STRNCAT( buf, "\t\t\n", len ); - - len -= format_seg( op, buf, len, xml_syntax ); - len -= format_expr( &op->data.expression, buf, len, - xml_syntax ); - - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_offset: - - STRNCAT( buf, "\t\t\n", len ); - - len -= format_seg( op, buf, len, xml_syntax ); - - STRNCAT( buf, "\t\t\t
\n", - op->data.sdword, len ); - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_RAW_STRING]; - const char *datatype = get_operand_datatype_str(op); - - switch (op->type) { - case op_register: - - get_operand_regtype_str( op->data.reg.type, str, - sizeof str ); - - STRNCAT( buf, "reg|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%s:", op->data.reg.name, len ); - STRNCATF( buf, "%s:", str, len ); - STRNCATF( buf, "%d|", op->data.reg.size, len ); - break; - - case op_immediate: - - get_operand_data_str( op, str, sizeof str ); - - STRNCAT( buf, "immediate|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%s|", str, len ); - break; - - case op_relative_near: - /* NOTE: in raw format, we print the - * relative offset, not the actual - * address of the jump target */ - - STRNCAT( buf, "relative|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%" PRId8 "|", op->data.sbyte, len ); - break; - - case op_relative_far: - - STRNCAT( buf, "relative|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - if (op->datatype == op_word) { - STRNCATF( buf, "%" PRId16 "|", op->data.sword, len); - break; - } else { - STRNCATF( buf, "%" PRId32 "|", op->data.sdword, len ); - } - break; - - case op_absolute: - - STRNCAT( buf, "absolute_address|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - STRNCATF( buf, "$0x%04" PRIX16 ":", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "0x%04" PRIX16 "|", - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "0x%08" PRIX32 "|", - op->data.absolute.offset.off32, len ); - } - - break; - - case op_expression: - - STRNCAT( buf, "address_expression|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - len -= format_seg( op, buf, len, native_syntax ); - len -= format_expr( &op->data.expression, buf, len, - raw_syntax ); - - STRNCAT( buf, "|", len ); - break; - - case op_offset: - - STRNCAT( buf, "segment_offset|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - len -= format_seg( op, buf, len, xml_syntax ); - - STRNCATF( buf, "%08" PRIX32 "|", op->data.sdword, len ); - break; - - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -int x86_format_operand( x86_op_t *op, char *buf, int len, - enum x86_asm_format format ){ - x86_insn_t *insn; - - if ( ! op || ! buf || len < 1 ) { - return(0); - } - - /* insn is stored in x86_op_t since .21-pre3 */ - insn = (x86_insn_t *) op->insn; - - memset( buf, 0, len ); - - switch ( format ) { - case att_syntax: - return format_operand_att( op, insn, buf, len ); - case xml_syntax: - return format_operand_xml( op, insn, buf, len ); - case raw_syntax: - return format_operand_raw( op, insn, buf, len ); - case native_syntax: - case intel_syntax: - default: - return format_operand_native( op, insn, buf, len ); - } -} - -#define is_imm_jmp(op) (op->type == op_absolute || \ - op->type == op_immediate || \ - op->type == op_offset) -#define is_memory_op(op) (op->type == op_absolute || \ - op->type == op_expression || \ - op->type == op_offset) - -static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) { - int size = 0; - const char *suffix; - - if (! insn || ! buf || ! len ) - return(0); - - memset( buf, 0, len ); - - /* do long jump/call prefix */ - if ( insn->type == insn_jmp || insn->type == insn_call ) { - if (! is_imm_jmp( x86_operand_1st(insn) ) || - (x86_operand_1st(insn))->datatype != op_byte ) { - /* far jump/call, use "l" prefix */ - STRNCAT( buf, "l", len ); - } - STRNCAT( buf, insn->mnemonic, len ); - - return ( strlen( buf ) ); - } - - /* do mnemonic */ - STRNCAT( buf, insn->mnemonic, len ); - - /* do suffixes for memory operands */ - if (!(insn->note & insn_note_nosuffix) && - (insn->group == insn_arithmetic || - insn->group == insn_logic || - insn->group == insn_move || - insn->group == insn_stack || - insn->group == insn_string || - insn->group == insn_comparison || - insn->type == insn_in || - insn->type == insn_out - )) { - if ( x86_operand_count( insn, op_explicit ) > 0 && - is_memory_op( x86_operand_1st(insn) ) ){ - size = x86_operand_size( x86_operand_1st( insn ) ); - } else if ( x86_operand_count( insn, op_explicit ) > 1 && - is_memory_op( x86_operand_2nd(insn) ) ){ - size = x86_operand_size( x86_operand_2nd( insn ) ); - } - } - - if ( size == 1 ) suffix = "b"; - else if ( size == 2 ) suffix = "w"; - else if ( size == 4 ) suffix = "l"; - else if ( size == 8 ) suffix = "q"; - else suffix = ""; - - STRNCAT( buf, suffix, len ); - return ( strlen( buf ) ); -} - -int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format){ - char str[MAX_OP_STRING]; - - memset( buf, 0, len ); - STRNCAT( buf, insn->prefix_string, len ); - if ( format == att_syntax ) { - format_att_mnemonic( insn, str, sizeof str ); - STRNCAT( buf, str, len ); - } else { - STRNCAT( buf, insn->mnemonic, len ); - } - - return( strlen( buf ) ); -} - -struct op_string { char *buf; size_t len; }; - -static void format_op_raw( x86_op_t *op, x86_insn_t *insn, void *arg ) { - struct op_string * opstr = (struct op_string *) arg; - - format_operand_raw(op, insn, opstr->buf, opstr->len); -} - -static int format_insn_note(x86_insn_t *insn, char *buf, int len){ - char note[32] = {0}; - int len_orig = len, note_len = 32; - - if ( insn->note & insn_note_ring0 ) { - STRNCATF( note, "%s", "Ring0 ", note_len ); - } - if ( insn->note & insn_note_smm ) { - STRNCATF( note, "%s", "SMM ", note_len ); - } - if ( insn->note & insn_note_serial ) { - STRNCATF(note, "%s", "Serialize ", note_len ); - } - STRNCATF( buf, "%s|", note, len ); - - return( len_orig - len ); -} - -static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){ - struct op_string opstr = { buf, len }; - int i; - - /* RAW style: - * ADDRESS|OFFSET|SIZE|BYTES| - * PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES| - * MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED| - * STACK_MOD|STACK_MOD_VAL - * [|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]* - * - * Register values are encoded as: - * NAME:TYPE:SIZE - * - * Effective addresses are encoded as: - * disp(base_reg,index_reg,scale) - */ - STRNCATF( buf, "0x%08" PRIX32 "|", insn->addr , len ); - STRNCATF( buf, "0x%08" PRIX32 "|", insn->offset, len ); - STRNCATF( buf, "%d|" , insn->size , len ); - - /* print bytes */ - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - STRNCAT( buf, "|", len ); - - len -= format_insn_prefix_str( insn->prefix, buf, len ); - STRNCATF( buf, "|%s|", insn->prefix_string , len ); - STRNCATF( buf, "%s|", get_insn_group_str( insn->group ), len ); - STRNCATF( buf, "%s|", get_insn_type_str( insn->type ) , len ); - STRNCATF( buf, "%s|", insn->mnemonic , len ); - STRNCATF( buf, "%s|", get_insn_cpu_str( insn->cpu ) , len ); - STRNCATF( buf, "%s|", get_insn_isa_str( insn->isa ) , len ); - - /* insn note */ - len -= format_insn_note( insn, buf, len ); - - len -= format_insn_eflags_str( insn->flags_set, buf, len ); - STRNCAT( buf, "|", len ); - len -= format_insn_eflags_str( insn->flags_tested, buf, len ); - STRNCAT( buf, "|", len ); - STRNCATF( buf, "%d|", insn->stack_mod, len ); - STRNCATF( buf, "%" PRId32 "|", insn->stack_mod_val, len ); - - opstr.len = len; - x86_operand_foreach( insn, format_op_raw, &opstr, op_any ); - - return( strlen (buf) ); -} - -static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) { - char str[MAX_OP_XML_STRING]; - int i; - - STRNCAT( buf, "\n", len ); - - STRNCATF( buf, "\t
addr, len ); - STRNCATF( buf, "offset=\"0x%08" PRIX32 "\" ", insn->offset, len ); - STRNCATF( buf, "size=%d bytes=\"", insn->size, len ); - - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - STRNCAT( buf, "\"/>\n", len ); - - STRNCAT( buf, "\tprefix, buf, len ); - STRNCATF( buf, "\" string=\"%s\"/>\n", insn->prefix_string, len ); - - STRNCATF( buf, "\tgroup), len ); - STRNCATF( buf, "type=\"%s\" ", get_insn_type_str (insn->type), len ); - STRNCATF( buf, "string=\"%s\"/>\n", insn->mnemonic, len ); - - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, "\t\tflags_set, buf, len ); - STRNCAT( buf, "\"/>\n\t\n", len ); - - - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, "\t\tflags_tested, buf, len ); - STRNCAT( buf, "\"/>\n\t\n", len ); - - if ( x86_operand_1st( insn ) ) { - x86_format_operand( x86_operand_1st(insn), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - if ( x86_operand_2nd( insn ) ) { - x86_format_operand( x86_operand_2nd( insn ), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - if ( x86_operand_3rd( insn ) ) { - x86_format_operand( x86_operand_3rd(insn), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - STRNCAT( buf, "\n", len ); - - return strlen (buf); -} - -int x86_format_header( char *buf, int len, enum x86_asm_format format ) { - switch (format) { - case att_syntax: - snprintf( buf, len, "MNEMONIC\tSRC, DEST, IMM" ); - break; - case intel_syntax: - snprintf( buf, len, "MNEMONIC\tDEST, SRC, IMM" ); - break; - case native_syntax: - snprintf( buf, len, "ADDRESS\tBYTES\tMNEMONIC\t" - "DEST\tSRC\tIMM" ); - break; - case raw_syntax: - snprintf( buf, len, "ADDRESS|OFFSET|SIZE|BYTES|" - "PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES|" - "MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED|" - "STACK_MOD|STACK_MOD_VAL" - "[|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]*" - ); - break; - case xml_syntax: - snprintf( buf, len, - "" - "
" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
" - "" - "" - "" - "
" - "" - "" - "" - ); - break; - case unknown_syntax: - if ( len ) { - buf[0] = '\0'; - } - break; - } - - return( strlen(buf) ); -} - -int x86_format_insn( x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format ){ - char str[MAX_OP_STRING]; - x86_op_t *src, *dst; - int i; - - memset(buf, 0, len); - if ( format == intel_syntax ) { - /* INTEL STYLE: mnemonic dest, src, imm */ - STRNCAT( buf, insn->prefix_string, len ); - STRNCAT( buf, insn->mnemonic, len ); - STRNCAT( buf, "\t", len ); - - /* dest */ - if ( (dst = x86_operand_1st( insn )) && !(dst->flags & op_implied) ) { - x86_format_operand( dst, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - /* src */ - if ( (src = x86_operand_2nd( insn )) ) { - if ( !(dst->flags & op_implied) ) { - STRNCAT( buf, ", ", len ); - } - x86_format_operand( src, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - /* imm */ - if ( x86_operand_3rd( insn )) { - STRNCAT( buf, ", ", len ); - x86_format_operand( x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - } else if ( format == att_syntax ) { - /* ATT STYLE: mnemonic src, dest, imm */ - STRNCAT( buf, insn->prefix_string, len ); - format_att_mnemonic(insn, str, MAX_OP_STRING); - STRNCATF( buf, "%s\t", str, len); - - - /* not sure which is correct? sometimes GNU as requires - * an imm as the first operand, sometimes as the third... */ - /* imm */ - if ( x86_operand_3rd( insn ) ) { - x86_format_operand(x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - /* there is always 'dest' operand if there is 'src' */ - STRNCAT( buf, ", ", len ); - } - - if ( (insn->note & insn_note_nonswap ) == 0 ) { - /* regular AT&T style swap */ - src = x86_operand_2nd( insn ); - dst = x86_operand_1st( insn ); - } - else { - /* special-case instructions */ - src = x86_operand_1st( insn ); - dst = x86_operand_2nd( insn ); - } - - /* src */ - if ( src ) { - x86_format_operand(src, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - /* there is always 'dest' operand if there is 'src' */ - if ( dst && !(dst->flags & op_implied) ) { - STRNCAT( buf, ", ", len ); - } - } - - /* dest */ - if ( dst && !(dst->flags & op_implied) ) { - x86_format_operand( dst, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - - } else if ( format == raw_syntax ) { - format_raw_insn( insn, buf, len ); - } else if ( format == xml_syntax ) { - format_xml_insn( insn, buf, len ); - } else { /* default to native */ - /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */ - /* print address */ - STRNCATF( buf, "%08" PRIX32 "\t", insn->addr, len ); - - /* print bytes */ - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - - STRNCAT( buf, "\t", len ); - - /* print mnemonic */ - STRNCAT( buf, insn->prefix_string, len ); - STRNCAT( buf, insn->mnemonic, len ); - STRNCAT( buf, "\t", len ); - - /* print operands */ - /* dest */ - if ( x86_operand_1st( insn ) ) { - x86_format_operand( x86_operand_1st( insn ), - str, MAX_OP_STRING, format); - STRNCATF( buf, "%s\t", str, len ); - } - - /* src */ - if ( x86_operand_2nd( insn ) ) { - x86_format_operand(x86_operand_2nd( insn ), - str, MAX_OP_STRING, format); - STRNCATF( buf, "%s\t", str, len ); - } - - /* imm */ - if ( x86_operand_3rd( insn )) { - x86_format_operand( x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - } - - return( strlen( buf ) ); -} - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.c deleted file mode 100644 index cd59bfc9a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "qword.h" -#include "x86_imm.h" - -#include - -unsigned int x86_imm_signsized( unsigned char * buf, size_t buf_len, - void *dest, unsigned int size ) { - signed char *cp = (signed char *) dest; - signed short *sp = (signed short *) dest; - int32_t *lp = (int32_t *) dest; - qword_t *qp = (qword_t *) dest; - - if ( size > buf_len ) { - return 0; - } - - /* Copy 'size' bytes from *buf to *op - * return number of bytes copied */ - switch (size) { - case 1: /* BYTE */ - *cp = *((signed char *) buf); - break; - case 2: /* WORD */ - *sp = *((signed short *) buf); - break; - case 6: - case 8: /* QWORD */ - *qp = *((qword_t *) buf); - break; - case 4: /* DWORD */ - default: - *lp = *((int32_t *) buf); - break; - } - return (size); -} - -unsigned int x86_imm_sized( unsigned char * buf, size_t buf_len, void *dest, - unsigned int size ) { - unsigned char *cp = (unsigned char *) dest; - unsigned short *sp = (unsigned short *) dest; - uint32_t *lp = (uint32_t *) dest; - qword_t *qp = (qword_t *) dest; - - if ( size > buf_len ) { - return 0; - } - - /* Copy 'size' bytes from *buf to *op - * return number of bytes copied */ - switch (size) { - case 1: /* BYTE */ - *cp = *((unsigned char *) buf); - break; - case 2: /* WORD */ - *sp = *((unsigned short *) buf); - break; - case 6: - case 8: /* QWORD */ - *qp = *((qword_t *) buf); - break; - case 4: /* DWORD */ - default: - *lp = *((uint32_t *) buf); - break; - } - - return (size); -} - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.h deleted file mode 100644 index fa35ff2de..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_imm.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef x86_IMM_H -#define x86_IMM_H - -#include "./qword.h" -#include - -#ifdef WIN32 -#include -#endif - -/* these are in the global x86 namespace but are not a part of the - * official API */ -unsigned int x86_imm_sized( unsigned char *buf, size_t buf_len, void *dest, - unsigned int size ); - -unsigned int x86_imm_signsized( unsigned char *buf, size_t buf_len, void *dest, - unsigned int size ); -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c deleted file mode 100644 index 5649b89fb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include - -#include "libdis.h" - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - -int x86_insn_is_valid( x86_insn_t *insn ) { - if ( insn && insn->type != insn_invalid && insn->size > 0 ) { - return 1; - } - - return 0; -} - -uint32_t x86_get_address( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return 0; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_offset ) { - return op_lst->op.data.offset; - } else if ( op_lst->op.type == op_absolute ) { - if ( op_lst->op.datatype == op_descr16 ) { - return (uint32_t) - op_lst->op.data.absolute.offset.off16; - } - return op_lst->op.data.absolute.offset.off32; - } - } - - return 0; -} - -int32_t x86_get_rel_offset( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return 0; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_relative_near ) { - return (int32_t) op_lst->op.data.relative_near; - } else if ( op_lst->op.type == op_relative_far ) { - return op_lst->op.data.relative_far; - } - } - - return 0; -} - -x86_op_t * x86_get_branch_target( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return NULL; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.access & op_execute ) { - return &(op_lst->op); - } - } - - return NULL; -} -x86_op_t * x86_get_imm( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return NULL; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_immediate ) { - return &(op_lst->op); - } - } - - return NULL; -} - -#define IS_PROPER_IMM( x ) \ - x->op.type == op_immediate && ! (x->op.flags & op_hardcode) - - -/* if there is an immediate value in the instruction, return a pointer to - * it */ -unsigned char * x86_get_raw_imm( x86_insn_t *insn ) { - int size, offset; - x86_op_t *op = NULL; - - if (! insn || ! insn->operands ) { - return(NULL); - } - - /* a bit inelegant, but oh well... */ - if ( IS_PROPER_IMM( insn->operands ) ) { - op = &insn->operands->op; - } else if ( insn->operands->next ) { - if ( IS_PROPER_IMM( insn->operands->next ) ) { - op = &insn->operands->next->op; - } else if ( insn->operands->next->next && - IS_PROPER_IMM( insn->operands->next->next ) ) { - op = &insn->operands->next->next->op; - } - } - - if (! op ) { - return( NULL ); - } - - /* immediate data is at the end of the insn */ - size = x86_operand_size( op ); - offset = insn->size - size; - return( &insn->bytes[offset] ); -} - - -unsigned int x86_operand_size( x86_op_t *op ) { - switch (op->datatype ) { - case op_byte: return 1; - case op_word: return 2; - case op_dword: return 4; - case op_qword: return 8; - case op_dqword: return 16; - case op_sreal: return 4; - case op_dreal: return 8; - case op_extreal: return 10; - case op_bcd: return 10; - case op_ssimd: return 16; - case op_dsimd: return 16; - case op_sssimd: return 4; - case op_sdsimd: return 8; - case op_descr32: return 6; - case op_descr16: return 4; - case op_pdescr32: return 6; - case op_pdescr16: return 6; - case op_bounds16: return 4; - case op_bounds32: return 8; - case op_fpuenv16: return 14; - case op_fpuenv32: return 28; - case op_fpustate16: return 94; - case op_fpustate32: return 108; - case op_fpregset: return 512; - case op_fpreg: return 10; - case op_none: return 0; - } - return(4); /* default size */ -} - -void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) { - if ( insn ) insn->addr = addr; -} - -void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){ - if ( insn ) insn->offset = offset; -} - -void x86_set_insn_function( x86_insn_t *insn, void * func ){ - if ( insn ) insn->function = func; -} - -void x86_set_insn_block( x86_insn_t *insn, void * block ){ - if ( insn ) insn->block = block; -} - -void x86_tag_insn( x86_insn_t *insn ){ - if ( insn ) insn->tag = 1; -} - -void x86_untag_insn( x86_insn_t *insn ){ - if ( insn ) insn->tag = 0; -} - -int x86_insn_is_tagged( x86_insn_t *insn ){ - return insn->tag; -} - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_misc.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_misc.c deleted file mode 100644 index 3d2dd0ae8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_misc.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_reg.h" /* for ia32_reg wrapper */ -#include "ia32_settings.h" -extern ia32_settings_t ia32_settings; - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - - -/* =========================================================== INIT/TERM */ -static DISASM_REPORTER __x86_reporter_func = NULL; -static void * __x86_reporter_arg = NULL; - -int x86_init( enum x86_options options, DISASM_REPORTER reporter, void * arg ) -{ - ia32_settings.options = options; - __x86_reporter_func = reporter; - __x86_reporter_arg = arg; - - return 1; -} - -void x86_set_reporter( DISASM_REPORTER reporter, void * arg ) { - __x86_reporter_func = reporter; - __x86_reporter_arg = arg; -} - -void x86_set_options( enum x86_options options ){ - ia32_settings.options = options; -} - -enum x86_options x86_get_options( void ) { - return ia32_settings.options; -} - -int x86_cleanup( void ) -{ - return 1; -} - -/* =========================================================== ERRORS */ -void x86_report_error( enum x86_report_codes code, void *data ) { - if ( __x86_reporter_func ) { - (*__x86_reporter_func)(code, data, __x86_reporter_arg); - } -} - - -/* =========================================================== MISC */ -unsigned int x86_endian(void) { return ia32_settings.endian; } -unsigned int x86_addr_size(void) { return ia32_settings.sz_addr; } -unsigned int x86_op_size(void) { return ia32_settings.sz_oper; } -unsigned int x86_word_size(void) { return ia32_settings.sz_word; } -unsigned int x86_max_insn_size(void) { return ia32_settings.max_insn; } -unsigned int x86_sp_reg(void) { return ia32_settings.id_sp_reg; } -unsigned int x86_fp_reg(void) { return ia32_settings.id_fp_reg; } -unsigned int x86_ip_reg(void) { return ia32_settings.id_ip_reg; } -unsigned int x86_flag_reg(void) { return ia32_settings.id_flag_reg; } - -/* wrapper function to hide the IA32 register fn */ -void x86_reg_from_id( unsigned int id, x86_reg_t * reg ) { - ia32_handle_register( reg, id ); - return; -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.c b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.c deleted file mode 100644 index 95409e069..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include "libdis.h" - - -static void x86_oplist_append( x86_insn_t *insn, x86_oplist_t *op ) { - x86_oplist_t *list; - - if (! insn ) { - return; - } - - list = insn->operands; - if (! list ) { - insn->operand_count = 1; - /* Note that we have no way of knowing if this is an - * exlicit operand or not, since the caller fills - * the x86_op_t after we return. We increase the - * explicit count automatically, and ia32_insn_implicit_ops - * decrements it */ - insn->explicit_count = 1; - insn->operands = op; - return; - } - - /* get to end of list */ - for ( ; list->next; list = list->next ) - ; - - insn->operand_count = insn->operand_count + 1; - insn->explicit_count = insn->explicit_count + 1; - list->next = op; - - return; -} - -x86_op_t * x86_operand_new( x86_insn_t *insn ) { - x86_oplist_t *op; - - if (! insn ) { - return(NULL); - } - op = calloc( sizeof(x86_oplist_t), 1 ); - op->op.insn = insn; - x86_oplist_append( insn, op ); - return( &(op->op) ); -} - -void x86_oplist_free( x86_insn_t *insn ) { - x86_oplist_t *op, *list; - - if (! insn ) { - return; - } - - for ( list = insn->operands; list; ) { - op = list; - list = list->next; - free(op); - } - - insn->operands = NULL; - insn->operand_count = 0; - insn->explicit_count = 0; - - return; -} - -/* ================================================== LIBDISASM API */ -/* these could probably just be #defines, but that means exposing the - enum... yet one more confusing thing in the API */ -int x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg, - enum x86_op_foreach_type type ){ - x86_oplist_t *list; - char explicit = 1, implicit = 1; - - if (! insn || ! func ) { - return 0; - } - - /* note: explicit and implicit can be ORed together to - * allow an "all" limited by access type, even though the - * user is stupid to do this since it is default behavior :) */ - if ( (type & op_explicit) && ! (type & op_implicit) ) { - implicit = 0; - } - if ( (type & op_implicit) && ! (type & op_explicit) ) { - explicit = 0; - } - - type = type & 0x0F; /* mask out explicit/implicit operands */ - - for ( list = insn->operands; list; list = list->next ) { - if (! implicit && (list->op.flags & op_implied) ) { - /* operand is implicit */ - continue; - } - - if (! explicit && ! (list->op.flags & op_implied) ) { - /* operand is not implicit */ - continue; - } - - switch ( type ) { - case op_any: - break; - case op_dest: - if (! (list->op.access & op_write) ) { - continue; - } - break; - case op_src: - if (! (list->op.access & op_read) ) { - continue; - } - break; - case op_ro: - if (! (list->op.access & op_read) || - (list->op.access & op_write ) ) { - continue; - } - break; - case op_wo: - if (! (list->op.access & op_write) || - (list->op.access & op_read ) ) { - continue; - } - break; - case op_xo: - if (! (list->op.access & op_execute) ) { - continue; - } - break; - case op_rw: - if (! (list->op.access & op_write) || - ! (list->op.access & op_read ) ) { - continue; - } - break; - case op_implicit: case op_explicit: /* make gcc happy */ - break; - } - /* any non-continue ends up here: invoke the callback */ - (*func)( &list->op, insn, arg ); - } - - return 1; -} - -static void count_operand( x86_op_t *op, x86_insn_t *insn, void *arg ) { - size_t * count = (size_t *) arg; - *count = *count + 1; -} - -size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type ) { - size_t count = 0; - - /* save us a list traversal for common counts... */ - if ( type == op_any ) { - return insn->operand_count; - } else if ( type == op_explicit ) { - return insn->explicit_count; - } - - x86_operand_foreach( insn, count_operand, &count, type ); - return count; -} - -/* accessor functions */ -x86_op_t * x86_operand_1st( x86_insn_t *insn ) { - if (! insn->explicit_count ) { - return NULL; - } - - return &(insn->operands->op); -} - -x86_op_t * x86_operand_2nd( x86_insn_t *insn ) { - if ( insn->explicit_count < 2 ) { - return NULL; - } - - return &(insn->operands->next->op); -} - -x86_op_t * x86_operand_3rd( x86_insn_t *insn ) { - if ( insn->explicit_count < 3 ) { - return NULL; - } - - return &(insn->operands->next->next->op); -} diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.h b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.h deleted file mode 100644 index 53668658e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_operand_list.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef X86_OPERAND_LIST_H -#define X86_OPERAND_LIST_H -#include "libdis.h" - - -x86_op_t * x86_operand_new( x86_insn_t *insn ); - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags.h b/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags.h deleted file mode 100644 index 08a3b637e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags.h +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Ray Sidney -// Revamped and reorganized by Craig Silverstein -// -// This is the file that should be included by any file which declares -// or defines a command line flag or wants to parse command line flags -// or print a program usage message (which will include information about -// flags). Executive summary, in the form of an example foo.cc file: -// -// #include "foo.h" // foo.h has a line "DECLARE_int32(start);" -// -// DEFINE_int32(end, 1000, "The last record to read"); -// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...) -// -// void MyFunc() { -// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); -// } -// -// Then, at the command-line: -// ./foo --noverbose --start=5 --end=100 -// -// For more details, see -// doc/gflags.html -// -// --- A note about thread-safety: -// -// We describe many functions in this routine as being thread-hostile, -// thread-compatible, or thread-safe. Here are the meanings we use: -// -// thread-safe: it is safe for multiple threads to call this routine -// (or, when referring to a class, methods of this class) -// concurrently. -// thread-hostile: it is not safe for multiple threads to call this -// routine (or methods of this class) concurrently. In gflags, -// most thread-hostile routines are intended to be called early in, -// or even before, main() -- that is, before threads are spawned. -// thread-compatible: it is safe for multiple threads to read from -// this variable (when applied to variables), or to call const -// methods of this class (when applied to classes), as long as no -// other thread is writing to the variable or calling non-const -// methods of this class. - -#ifndef GOOGLE_GFLAGS_H_ -#define GOOGLE_GFLAGS_H_ - -#include -#include - -// We care a lot about number of bits things take up. Unfortunately, -// systems define their bit-specific ints in a lot of different ways. -// We use our own way, and have a typedef to get there. -// Note: these commands below may look like "#if 1" or "#if 0", but -// that's because they were constructed that way at ./configure time. -// Look at gflags.h.in to see how they're calculated (based on your config). -#if 1 -#include // the normal place uint16_t is defined -#endif -#if 1 -#include // the normal place u_int16_t is defined -#endif -#if 1 -#include // a third place for uint16_t or u_int16_t -#endif - -namespace google { - -#if 1 // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif 1 // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif 0 // the windows (vc7) format -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else -#error Do not know how to define a 32-bit integer quantity on your system -#endif - -// -------------------------------------------------------------------- -// To actually define a flag in a file, use DEFINE_bool, -// DEFINE_string, etc. at the bottom of this file. You may also find -// it useful to register a validator with the flag. This ensures that -// when the flag is parsed from the commandline, or is later set via -// SetCommandLineOption, we call the validation function. -// -// The validation function should return true if the flag value is valid, and -// false otherwise. If the function returns false for the new setting of the -// flag, the flag will retain its current value. If it returns false for the -// default value, InitGoogle will die. -// -// This function is safe to call at global construct time (as in the -// example below). -// -// Example use: -// static bool ValidatePort(const char* flagname, int32 value) { -// if (value > 0 && value < 32768) // value is ok -// return true; -// printf("Invalid value for --%s: %d\n", flagname, (int)value); -// return false; -// } -// DEFINE_int32(port, 0, "What port to listen on"); -// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort); - -// Returns true if successfully registered, false if not (because the -// first argument doesn't point to a command-line flag, or because a -// validator is already registered for this flag). -bool RegisterFlagValidator(const bool* flag, - bool (*validate_fn)(const char*, bool)); -bool RegisterFlagValidator(const int32* flag, - bool (*validate_fn)(const char*, int32)); -bool RegisterFlagValidator(const int64* flag, - bool (*validate_fn)(const char*, int64)); -bool RegisterFlagValidator(const uint64* flag, - bool (*validate_fn)(const char*, uint64)); -bool RegisterFlagValidator(const double* flag, - bool (*validate_fn)(const char*, double)); -bool RegisterFlagValidator(const std::string* flag, - bool (*validate_fn)(const char*, const std::string&)); - - -// -------------------------------------------------------------------- -// These methods are the best way to get access to info about the -// list of commandline flags. Note that these routines are pretty slow. -// GetAllFlags: mostly-complete info about the list, sorted by file. -// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does) -// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr -// -// In addition to accessing flags, you can also access argv[0] (the program -// name) and argv (the entire commandline), which we sock away a copy of. -// These variables are static, so you should only set them once. - -struct CommandLineFlagInfo { - std::string name; // the name of the flag - std::string type; // the type of the flag: int32, etc - std::string description; // the "help text" associated with the flag - std::string current_value; // the current value, as a string - std::string default_value; // the default value, as a string - std::string filename; // 'cleaned' version of filename holding the flag - bool has_validator_fn; // true if RegisterFlagValidator called on flag - bool is_default; // true if the flag has default value -}; - -extern void GetAllFlags(std::vector* OUTPUT); -// These two are actually defined in commandlineflags_reporting.cc. -extern void ShowUsageWithFlags(const char *argv0); // what --help does -extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); - -// Create a descriptive string for a flag. -// Goes to some trouble to make pretty line breaks. -extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag); - -// Thread-hostile; meant to be called before any threads are spawned. -extern void SetArgv(int argc, const char** argv); -// The following functions are thread-safe as long as SetArgv() is -// only called before any threads start. -extern const std::vector& GetArgvs(); // all of argv as a vector -extern const char* GetArgv(); // all of argv as a string -extern const char* GetArgv0(); // only argv0 -extern uint32 GetArgvSum(); // simple checksum of argv -extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set -extern const char* ProgramInvocationShortName(); // basename(argv0) -// ProgramUsage() is thread-safe as long as SetUsageMessage() is only -// called before any threads start. -extern const char* ProgramUsage(); // string set by SetUsageMessage() - - -// -------------------------------------------------------------------- -// Normally you access commandline flags by just saying "if (FLAGS_foo)" -// or whatever, and set them by calling "FLAGS_foo = bar" (or, more -// commonly, via the DEFINE_foo macro). But if you need a bit more -// control, we have programmatic ways to get/set the flags as well. -// These programmatic ways to access flags are thread-safe, but direct -// access is only thread-compatible. - -// Return true iff the flagname was found. -// OUTPUT is set to the flag's value, or unchanged if we return false. -extern bool GetCommandLineOption(const char* name, std::string* OUTPUT); - -// Return true iff the flagname was found. OUTPUT is set to the flag's -// CommandLineFlagInfo or unchanged if we return false. -extern bool GetCommandLineFlagInfo(const char* name, - CommandLineFlagInfo* OUTPUT); - -// Return the CommandLineFlagInfo of the flagname. exit() if name not found. -// Example usage, to check if a flag's value is currently the default value: -// if (GetCommandLineFlagInfoOrDie("foo").is_default) ... -extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); - -enum FlagSettingMode { - // update the flag's value (can call this multiple times). - SET_FLAGS_VALUE, - // update the flag's value, but *only if* it has not yet been updated - // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef". - SET_FLAG_IF_DEFAULT, - // set the flag's default value to this. If the flag has not yet updated - // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef") - // change the flag's current value to the new default value as well. - SET_FLAGS_DEFAULT -}; - -// Set a particular flag ("command line option"). Returns a string -// describing the new value that the option has been set to. The -// return value API is not well-specified, so basically just depend on -// it to be empty if the setting failed for some reason -- the name is -// not a valid flag name, or the value is not a valid value -- and -// non-empty else. - -// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) -extern std::string SetCommandLineOption(const char* name, const char* value); -extern std::string SetCommandLineOptionWithMode(const char* name, const char* value, - FlagSettingMode set_mode); - - -// -------------------------------------------------------------------- -// Saves the states (value, default value, whether the user has set -// the flag, registered validators, etc) of all flags, and restores -// them when the FlagSaver is destroyed. This is very useful in -// tests, say, when you want to let your tests change the flags, but -// make sure that they get reverted to the original states when your -// test is complete. -// -// Example usage: -// void TestFoo() { -// FlagSaver s1; -// FLAG_foo = false; -// FLAG_bar = "some value"; -// -// // test happens here. You can return at any time -// // without worrying about restoring the FLAG values. -// } -// -// Note: This class is marked with __attribute__((unused)) because all the -// work is done in the constructor and destructor, so in the standard -// usage example above, the compiler would complain that it's an -// unused variable. -// -// This class is thread-safe. - -class FlagSaver { - public: - FlagSaver(); - ~FlagSaver(); - - private: - class FlagSaverImpl* impl_; // we use pimpl here to keep API steady - - FlagSaver(const FlagSaver&); // no copying! - void operator=(const FlagSaver&); -} __attribute__ ((unused)); - -// -------------------------------------------------------------------- -// Some deprecated or hopefully-soon-to-be-deprecated functions. - -// This is often used for logging. TODO(csilvers): figure out a better way -extern std::string CommandlineFlagsIntoString(); -// Usually where this is used, a FlagSaver should be used instead. -extern bool ReadFlagsFromString(const std::string& flagfilecontents, - const char* prog_name, - bool errors_are_fatal); // uses SET_FLAGS_VALUE - -// These let you manually implement --flagfile functionality. -// DEPRECATED. -extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); -extern bool SaveCommandFlags(); // actually defined in google.cc ! -extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, - bool errors_are_fatal); // uses SET_FLAGS_VALUE - - -// -------------------------------------------------------------------- -// Useful routines for initializing flags from the environment. -// In each case, if 'varname' does not exist in the environment -// return defval. If 'varname' does exist but is not valid -// (e.g., not a number for an int32 flag), abort with an error. -// Otherwise, return the value. NOTE: for booleans, for true use -// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. - -extern bool BoolFromEnv(const char *varname, bool defval); -extern int32 Int32FromEnv(const char *varname, int32 defval); -extern int64 Int64FromEnv(const char *varname, int64 defval); -extern uint64 Uint64FromEnv(const char *varname, uint64 defval); -extern double DoubleFromEnv(const char *varname, double defval); -extern const char *StringFromEnv(const char *varname, const char *defval); - - -// -------------------------------------------------------------------- -// The next two functions parse commandlineflags from main(): - -// Set the "usage" message for this program. For example: -// string usage("This program does nothing. Sample usage:\n"); -// usage += argv[0] + " "; -// SetUsageMessage(usage); -// Do not include commandline flags in the usage: we do that for you! -// Thread-hostile; meant to be called before any threads are spawned. -extern void SetUsageMessage(const std::string& usage); - -// Looks for flags in argv and parses them. Rearranges argv to put -// flags first, or removes them entirely if remove_flags is true. -// If a flag is defined more than once in the command line or flag -// file, the last definition is used. -// See top-of-file for more details on this function. -#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. -extern uint32 ParseCommandLineFlags(int *argc, char*** argv, - bool remove_flags); -#endif - - -// Calls to ParseCommandLineNonHelpFlags and then to -// HandleCommandLineHelpFlags can be used instead of a call to -// ParseCommandLineFlags during initialization, in order to allow for -// changing default values for some FLAGS (via -// e.g. SetCommandLineOptionWithMode calls) between the time of -// command line parsing and the time of dumping help information for -// the flags as a result of command line parsing. -// If a flag is defined more than once in the command line or flag -// file, the last definition is used. -extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, - bool remove_flags); -// This is actually defined in commandlineflags_reporting.cc. -// This function is misnamed (it also handles --version, etc.), but -// it's too late to change that now. :-( -extern void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc - -// Allow command line reparsing. Disables the error normally -// generated when an unknown flag is found, since it may be found in a -// later parse. Thread-hostile; meant to be called before any threads -// are spawned. -extern void AllowCommandLineReparsing(); - -// Reparse the flags that have not yet been recognized. -// Only flags registered since the last parse will be recognized. -// Any flag value must be provided as part of the argument using "=", -// not as a separate command line argument that follows the flag argument. -// Intended for handling flags from dynamically loaded libraries, -// since their flags are not registered until they are loaded. -extern uint32 ReparseCommandLineNonHelpFlags(); - - -// -------------------------------------------------------------------- -// Now come the command line flag declaration/definition macros that -// will actually be used. They're kind of hairy. A major reason -// for this is initialization: we want people to be able to access -// variables in global constructors and have that not crash, even if -// their global constructor runs before the global constructor here. -// (Obviously, we can't guarantee the flags will have the correct -// default value in that case, but at least accessing them is safe.) -// The only way to do that is have flags point to a static buffer. -// So we make one, using a union to ensure proper alignment, and -// then use placement-new to actually set up the flag with the -// correct default value. In the same vein, we have to worry about -// flag access in global destructors, so FlagRegisterer has to be -// careful never to destroy the flag-values it constructs. -// -// Note that when we define a flag variable FLAGS_, we also -// preemptively define a junk variable, FLAGS_no. This is to -// cause a link-time error if someone tries to define 2 flags with -// names like "logging" and "nologging". We do this because a bool -// flag FLAG can be set from the command line to true with a "-FLAG" -// argument, and to false with a "-noFLAG" argument, and so this can -// potentially avert confusion. -// -// We also put flags into their own namespace. It is purposefully -// named in an opaque way that people should have trouble typing -// directly. The idea is that DEFINE puts the flag in the weird -// namespace, and DECLARE imports the flag from there into the current -// namespace. The net result is to force people to use DECLARE to get -// access to a flag, rather than saying "extern bool FLAGS_whatever;" -// or some such instead. We want this so we can put extra -// functionality (like sanity-checking) in DECLARE if we want, and -// make sure it is picked up everywhere. -// -// We also put the type of the variable in the namespace, so that -// people can't DECLARE_int32 something that they DEFINE_bool'd -// elsewhere. - -class FlagRegisterer { - public: - FlagRegisterer(const char* name, const char* type, - const char* help, const char* filename, - void* current_storage, void* defvalue_storage); -}; - -extern bool FlagsTypeWarn(const char *name); - -// If your application #defines STRIP_FLAG_HELP to a non-zero value -// before #including this file, we remove the help message from the -// binary file. This can reduce the size of the resulting binary -// somewhat, and may also be useful for security reasons. - -extern const char kStrippedFlagHelp[]; - -} - -#ifndef SWIG // In swig, ignore the main flag declarations - -#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 -// Need this construct to avoid the 'defined but not used' warning. -#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp) -#else -#define MAYBE_STRIPPED_HELP(txt) txt -#endif - -// Each command-line flag has two variables associated with it: one -// with the current value, and one with the default value. However, -// we have a third variable, which is where value is assigned; it's a -// constant. This guarantees that FLAG_##value is initialized at -// static initialization time (e.g. before program-start) rather than -// than global construction time (which is after program-start but -// before main), at least when 'value' is a compile-time constant. We -// use a small trick for the "default value" variable, and call it -// FLAGS_no. This serves the second purpose of assuring a -// compile error if someone tries to define a flag named no -// which is illegal (--foo and --nofoo both affect the "foo" flag). -#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ - namespace fL##shorttype { \ - static const type FLAGS_nono##name = value; \ - type FLAGS_##name = FLAGS_nono##name; \ - type FLAGS_no##name = FLAGS_nono##name; \ - static ::google::FlagRegisterer o_##name( \ - #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \ - &FLAGS_##name, &FLAGS_no##name); \ - } \ - using fL##shorttype::FLAGS_##name - -#define DECLARE_VARIABLE(type, shorttype, name) \ - namespace fL##shorttype { \ - extern type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// For DEFINE_bool, we want to do the extra check that the passed-in -// value is actually a bool, and not a string or something that can be -// coerced to a bool. These declarations (no definition needed!) will -// help us do that, and never evaluate From, which is important. -// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires -// that the compiler have different sizes for bool & double. Since -// this is not guaranteed by the standard, we check it with a -// compile-time assert (msg[-1] will give a compile-time error). -namespace fLB { -struct CompileAssert {}; -typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ - (sizeof(double) != sizeof(bool)) ? 1 : -1]; -template double IsBoolFlag(const From& from); -bool IsBoolFlag(bool from); -} // namespace fLB - -#define DECLARE_bool(name) DECLARE_VARIABLE(bool,B, name) -#define DEFINE_bool(name,val,txt) \ - namespace fLB { \ - typedef CompileAssert FLAG_##name##_value_is_not_a_bool[ \ - (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \ - } \ - DEFINE_VARIABLE(bool,B, name, val, txt) - -#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32,I, name) -#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32,I, name, val, txt) - -#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64,I64, name) -#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64,I64, name, val, txt) - -#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64,U64, name) -#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64,U64, name, val, txt) - -#define DECLARE_double(name) DECLARE_VARIABLE(double,D, name) -#define DEFINE_double(name,val,txt) DEFINE_VARIABLE(double,D, name, val, txt) - -// Strings are trickier, because they're not a POD, so we can't -// construct them at static-initialization time (instead they get -// constructed at global-constructor time, which is much later). To -// try to avoid crashes in that case, we use a char buffer to store -// the string, which we can static-initialize, and then placement-new -// into it later. It's not perfect, but the best we can do. -#define DECLARE_string(name) namespace fLS { extern std::string& FLAGS_##name; } \ - using fLS::FLAGS_##name - -// We need to define a var named FLAGS_no##name so people don't define -// --string and --nostring. And we need a temporary place to put val -// so we don't have to evaluate it twice. Two great needs that go -// great together! -// The weird 'using' + 'extern' inside the fLS namespace is to work around -// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See -// http://code.google.com/p/google-gflags/issues/detail?id=20 -#define DEFINE_string(name, val, txt) \ - namespace fLS { \ - static union { void* align; char s[sizeof(std::string)]; } s_##name[2]; \ - const std::string* const FLAGS_no##name = new (s_##name[0].s) std::string(val); \ - static ::google::FlagRegisterer o_##name( \ - #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ - s_##name[0].s, new (s_##name[1].s) std::string(*FLAGS_no##name)); \ - extern std::string& FLAGS_##name; \ - using fLS::FLAGS_##name; \ - std::string& FLAGS_##name = *(reinterpret_cast(s_##name[0].s)); \ - } \ - using fLS::FLAGS_##name - -#endif // SWIG - -#endif // GOOGLE_GFLAGS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags_completions.h b/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags_completions.h deleted file mode 100644 index 9d9ce7a5f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags_completions.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// --- -// Author: Dave Nicponski -// -// Implement helpful bash-style command line flag completions -// -// ** Functional API: -// HandleCommandLineCompletions() should be called early during -// program startup, but after command line flag code has been -// initialized, such as the beginning of HandleCommandLineHelpFlags(). -// It checks the value of the flag --tab_completion_word. If this -// flag is empty, nothing happens here. If it contains a string, -// however, then HandleCommandLineCompletions() will hijack the -// process, attempting to identify the intention behind this -// completion. Regardless of the outcome of this deduction, the -// process will be terminated, similar to --helpshort flag -// handling. -// -// ** Overview of Bash completions: -// Bash can be told to programatically determine completions for the -// current 'cursor word'. It does this by (in this case) invoking a -// command with some additional arguments identifying the command -// being executed, the word being completed, and the previous word -// (if any). Bash then expects a sequence of output lines to be -// printed to stdout. If these lines all contain a common prefix -// longer than the cursor word, bash will replace the cursor word -// with that common prefix, and display nothing. If there isn't such -// a common prefix, bash will display the lines in pages using 'more'. -// -// ** Strategy taken for command line completions: -// If we can deduce either the exact flag intended, or a common flag -// prefix, we'll output exactly that. Otherwise, if information -// must be displayed to the user, we'll take the opportunity to add -// some helpful information beyond just the flag name (specifically, -// we'll include the default flag value and as much of the flag's -// description as can fit on a single terminal line width, as specified -// by the flag --tab_completion_columns). Furthermore, we'll try to -// make bash order the output such that the most useful or relevent -// flags are the most likely to be shown at the top. -// -// ** Additional features: -// To assist in finding that one really useful flag, substring matching -// was implemented. Before pressing a to get completion for the -// current word, you can append one or more '?' to the flag to do -// substring matching. Here's the semantics: -// --foo Show me all flags with names prefixed by 'foo' -// --foo? Show me all flags with 'foo' somewhere in the name -// --foo?? Same as prior case, but also search in module -// definition path for 'foo' -// --foo??? Same as prior case, but also search in flag -// descriptions for 'foo' -// Finally, we'll trim the output to a relatively small number of -// flags to keep bash quiet about the verbosity of output. If one -// really wanted to see all possible matches, appending a '+' to the -// search word will force the exhaustive list of matches to be printed. -// -// ** How to have bash accept completions from a binary: -// Bash requires that it be informed about each command that programmatic -// completion should be enabled for. Example addition to a .bashrc -// file would be (your path to gflags_completions.sh file may differ): - -/* -$ complete -o bashdefault -o default -o nospace -C \ - '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ - time env binary_name another_binary [...] -*/ - -// This would allow the following to work: -// $ /path/to/binary_name --vmodule -// Or: -// $ ./bin/path/another_binary --gfs_u -// (etc) -// -// Sadly, it appears that bash gives no easy way to force this behavior for -// all commands. That's where the "time" in the above example comes in. -// If you haven't specifically added a command to the list of completion -// supported commands, you can still get completions by prefixing the -// entire command with "env". -// $ env /some/brand/new/binary --vmod -// Assuming that "binary" is a newly compiled binary, this should still -// produce the expected completion output. - - -#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ -#define GOOGLE_GFLAGS_COMPLETIONS_H_ - -namespace google { - -void HandleCommandLineCompletions(void); - -} - -#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/lss/codereview.settings b/toolkit/crashreporter/google-breakpad/src/third_party/lss/codereview.settings deleted file mode 100644 index b3eb38787..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/lss/codereview.settings +++ /dev/null @@ -1,5 +0,0 @@ -# This file is used by gcl to get repository specific information. -CODE_REVIEW_SERVER: codereview.chromium.org -CC_LIST: chromium-reviews@chromium.org,markus@chromium.org,mseaborn@chromium.org -VIEW_VC: https://chromium.googlesource.com/linux-syscall-support/+/ - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h b/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h deleted file mode 100644 index 06b64e2ee..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h +++ /dev/null @@ -1,4496 +0,0 @@ -/* Copyright (c) 2005-2011, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Markus Gutschke - */ - -/* This file includes Linux-specific support functions common to the - * coredumper and the thread lister; primarily, this is a collection - * of direct system calls, and a couple of symbols missing from - * standard header files. - * There are a few options that the including file can set to control - * the behavior of this file: - * - * SYS_CPLUSPLUS: - * The entire header file will normally be wrapped in 'extern "C" { }", - * making it suitable for compilation as both C and C++ source. If you - * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit - * the wrapping. N.B. doing so will suppress inclusion of all prerequisite - * system header files, too. It is the caller's responsibility to provide - * the necessary definitions. - * - * SYS_ERRNO: - * All system calls will update "errno" unless overriden by setting the - * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be - * an l-value. - * - * SYS_INLINE: - * New symbols will be defined "static inline", unless overridden by - * the SYS_INLINE macro. - * - * SYS_LINUX_SYSCALL_SUPPORT_H - * This macro is used to avoid multiple inclusions of this header file. - * If you need to include this file more than once, make sure to - * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. - * - * SYS_PREFIX: - * New system calls will have a prefix of "sys_" unless overridden by - * the SYS_PREFIX macro. Valid values for this macro are [0..9] which - * results in prefixes "sys[0..9]_". It is also possible to set this - * macro to -1, which avoids all prefixes. - * - * SYS_SYSCALL_ENTRYPOINT: - * Some applications (such as sandboxes that filter system calls), need - * to be able to run custom-code each time a system call is made. If this - * macro is defined, it expands to the name of a "common" symbol. If - * this symbol is assigned a non-NULL pointer value, it is used as the - * address of the system call entrypoint. - * A pointer to this symbol can be obtained by calling - * get_syscall_entrypoint() - * - * This file defines a few internal symbols that all start with "LSS_". - * Do not access these symbols from outside this file. They are not part - * of the supported API. - */ -#ifndef SYS_LINUX_SYSCALL_SUPPORT_H -#define SYS_LINUX_SYSCALL_SUPPORT_H - -/* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x - * on Linux. - * Porting to other related platforms should not be difficult. - */ -#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ - defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \ - defined(__aarch64__) || defined(__s390__)) \ - && (defined(__linux) || defined(__ANDROID__)) - -#ifndef SYS_CPLUSPLUS -#ifdef __cplusplus -/* Some system header files in older versions of gcc neglect to properly - * handle being included from C++. As it appears to be harmless to have - * multiple nested 'extern "C"' blocks, just add another one here. - */ -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __mips__ -/* Include definitions of the ABI currently in use. */ -#ifdef __ANDROID__ -/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h, - * which has the definitions we need. - */ -#include -#else -#include -#endif -#endif -#endif - -/* The Android NDK's #defines these macros as aliases - * to their non-64 counterparts. To avoid naming conflict, remove them. */ -#ifdef __ANDROID__ - /* These are restored by the corresponding #pragma pop_macro near - * the end of this file. */ -# pragma push_macro("stat64") -# pragma push_macro("fstat64") -# pragma push_macro("lstat64") -# undef stat64 -# undef fstat64 -# undef lstat64 -#endif - -/* As glibc often provides subtly incompatible data structures (and implicit - * wrapper functions that convert them), we provide our own kernel data - * structures for use by the system calls. - * These structures have been developed by using Linux 2.6.23 headers for - * reference. Note though, we do not care about exact API compatibility - * with the kernel, and in fact the kernel often does not have a single - * API that works across architectures. Instead, we try to mimic the glibc - * API where reasonable, and only guarantee ABI compatibility with the - * kernel headers. - * Most notably, here are a few changes that were made to the structures - * defined by kernel headers: - * - * - we only define structures, but not symbolic names for kernel data - * types. For the latter, we directly use the native C datatype - * (i.e. "unsigned" instead of "mode_t"). - * - in a few cases, it is possible to define identical structures for - * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by - * standardizing on the 64bit version of the data types. In particular, - * this means that we use "unsigned" where the 32bit headers say - * "unsigned long". - * - overall, we try to minimize the number of cases where we need to - * conditionally define different structures. - * - the "struct kernel_sigaction" class of structures have been - * modified to more closely mimic glibc's API by introducing an - * anonymous union for the function pointer. - * - a small number of field names had to have an underscore appended to - * them, because glibc defines a global macro by the same name. - */ - -/* include/linux/dirent.h */ -struct kernel_dirent64 { - unsigned long long d_ino; - long long d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[256]; -}; - -/* include/linux/dirent.h */ -#if defined(__aarch64__) -// aarch64 only defines dirent64, just uses that for dirent too. -#define kernel_dirent kernel_dirent64 -#else -struct kernel_dirent { - long d_ino; - long d_off; - unsigned short d_reclen; - char d_name[256]; -}; -#endif - -/* include/linux/uio.h */ -struct kernel_iovec { - void *iov_base; - unsigned long iov_len; -}; - -/* include/linux/socket.h */ -struct kernel_msghdr { - void *msg_name; - int msg_namelen; - struct kernel_iovec*msg_iov; - unsigned long msg_iovlen; - void *msg_control; - unsigned long msg_controllen; - unsigned msg_flags; -}; - -/* include/asm-generic/poll.h */ -struct kernel_pollfd { - int fd; - short events; - short revents; -}; - -/* include/linux/resource.h */ -struct kernel_rlimit { - unsigned long rlim_cur; - unsigned long rlim_max; -}; - -/* include/linux/time.h */ -struct kernel_timespec { - long tv_sec; - long tv_nsec; -}; - -/* include/linux/time.h */ -struct kernel_timeval { - long tv_sec; - long tv_usec; -}; - -/* include/linux/resource.h */ -struct kernel_rusage { - struct kernel_timeval ru_utime; - struct kernel_timeval ru_stime; - long ru_maxrss; - long ru_ixrss; - long ru_idrss; - long ru_isrss; - long ru_minflt; - long ru_majflt; - long ru_nswap; - long ru_inblock; - long ru_oublock; - long ru_msgsnd; - long ru_msgrcv; - long ru_nsignals; - long ru_nvcsw; - long ru_nivcsw; -}; - -#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \ - || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) - -/* include/asm-{arm,i386,mips,ppc}/signal.h */ -struct kernel_old_sigaction { - union { - void (*sa_handler_)(int); - void (*sa_sigaction_)(int, siginfo_t *, void *); - }; - unsigned long sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -} __attribute__((packed,aligned(4))); -#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) - #define kernel_old_sigaction kernel_sigaction -#elif defined(__aarch64__) - // No kernel_old_sigaction defined for arm64. -#endif - -/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the - * exactly match the size of the signal set, even though the API was - * intended to be extensible. We define our own KERNEL_NSIG to deal with - * this. - * Please note that glibc provides signals [1.._NSIG-1], whereas the - * kernel (and this header) provides the range [1..KERNEL_NSIG]. The - * actual number of signals is obviously the same, but the constants - * differ by one. - */ -#ifdef __mips__ -#define KERNEL_NSIG 128 -#else -#define KERNEL_NSIG 64 -#endif - -/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */ -struct kernel_sigset_t { - unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ - (8*sizeof(unsigned long))]; -}; - -/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ -struct kernel_sigaction { -#ifdef __mips__ - unsigned long sa_flags; - union { - void (*sa_handler_)(int); - void (*sa_sigaction_)(int, siginfo_t *, void *); - }; - struct kernel_sigset_t sa_mask; -#else - union { - void (*sa_handler_)(int); - void (*sa_sigaction_)(int, siginfo_t *, void *); - }; - unsigned long sa_flags; - void (*sa_restorer)(void); - struct kernel_sigset_t sa_mask; -#endif -}; - -/* include/linux/socket.h */ -struct kernel_sockaddr { - unsigned short sa_family; - char sa_data[14]; -}; - -/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */ -#ifdef __mips__ -#if _MIPS_SIM == _MIPS_SIM_ABI64 -struct kernel_stat { -#else -struct kernel_stat64 { -#endif - unsigned st_dev; - unsigned __pad0[3]; - unsigned long long st_ino; - unsigned st_mode; - unsigned st_nlink; - unsigned st_uid; - unsigned st_gid; - unsigned st_rdev; - unsigned __pad1[3]; - long long st_size; - unsigned st_atime_; - unsigned st_atime_nsec_; - unsigned st_mtime_; - unsigned st_mtime_nsec_; - unsigned st_ctime_; - unsigned st_ctime_nsec_; - unsigned st_blksize; - unsigned __pad2; - unsigned long long st_blocks; -}; -#elif defined __PPC__ -struct kernel_stat64 { - unsigned long long st_dev; - unsigned long long st_ino; - unsigned st_mode; - unsigned st_nlink; - unsigned st_uid; - unsigned st_gid; - unsigned long long st_rdev; - unsigned short int __pad2; - long long st_size; - long st_blksize; - long long st_blocks; - long st_atime_; - unsigned long st_atime_nsec_; - long st_mtime_; - unsigned long st_mtime_nsec_; - long st_ctime_; - unsigned long st_ctime_nsec_; - unsigned long __unused4; - unsigned long __unused5; -}; -#else -struct kernel_stat64 { - unsigned long long st_dev; - unsigned char __pad0[4]; - unsigned __st_ino; - unsigned st_mode; - unsigned st_nlink; - unsigned st_uid; - unsigned st_gid; - unsigned long long st_rdev; - unsigned char __pad3[4]; - long long st_size; - unsigned st_blksize; - unsigned long long st_blocks; - unsigned st_atime_; - unsigned st_atime_nsec_; - unsigned st_mtime_; - unsigned st_mtime_nsec_; - unsigned st_ctime_; - unsigned st_ctime_nsec_; - unsigned long long st_ino; -}; -#endif - -/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */ -#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) -struct kernel_stat { - /* The kernel headers suggest that st_dev and st_rdev should be 32bit - * quantities encoding 12bit major and 20bit minor numbers in an interleaved - * format. In reality, we do not see useful data in the top bits. So, - * we'll leave the padding in here, until we find a better solution. - */ - unsigned short st_dev; - short pad1; - unsigned st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - short pad2; - unsigned st_size; - unsigned st_blksize; - unsigned st_blocks; - unsigned st_atime_; - unsigned st_atime_nsec_; - unsigned st_mtime_; - unsigned st_mtime_nsec_; - unsigned st_ctime_; - unsigned st_ctime_nsec_; - unsigned __unused4; - unsigned __unused5; -}; -#elif defined(__x86_64__) -struct kernel_stat { - uint64_t st_dev; - uint64_t st_ino; - uint64_t st_nlink; - unsigned st_mode; - unsigned st_uid; - unsigned st_gid; - unsigned __pad0; - uint64_t st_rdev; - int64_t st_size; - int64_t st_blksize; - int64_t st_blocks; - uint64_t st_atime_; - uint64_t st_atime_nsec_; - uint64_t st_mtime_; - uint64_t st_mtime_nsec_; - uint64_t st_ctime_; - uint64_t st_ctime_nsec_; - int64_t __unused4[3]; -}; -#elif defined(__PPC__) -struct kernel_stat { - unsigned st_dev; - unsigned long st_ino; // ino_t - unsigned long st_mode; // mode_t - unsigned short st_nlink; // nlink_t - unsigned st_uid; // uid_t - unsigned st_gid; // gid_t - unsigned st_rdev; - long st_size; // off_t - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime_; - unsigned long st_atime_nsec_; - unsigned long st_mtime_; - unsigned long st_mtime_nsec_; - unsigned long st_ctime_; - unsigned long st_ctime_nsec_; - unsigned long __unused4; - unsigned long __unused5; -}; -#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) -struct kernel_stat { - unsigned st_dev; - int st_pad1[3]; - unsigned st_ino; - unsigned st_mode; - unsigned st_nlink; - unsigned st_uid; - unsigned st_gid; - unsigned st_rdev; - int st_pad2[2]; - long st_size; - int st_pad3; - long st_atime_; - long st_atime_nsec_; - long st_mtime_; - long st_mtime_nsec_; - long st_ctime_; - long st_ctime_nsec_; - int st_blksize; - int st_blocks; - int st_pad4[14]; -}; -#elif defined(__aarch64__) -struct kernel_stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned long st_rdev; - unsigned long __pad1; - long st_size; - int st_blksize; - int __pad2; - long st_blocks; - long st_atime_; - unsigned long st_atime_nsec_; - long st_mtime_; - unsigned long st_mtime_nsec_; - long st_ctime_; - unsigned long st_ctime_nsec_; - unsigned int __unused4; - unsigned int __unused5; -}; -#elif defined(__s390x__) -struct kernel_stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_nlink; - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int __pad1; - unsigned long st_rdev; - unsigned long st_size; - unsigned long st_atime_; - unsigned long st_atime_nsec_; - unsigned long st_mtime_; - unsigned long st_mtime_nsec_; - unsigned long st_ctime_; - unsigned long st_ctime_nsec_; - unsigned long st_blksize; - long st_blocks; - unsigned long __unused[3]; -}; -#elif defined(__s390__) -struct kernel_stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime_; - unsigned long st_atime_nsec_; - unsigned long st_mtime_; - unsigned long st_mtime_nsec_; - unsigned long st_ctime_; - unsigned long st_ctime_nsec_; - unsigned long __unused4; - unsigned long __unused5; -}; -#endif - -/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */ -#ifdef __mips__ -#if _MIPS_SIM != _MIPS_SIM_ABI64 -struct kernel_statfs64 { - unsigned long f_type; - unsigned long f_bsize; - unsigned long f_frsize; - unsigned long __pad; - unsigned long long f_blocks; - unsigned long long f_bfree; - unsigned long long f_files; - unsigned long long f_ffree; - unsigned long long f_bavail; - struct { int val[2]; } f_fsid; - unsigned long f_namelen; - unsigned long f_spare[6]; -}; -#endif -#elif defined(__s390__) -/* See also arch/s390/include/asm/compat.h */ -struct kernel_statfs64 { - unsigned int f_type; - unsigned int f_bsize; - unsigned long long f_blocks; - unsigned long long f_bfree; - unsigned long long f_bavail; - unsigned long long f_files; - unsigned long long f_ffree; - struct { int val[2]; } f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; -}; -#elif !defined(__x86_64__) -struct kernel_statfs64 { - unsigned long f_type; - unsigned long f_bsize; - unsigned long long f_blocks; - unsigned long long f_bfree; - unsigned long long f_bavail; - unsigned long long f_files; - unsigned long long f_ffree; - struct { int val[2]; } f_fsid; - unsigned long f_namelen; - unsigned long f_frsize; - unsigned long f_spare[5]; -}; -#endif - -/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */ -#ifdef __mips__ -struct kernel_statfs { - long f_type; - long f_bsize; - long f_frsize; - long f_blocks; - long f_bfree; - long f_files; - long f_ffree; - long f_bavail; - struct { int val[2]; } f_fsid; - long f_namelen; - long f_spare[6]; -}; -#elif defined(__x86_64__) -struct kernel_statfs { - /* x86_64 actually defines all these fields as signed, whereas all other */ - /* platforms define them as unsigned. Leaving them at unsigned should not */ - /* cause any problems. Make sure these are 64-bit even on x32. */ - uint64_t f_type; - uint64_t f_bsize; - uint64_t f_blocks; - uint64_t f_bfree; - uint64_t f_bavail; - uint64_t f_files; - uint64_t f_ffree; - struct { int val[2]; } f_fsid; - uint64_t f_namelen; - uint64_t f_frsize; - uint64_t f_spare[5]; -}; -#elif defined(__s390__) -struct kernel_statfs { - unsigned int f_type; - unsigned int f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; - struct { int val[2]; } f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; -}; -#else -struct kernel_statfs { - unsigned long f_type; - unsigned long f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; - struct { int val[2]; } f_fsid; - unsigned long f_namelen; - unsigned long f_frsize; - unsigned long f_spare[5]; -}; -#endif - - -/* Definitions missing from the standard header files */ -#ifndef O_DIRECTORY -#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__) -#define O_DIRECTORY 0040000 -#else -#define O_DIRECTORY 0200000 -#endif -#endif -#ifndef NT_PRXFPREG -#define NT_PRXFPREG 0x46e62b7f -#endif -#ifndef PTRACE_GETFPXREGS -#define PTRACE_GETFPXREGS ((enum __ptrace_request)18) -#endif -#ifndef PR_GET_DUMPABLE -#define PR_GET_DUMPABLE 3 -#endif -#ifndef PR_SET_DUMPABLE -#define PR_SET_DUMPABLE 4 -#endif -#ifndef PR_GET_SECCOMP -#define PR_GET_SECCOMP 21 -#endif -#ifndef PR_SET_SECCOMP -#define PR_SET_SECCOMP 22 -#endif -#ifndef AT_FDCWD -#define AT_FDCWD (-100) -#endif -#ifndef AT_SYMLINK_NOFOLLOW -#define AT_SYMLINK_NOFOLLOW 0x100 -#endif -#ifndef AT_REMOVEDIR -#define AT_REMOVEDIR 0x200 -#endif -#ifndef MREMAP_FIXED -#define MREMAP_FIXED 2 -#endif -#ifndef SA_RESTORER -#define SA_RESTORER 0x04000000 -#endif -#ifndef CPUCLOCK_PROF -#define CPUCLOCK_PROF 0 -#endif -#ifndef CPUCLOCK_VIRT -#define CPUCLOCK_VIRT 1 -#endif -#ifndef CPUCLOCK_SCHED -#define CPUCLOCK_SCHED 2 -#endif -#ifndef CPUCLOCK_PERTHREAD_MASK -#define CPUCLOCK_PERTHREAD_MASK 4 -#endif -#ifndef MAKE_PROCESS_CPUCLOCK -#define MAKE_PROCESS_CPUCLOCK(pid, clock) \ - ((~(int)(pid) << 3) | (int)(clock)) -#endif -#ifndef MAKE_THREAD_CPUCLOCK -#define MAKE_THREAD_CPUCLOCK(tid, clock) \ - ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK)) -#endif - -#ifndef FUTEX_WAIT -#define FUTEX_WAIT 0 -#endif -#ifndef FUTEX_WAKE -#define FUTEX_WAKE 1 -#endif -#ifndef FUTEX_FD -#define FUTEX_FD 2 -#endif -#ifndef FUTEX_REQUEUE -#define FUTEX_REQUEUE 3 -#endif -#ifndef FUTEX_CMP_REQUEUE -#define FUTEX_CMP_REQUEUE 4 -#endif -#ifndef FUTEX_WAKE_OP -#define FUTEX_WAKE_OP 5 -#endif -#ifndef FUTEX_LOCK_PI -#define FUTEX_LOCK_PI 6 -#endif -#ifndef FUTEX_UNLOCK_PI -#define FUTEX_UNLOCK_PI 7 -#endif -#ifndef FUTEX_TRYLOCK_PI -#define FUTEX_TRYLOCK_PI 8 -#endif -#ifndef FUTEX_PRIVATE_FLAG -#define FUTEX_PRIVATE_FLAG 128 -#endif -#ifndef FUTEX_CMD_MASK -#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG -#endif -#ifndef FUTEX_WAIT_PRIVATE -#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_WAKE_PRIVATE -#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_REQUEUE_PRIVATE -#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_CMP_REQUEUE_PRIVATE -#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_WAKE_OP_PRIVATE -#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_LOCK_PI_PRIVATE -#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_UNLOCK_PI_PRIVATE -#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) -#endif -#ifndef FUTEX_TRYLOCK_PI_PRIVATE -#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) -#endif - - -#if defined(__x86_64__) -#ifndef ARCH_SET_GS -#define ARCH_SET_GS 0x1001 -#endif -#ifndef ARCH_GET_GS -#define ARCH_GET_GS 0x1004 -#endif -#endif - -#if defined(__i386__) -#ifndef __NR_quotactl -#define __NR_quotactl 131 -#endif -#ifndef __NR_setresuid -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#endif -#ifndef __NR_rt_sigaction -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigsuspend 179 -#endif -#ifndef __NR_pread64 -#define __NR_pread64 180 -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 181 -#endif -#ifndef __NR_ugetrlimit -#define __NR_ugetrlimit 191 -#endif -#ifndef __NR_stat64 -#define __NR_stat64 195 -#endif -#ifndef __NR_fstat64 -#define __NR_fstat64 197 -#endif -#ifndef __NR_setresuid32 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#endif -#ifndef __NR_setfsuid32 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 220 -#endif -#ifndef __NR_gettid -#define __NR_gettid 224 -#endif -#ifndef __NR_readahead -#define __NR_readahead 225 -#endif -#ifndef __NR_setxattr -#define __NR_setxattr 226 -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr 227 -#endif -#ifndef __NR_getxattr -#define __NR_getxattr 229 -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr 230 -#endif -#ifndef __NR_listxattr -#define __NR_listxattr 232 -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr 233 -#endif -#ifndef __NR_tkill -#define __NR_tkill 238 -#endif -#ifndef __NR_futex -#define __NR_futex 240 -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 241 -#define __NR_sched_getaffinity 242 -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address 258 -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime 265 -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres 266 -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 268 -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 269 -#endif -#ifndef __NR_fadvise64_64 -#define __NR_fadvise64_64 272 -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set 289 -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get 290 -#endif -#ifndef __NR_openat -#define __NR_openat 295 -#endif -#ifndef __NR_fstatat64 -#define __NR_fstatat64 300 -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat 301 -#endif -#ifndef __NR_move_pages -#define __NR_move_pages 317 -#endif -#ifndef __NR_getcpu -#define __NR_getcpu 318 -#endif -#ifndef __NR_fallocate -#define __NR_fallocate 324 -#endif -/* End of i386 definitions */ -#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) -#ifndef __NR_setresuid -#define __NR_setresuid (__NR_SYSCALL_BASE + 164) -#define __NR_getresuid (__NR_SYSCALL_BASE + 165) -#define __NR_setresgid (__NR_SYSCALL_BASE + 170) -#define __NR_getresgid (__NR_SYSCALL_BASE + 171) -#endif -#ifndef __NR_rt_sigaction -#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173) -#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) -#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) -#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176) -#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179) -#endif -#ifndef __NR_pread64 -#define __NR_pread64 (__NR_SYSCALL_BASE + 180) -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181) -#endif -#ifndef __NR_ugetrlimit -#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191) -#endif -#ifndef __NR_stat64 -#define __NR_stat64 (__NR_SYSCALL_BASE + 195) -#endif -#ifndef __NR_fstat64 -#define __NR_fstat64 (__NR_SYSCALL_BASE + 197) -#endif -#ifndef __NR_setresuid32 -#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208) -#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209) -#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210) -#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211) -#endif -#ifndef __NR_setfsuid32 -#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215) -#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216) -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 (__NR_SYSCALL_BASE + 217) -#endif -#ifndef __NR_gettid -#define __NR_gettid (__NR_SYSCALL_BASE + 224) -#endif -#ifndef __NR_readahead -#define __NR_readahead (__NR_SYSCALL_BASE + 225) -#endif -#ifndef __NR_setxattr -#define __NR_setxattr (__NR_SYSCALL_BASE + 226) -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227) -#endif -#ifndef __NR_getxattr -#define __NR_getxattr (__NR_SYSCALL_BASE + 229) -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230) -#endif -#ifndef __NR_listxattr -#define __NR_listxattr (__NR_SYSCALL_BASE + 232) -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr (__NR_SYSCALL_BASE + 233) -#endif -#ifndef __NR_tkill -#define __NR_tkill (__NR_SYSCALL_BASE + 238) -#endif -#ifndef __NR_futex -#define __NR_futex (__NR_SYSCALL_BASE + 240) -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241) -#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242) -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256) -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263) -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres (__NR_SYSCALL_BASE + 264) -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 (__NR_SYSCALL_BASE + 266) -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267) -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) -#endif -#ifndef __NR_move_pages -#define __NR_move_pages (__NR_SYSCALL_BASE + 344) -#endif -#ifndef __NR_getcpu -#define __NR_getcpu (__NR_SYSCALL_BASE + 345) -#endif -/* End of ARM 3/EABI definitions */ -#elif defined(__aarch64__) -#ifndef __NR_setxattr -#define __NR_setxattr 5 -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr 6 -#endif -#ifndef __NR_getxattr -#define __NR_getxattr 8 -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr 9 -#endif -#ifndef __NR_listxattr -#define __NR_listxattr 11 -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr 12 -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set 30 -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get 31 -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat 35 -#endif -#ifndef __NR_fallocate -#define __NR_fallocate 47 -#endif -#ifndef __NR_openat -#define __NR_openat 56 -#endif -#ifndef __NR_quotactl -#define __NR_quotactl 60 -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 61 -#endif -#ifndef __NR_getdents -#define __NR_getdents __NR_getdents64 -#endif -#ifndef __NR_pread64 -#define __NR_pread64 67 -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 68 -#endif -#ifndef __NR_ppoll -#define __NR_ppoll 73 -#endif -#ifndef __NR_readlinkat -#define __NR_readlinkat 78 -#endif -#ifndef __NR_newfstatat -#define __NR_newfstatat 79 -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address 96 -#endif -#ifndef __NR_futex -#define __NR_futex 98 -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime 113 -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres 114 -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 122 -#define __NR_sched_getaffinity 123 -#endif -#ifndef __NR_tkill -#define __NR_tkill 130 -#endif -#ifndef __NR_setresuid -#define __NR_setresuid 147 -#define __NR_getresuid 148 -#define __NR_setresgid 149 -#define __NR_getresgid 150 -#endif -#ifndef __NR_gettid -#define __NR_gettid 178 -#endif -#ifndef __NR_readahead -#define __NR_readahead 213 -#endif -#ifndef __NR_fadvise64 -#define __NR_fadvise64 223 -#endif -#ifndef __NR_move_pages -#define __NR_move_pages 239 -#endif -/* End of aarch64 definitions */ -#elif defined(__x86_64__) -#ifndef __NR_pread64 -#define __NR_pread64 17 -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 18 -#endif -#ifndef __NR_setresuid -#define __NR_setresuid 117 -#define __NR_getresuid 118 -#define __NR_setresgid 119 -#define __NR_getresgid 120 -#endif -#ifndef __NR_quotactl -#define __NR_quotactl 179 -#endif -#ifndef __NR_gettid -#define __NR_gettid 186 -#endif -#ifndef __NR_readahead -#define __NR_readahead 187 -#endif -#ifndef __NR_setxattr -#define __NR_setxattr 188 -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr 189 -#endif -#ifndef __NR_getxattr -#define __NR_getxattr 191 -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr 192 -#endif -#ifndef __NR_listxattr -#define __NR_listxattr 194 -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr 195 -#endif -#ifndef __NR_tkill -#define __NR_tkill 200 -#endif -#ifndef __NR_futex -#define __NR_futex 202 -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 203 -#define __NR_sched_getaffinity 204 -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 217 -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address 218 -#endif -#ifndef __NR_fadvise64 -#define __NR_fadvise64 221 -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime 228 -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres 229 -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set 251 -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get 252 -#endif -#ifndef __NR_openat -#define __NR_openat 257 -#endif -#ifndef __NR_newfstatat -#define __NR_newfstatat 262 -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat 263 -#endif -#ifndef __NR_move_pages -#define __NR_move_pages 279 -#endif -#ifndef __NR_fallocate -#define __NR_fallocate 285 -#endif -/* End of x86-64 definitions */ -#elif defined(__mips__) -#if _MIPS_SIM == _MIPS_SIM_ABI32 -#ifndef __NR_setresuid -#define __NR_setresuid (__NR_Linux + 185) -#define __NR_getresuid (__NR_Linux + 186) -#define __NR_setresgid (__NR_Linux + 190) -#define __NR_getresgid (__NR_Linux + 191) -#endif -#ifndef __NR_rt_sigaction -#define __NR_rt_sigreturn (__NR_Linux + 193) -#define __NR_rt_sigaction (__NR_Linux + 194) -#define __NR_rt_sigprocmask (__NR_Linux + 195) -#define __NR_rt_sigpending (__NR_Linux + 196) -#define __NR_rt_sigsuspend (__NR_Linux + 199) -#endif -#ifndef __NR_pread64 -#define __NR_pread64 (__NR_Linux + 200) -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 (__NR_Linux + 201) -#endif -#ifndef __NR_stat64 -#define __NR_stat64 (__NR_Linux + 213) -#endif -#ifndef __NR_fstat64 -#define __NR_fstat64 (__NR_Linux + 215) -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 (__NR_Linux + 219) -#endif -#ifndef __NR_gettid -#define __NR_gettid (__NR_Linux + 222) -#endif -#ifndef __NR_readahead -#define __NR_readahead (__NR_Linux + 223) -#endif -#ifndef __NR_setxattr -#define __NR_setxattr (__NR_Linux + 224) -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr (__NR_Linux + 225) -#endif -#ifndef __NR_getxattr -#define __NR_getxattr (__NR_Linux + 227) -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr (__NR_Linux + 228) -#endif -#ifndef __NR_listxattr -#define __NR_listxattr (__NR_Linux + 230) -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr (__NR_Linux + 231) -#endif -#ifndef __NR_tkill -#define __NR_tkill (__NR_Linux + 236) -#endif -#ifndef __NR_futex -#define __NR_futex (__NR_Linux + 238) -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity (__NR_Linux + 239) -#define __NR_sched_getaffinity (__NR_Linux + 240) -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address (__NR_Linux + 252) -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 (__NR_Linux + 255) -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 (__NR_Linux + 256) -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime (__NR_Linux + 263) -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres (__NR_Linux + 264) -#endif -#ifndef __NR_openat -#define __NR_openat (__NR_Linux + 288) -#endif -#ifndef __NR_fstatat -#define __NR_fstatat (__NR_Linux + 293) -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat (__NR_Linux + 294) -#endif -#ifndef __NR_move_pages -#define __NR_move_pages (__NR_Linux + 308) -#endif -#ifndef __NR_getcpu -#define __NR_getcpu (__NR_Linux + 312) -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set (__NR_Linux + 314) -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get (__NR_Linux + 315) -#endif -/* End of MIPS (old 32bit API) definitions */ -#elif _MIPS_SIM == _MIPS_SIM_ABI64 -#ifndef __NR_pread64 -#define __NR_pread64 (__NR_Linux + 16) -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 (__NR_Linux + 17) -#endif -#ifndef __NR_setresuid -#define __NR_setresuid (__NR_Linux + 115) -#define __NR_getresuid (__NR_Linux + 116) -#define __NR_setresgid (__NR_Linux + 117) -#define __NR_getresgid (__NR_Linux + 118) -#endif -#ifndef __NR_gettid -#define __NR_gettid (__NR_Linux + 178) -#endif -#ifndef __NR_readahead -#define __NR_readahead (__NR_Linux + 179) -#endif -#ifndef __NR_setxattr -#define __NR_setxattr (__NR_Linux + 180) -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr (__NR_Linux + 181) -#endif -#ifndef __NR_getxattr -#define __NR_getxattr (__NR_Linux + 183) -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr (__NR_Linux + 184) -#endif -#ifndef __NR_listxattr -#define __NR_listxattr (__NR_Linux + 186) -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr (__NR_Linux + 187) -#endif -#ifndef __NR_tkill -#define __NR_tkill (__NR_Linux + 192) -#endif -#ifndef __NR_futex -#define __NR_futex (__NR_Linux + 194) -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity (__NR_Linux + 195) -#define __NR_sched_getaffinity (__NR_Linux + 196) -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address (__NR_Linux + 212) -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime (__NR_Linux + 222) -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres (__NR_Linux + 223) -#endif -#ifndef __NR_openat -#define __NR_openat (__NR_Linux + 247) -#endif -#ifndef __NR_fstatat -#define __NR_fstatat (__NR_Linux + 252) -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat (__NR_Linux + 253) -#endif -#ifndef __NR_move_pages -#define __NR_move_pages (__NR_Linux + 267) -#endif -#ifndef __NR_getcpu -#define __NR_getcpu (__NR_Linux + 271) -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set (__NR_Linux + 273) -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get (__NR_Linux + 274) -#endif -/* End of MIPS (64bit API) definitions */ -#else -#ifndef __NR_setresuid -#define __NR_setresuid (__NR_Linux + 115) -#define __NR_getresuid (__NR_Linux + 116) -#define __NR_setresgid (__NR_Linux + 117) -#define __NR_getresgid (__NR_Linux + 118) -#endif -#ifndef __NR_gettid -#define __NR_gettid (__NR_Linux + 178) -#endif -#ifndef __NR_readahead -#define __NR_readahead (__NR_Linux + 179) -#endif -#ifndef __NR_setxattr -#define __NR_setxattr (__NR_Linux + 180) -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr (__NR_Linux + 181) -#endif -#ifndef __NR_getxattr -#define __NR_getxattr (__NR_Linux + 183) -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr (__NR_Linux + 184) -#endif -#ifndef __NR_listxattr -#define __NR_listxattr (__NR_Linux + 186) -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr (__NR_Linux + 187) -#endif -#ifndef __NR_tkill -#define __NR_tkill (__NR_Linux + 192) -#endif -#ifndef __NR_futex -#define __NR_futex (__NR_Linux + 194) -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity (__NR_Linux + 195) -#define __NR_sched_getaffinity (__NR_Linux + 196) -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address (__NR_Linux + 213) -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 (__NR_Linux + 217) -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 (__NR_Linux + 218) -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime (__NR_Linux + 226) -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres (__NR_Linux + 227) -#endif -#ifndef __NR_openat -#define __NR_openat (__NR_Linux + 251) -#endif -#ifndef __NR_fstatat -#define __NR_fstatat (__NR_Linux + 256) -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat (__NR_Linux + 257) -#endif -#ifndef __NR_move_pages -#define __NR_move_pages (__NR_Linux + 271) -#endif -#ifndef __NR_getcpu -#define __NR_getcpu (__NR_Linux + 275) -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set (__NR_Linux + 277) -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get (__NR_Linux + 278) -#endif -/* End of MIPS (new 32bit API) definitions */ -#endif -/* End of MIPS definitions */ -#elif defined(__PPC__) -#ifndef __NR_setfsuid -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#endif -#ifndef __NR_setresuid -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_setresgid 169 -#define __NR_getresgid 170 -#endif -#ifndef __NR_rt_sigaction -#define __NR_rt_sigreturn 172 -#define __NR_rt_sigaction 173 -#define __NR_rt_sigprocmask 174 -#define __NR_rt_sigpending 175 -#define __NR_rt_sigsuspend 178 -#endif -#ifndef __NR_pread64 -#define __NR_pread64 179 -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 180 -#endif -#ifndef __NR_ugetrlimit -#define __NR_ugetrlimit 190 -#endif -#ifndef __NR_readahead -#define __NR_readahead 191 -#endif -#ifndef __NR_stat64 -#define __NR_stat64 195 -#endif -#ifndef __NR_fstat64 -#define __NR_fstat64 197 -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 202 -#endif -#ifndef __NR_gettid -#define __NR_gettid 207 -#endif -#ifndef __NR_tkill -#define __NR_tkill 208 -#endif -#ifndef __NR_setxattr -#define __NR_setxattr 209 -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr 210 -#endif -#ifndef __NR_getxattr -#define __NR_getxattr 212 -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr 213 -#endif -#ifndef __NR_listxattr -#define __NR_listxattr 215 -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr 216 -#endif -#ifndef __NR_futex -#define __NR_futex 221 -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 222 -#define __NR_sched_getaffinity 223 -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address 232 -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime 246 -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres 247 -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 252 -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 253 -#endif -#ifndef __NR_fadvise64_64 -#define __NR_fadvise64_64 254 -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set 273 -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get 274 -#endif -#ifndef __NR_openat -#define __NR_openat 286 -#endif -#ifndef __NR_fstatat64 -#define __NR_fstatat64 291 -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat 292 -#endif -#ifndef __NR_move_pages -#define __NR_move_pages 301 -#endif -#ifndef __NR_getcpu -#define __NR_getcpu 302 -#endif -/* End of powerpc defininitions */ -#elif defined(__s390__) -#ifndef __NR_quotactl -#define __NR_quotactl 131 -#endif -#ifndef __NR_rt_sigreturn -#define __NR_rt_sigreturn 173 -#endif -#ifndef __NR_rt_sigaction -#define __NR_rt_sigaction 174 -#endif -#ifndef __NR_rt_sigprocmask -#define __NR_rt_sigprocmask 175 -#endif -#ifndef __NR_rt_sigpending -#define __NR_rt_sigpending 176 -#endif -#ifndef __NR_rt_sigsuspend -#define __NR_rt_sigsuspend 179 -#endif -#ifndef __NR_pread64 -#define __NR_pread64 180 -#endif -#ifndef __NR_pwrite64 -#define __NR_pwrite64 181 -#endif -#ifndef __NR_getdents64 -#define __NR_getdents64 220 -#endif -#ifndef __NR_readahead -#define __NR_readahead 222 -#endif -#ifndef __NR_setxattr -#define __NR_setxattr 224 -#endif -#ifndef __NR_lsetxattr -#define __NR_lsetxattr 225 -#endif -#ifndef __NR_getxattr -#define __NR_getxattr 227 -#endif -#ifndef __NR_lgetxattr -#define __NR_lgetxattr 228 -#endif -#ifndef __NR_listxattr -#define __NR_listxattr 230 -#endif -#ifndef __NR_llistxattr -#define __NR_llistxattr 231 -#endif -#ifndef __NR_gettid -#define __NR_gettid 236 -#endif -#ifndef __NR_tkill -#define __NR_tkill 237 -#endif -#ifndef __NR_futex -#define __NR_futex 238 -#endif -#ifndef __NR_sched_setaffinity -#define __NR_sched_setaffinity 239 -#endif -#ifndef __NR_sched_getaffinity -#define __NR_sched_getaffinity 240 -#endif -#ifndef __NR_set_tid_address -#define __NR_set_tid_address 252 -#endif -#ifndef __NR_clock_gettime -#define __NR_clock_gettime 260 -#endif -#ifndef __NR_clock_getres -#define __NR_clock_getres 261 -#endif -#ifndef __NR_statfs64 -#define __NR_statfs64 265 -#endif -#ifndef __NR_fstatfs64 -#define __NR_fstatfs64 266 -#endif -#ifndef __NR_ioprio_set -#define __NR_ioprio_set 282 -#endif -#ifndef __NR_ioprio_get -#define __NR_ioprio_get 283 -#endif -#ifndef __NR_openat -#define __NR_openat 288 -#endif -#ifndef __NR_unlinkat -#define __NR_unlinkat 294 -#endif -#ifndef __NR_move_pages -#define __NR_move_pages 310 -#endif -#ifndef __NR_getcpu -#define __NR_getcpu 311 -#endif -#ifndef __NR_fallocate -#define __NR_fallocate 314 -#endif -/* Some syscalls are named/numbered differently between s390 and s390x. */ -#ifdef __s390x__ -# ifndef __NR_getrlimit -# define __NR_getrlimit 191 -# endif -# ifndef __NR_setresuid -# define __NR_setresuid 208 -# endif -# ifndef __NR_getresuid -# define __NR_getresuid 209 -# endif -# ifndef __NR_setresgid -# define __NR_setresgid 210 -# endif -# ifndef __NR_getresgid -# define __NR_getresgid 211 -# endif -# ifndef __NR_setfsuid -# define __NR_setfsuid 215 -# endif -# ifndef __NR_setfsgid -# define __NR_setfsgid 216 -# endif -# ifndef __NR_fadvise64 -# define __NR_fadvise64 253 -# endif -# ifndef __NR_newfstatat -# define __NR_newfstatat 293 -# endif -#else /* __s390x__ */ -# ifndef __NR_getrlimit -# define __NR_getrlimit 76 -# endif -# ifndef __NR_setfsuid -# define __NR_setfsuid 138 -# endif -# ifndef __NR_setfsgid -# define __NR_setfsgid 139 -# endif -# ifndef __NR_setresuid -# define __NR_setresuid 164 -# endif -# ifndef __NR_getresuid -# define __NR_getresuid 165 -# endif -# ifndef __NR_setresgid -# define __NR_setresgid 170 -# endif -# ifndef __NR_getresgid -# define __NR_getresgid 171 -# endif -# ifndef __NR_ugetrlimit -# define __NR_ugetrlimit 191 -# endif -# ifndef __NR_mmap2 -# define __NR_mmap2 192 -# endif -# ifndef __NR_setresuid32 -# define __NR_setresuid32 208 -# endif -# ifndef __NR_getresuid32 -# define __NR_getresuid32 209 -# endif -# ifndef __NR_setresgid32 -# define __NR_setresgid32 210 -# endif -# ifndef __NR_getresgid32 -# define __NR_getresgid32 211 -# endif -# ifndef __NR_setfsuid32 -# define __NR_setfsuid32 215 -# endif -# ifndef __NR_setfsgid32 -# define __NR_setfsgid32 216 -# endif -# ifndef __NR_fadvise64_64 -# define __NR_fadvise64_64 264 -# endif -# ifndef __NR_fstatat64 -# define __NR_fstatat64 293 -# endif -#endif /* __s390__ */ -/* End of s390/s390x definitions */ -#endif - - -/* After forking, we must make sure to only call system calls. */ -#if defined(__BOUNDED_POINTERS__) - #error "Need to port invocations of syscalls for bounded ptrs" -#else - /* The core dumper and the thread lister get executed after threads - * have been suspended. As a consequence, we cannot call any functions - * that acquire locks. Unfortunately, libc wraps most system calls - * (e.g. in order to implement pthread_atfork, and to make calls - * cancellable), which means we cannot call these functions. Instead, - * we have to call syscall() directly. - */ - #undef LSS_ERRNO - #ifdef SYS_ERRNO - /* Allow the including file to override the location of errno. This can - * be useful when using clone() with the CLONE_VM option. - */ - #define LSS_ERRNO SYS_ERRNO - #else - #define LSS_ERRNO errno - #endif - - #undef LSS_INLINE - #ifdef SYS_INLINE - #define LSS_INLINE SYS_INLINE - #else - #define LSS_INLINE static inline - #endif - - /* Allow the including file to override the prefix used for all new - * system calls. By default, it will be set to "sys_". - */ - #undef LSS_NAME - #ifndef SYS_PREFIX - #define LSS_NAME(name) sys_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX < 0 - #define LSS_NAME(name) name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 0 - #define LSS_NAME(name) sys0_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 1 - #define LSS_NAME(name) sys1_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 2 - #define LSS_NAME(name) sys2_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 3 - #define LSS_NAME(name) sys3_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 4 - #define LSS_NAME(name) sys4_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 5 - #define LSS_NAME(name) sys5_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 6 - #define LSS_NAME(name) sys6_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 7 - #define LSS_NAME(name) sys7_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 8 - #define LSS_NAME(name) sys8_##name - #elif defined(SYS_PREFIX) && SYS_PREFIX == 9 - #define LSS_NAME(name) sys9_##name - #endif - - #undef LSS_RETURN - #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ - || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__)) - /* Failing system calls return a negative result in the range of - * -1..-4095. These are "errno" values with the sign inverted. - */ - #define LSS_RETURN(type, res) \ - do { \ - if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ - LSS_ERRNO = -(res); \ - res = -1; \ - } \ - return (type) (res); \ - } while (0) - #elif defined(__mips__) - /* On MIPS, failing system calls return -1, and set errno in a - * separate CPU register. - */ - #define LSS_RETURN(type, res, err) \ - do { \ - if (err) { \ - unsigned long __errnovalue = (res); \ - LSS_ERRNO = __errnovalue; \ - res = -1; \ - } \ - return (type) (res); \ - } while (0) - #elif defined(__PPC__) - /* On PPC, failing system calls return -1, and set errno in a - * separate CPU register. See linux/unistd.h. - */ - #define LSS_RETURN(type, res, err) \ - do { \ - if (err & 0x10000000 ) { \ - LSS_ERRNO = (res); \ - res = -1; \ - } \ - return (type) (res); \ - } while (0) - #endif - #if defined(__i386__) - /* In PIC mode (e.g. when building shared libraries), gcc for i386 - * reserves ebx. Unfortunately, most distribution ship with implementations - * of _syscallX() which clobber ebx. - * Also, most definitions of _syscallX() neglect to mark "memory" as being - * clobbered. This causes problems with compilers, that do a better job - * at optimizing across __asm__ calls. - * So, we just have to redefine all of the _syscallX() macros. - */ - #undef LSS_ENTRYPOINT - #ifdef SYS_SYSCALL_ENTRYPOINT - static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { - void (**entrypoint)(void); - asm volatile(".bss\n" - ".align 8\n" - ".globl " SYS_SYSCALL_ENTRYPOINT "\n" - ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" - ".previous\n" - /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */ - "call 0f\n" - "0:pop %0\n" - "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n" - "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n" - : "=r"(entrypoint)); - return entrypoint; - } - - #define LSS_ENTRYPOINT ".bss\n" \ - ".align 8\n" \ - ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ - ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ - ".previous\n" \ - /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \ - "push %%eax\n" \ - "call 10000f\n" \ - "10000:pop %%eax\n" \ - "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \ - "mov " SYS_SYSCALL_ENTRYPOINT \ - "@GOT(%%eax), %%eax\n" \ - "mov 0(%%eax), %%eax\n" \ - "test %%eax, %%eax\n" \ - "jz 10002f\n" \ - "push %%eax\n" \ - "call 10001f\n" \ - "10001:pop %%eax\n" \ - "add $(10003f-10001b), %%eax\n" \ - "xchg 4(%%esp), %%eax\n" \ - "ret\n" \ - "10002:pop %%eax\n" \ - "int $0x80\n" \ - "10003:\n" - #else - #define LSS_ENTRYPOINT "int $0x80\n" - #endif - #undef LSS_BODY - #define LSS_BODY(type,args...) \ - long __res; \ - __asm__ __volatile__("push %%ebx\n" \ - "movl %2,%%ebx\n" \ - LSS_ENTRYPOINT \ - "pop %%ebx" \ - args \ - : "esp", "memory"); \ - LSS_RETURN(type,__res) - #undef _syscall0 - #define _syscall0(type,name) \ - type LSS_NAME(name)(void) { \ - long __res; \ - __asm__ volatile(LSS_ENTRYPOINT \ - : "=a" (__res) \ - : "0" (__NR_##name) \ - : "esp", "memory"); \ - LSS_RETURN(type,__res); \ - } - #undef _syscall1 - #define _syscall1(type,name,type1,arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_BODY(type, \ - : "=a" (__res) \ - : "0" (__NR_##name), "ri" ((long)(arg1))); \ - } - #undef _syscall2 - #define _syscall2(type,name,type1,arg1,type2,arg2) \ - type LSS_NAME(name)(type1 arg1,type2 arg2) { \ - LSS_BODY(type, \ - : "=a" (__res) \ - : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ - } - #undef _syscall3 - #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ - type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ - LSS_BODY(type, \ - : "=a" (__res) \ - : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ - "d" ((long)(arg3))); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_BODY(type, \ - : "=a" (__res) \ - : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4))); \ - } - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - long __res; \ - __asm__ __volatile__("push %%ebx\n" \ - "movl %2,%%ebx\n" \ - "movl %1,%%eax\n" \ - LSS_ENTRYPOINT \ - "pop %%ebx" \ - : "=a" (__res) \ - : "i" (__NR_##name), "ri" ((long)(arg1)), \ - "c" ((long)(arg2)), "d" ((long)(arg3)), \ - "S" ((long)(arg4)), "D" ((long)(arg5)) \ - : "esp", "memory"); \ - LSS_RETURN(type,__res); \ - } - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - long __res; \ - struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ - __asm__ __volatile__("push %%ebp\n" \ - "push %%ebx\n" \ - "movl 4(%2),%%ebp\n" \ - "movl 0(%2), %%ebx\n" \ - "movl %1,%%eax\n" \ - LSS_ENTRYPOINT \ - "pop %%ebx\n" \ - "pop %%ebp" \ - : "=a" (__res) \ - : "i" (__NR_##name), "0" ((long)(&__s)), \ - "c" ((long)(arg2)), "d" ((long)(arg3)), \ - "S" ((long)(arg4)), "D" ((long)(arg5)) \ - : "esp", "memory"); \ - LSS_RETURN(type,__res); \ - } - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long __res; - __asm__ __volatile__(/* if (fn == NULL) - * return -EINVAL; - */ - "movl %3,%%ecx\n" - "jecxz 1f\n" - - /* if (child_stack == NULL) - * return -EINVAL; - */ - "movl %4,%%ecx\n" - "jecxz 1f\n" - - /* Set up alignment of the child stack: - * child_stack = (child_stack & ~0xF) - 20; - */ - "andl $-16,%%ecx\n" - "subl $20,%%ecx\n" - - /* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - "movl %6,%%eax\n" - "movl %%eax,4(%%ecx)\n" - "movl %3,%%eax\n" - "movl %%eax,(%%ecx)\n" - - /* %eax = syscall(%eax = __NR_clone, - * %ebx = flags, - * %ecx = child_stack, - * %edx = parent_tidptr, - * %esi = newtls, - * %edi = child_tidptr) - * Also, make sure that %ebx gets preserved as it is - * used in PIC mode. - */ - "movl %8,%%esi\n" - "movl %7,%%edx\n" - "movl %5,%%eax\n" - "movl %9,%%edi\n" - "pushl %%ebx\n" - "movl %%eax,%%ebx\n" - "movl %2,%%eax\n" - LSS_ENTRYPOINT - - /* In the parent: restore %ebx - * In the child: move "fn" into %ebx - */ - "popl %%ebx\n" - - /* if (%eax != 0) - * return %eax; - */ - "test %%eax,%%eax\n" - "jnz 1f\n" - - /* In the child, now. Terminate frame pointer chain. - */ - "movl $0,%%ebp\n" - - /* Call "fn". "arg" is already on the stack. - */ - "call *%%ebx\n" - - /* Call _exit(%ebx). Unfortunately older versions - * of gcc restrict the number of arguments that can - * be passed to asm(). So, we need to hard-code the - * system call number. - */ - "movl %%eax,%%ebx\n" - "movl $1,%%eax\n" - LSS_ENTRYPOINT - - /* Return to parent. - */ - "1:\n" - : "=a" (__res) - : "0"(-EINVAL), "i"(__NR_clone), - "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), - "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) - : "esp", "memory", "ecx", "edx", "esi", "edi"); - LSS_RETURN(int, __res); - } - - LSS_INLINE _syscall1(int, set_thread_area, void *, u) - LSS_INLINE _syscall1(int, get_thread_area, void *, u) - - LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { - /* On i386, the kernel does not know how to return from a signal - * handler. Instead, it relies on user space to provide a - * restorer function that calls the {rt_,}sigreturn() system call. - * Unfortunately, we cannot just reference the glibc version of this - * function, as glibc goes out of its way to make it inaccessible. - */ - void (*res)(void); - __asm__ __volatile__("call 2f\n" - "0:.align 16\n" - "1:movl %1,%%eax\n" - LSS_ENTRYPOINT - "2:popl %0\n" - "addl $(1b-0b),%0\n" - : "=a" (res) - : "i" (__NR_rt_sigreturn)); - return res; - } - LSS_INLINE void (*LSS_NAME(restore)(void))(void) { - /* On i386, the kernel does not know how to return from a signal - * handler. Instead, it relies on user space to provide a - * restorer function that calls the {rt_,}sigreturn() system call. - * Unfortunately, we cannot just reference the glibc version of this - * function, as glibc goes out of its way to make it inaccessible. - */ - void (*res)(void); - __asm__ __volatile__("call 2f\n" - "0:.align 16\n" - "1:pop %%eax\n" - "movl %1,%%eax\n" - LSS_ENTRYPOINT - "2:popl %0\n" - "addl $(1b-0b),%0\n" - : "=a" (res) - : "i" (__NR_sigreturn)); - return res; - } - #elif defined(__x86_64__) - /* There are no known problems with any of the _syscallX() macros - * currently shipping for x86_64, but we still need to be able to define - * our own version so that we can override the location of the errno - * location (e.g. when using the clone() system call with the CLONE_VM - * option). - */ - #undef LSS_ENTRYPOINT - #ifdef SYS_SYSCALL_ENTRYPOINT - static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { - void (**entrypoint)(void); - asm volatile(".bss\n" - ".align 8\n" - ".globl " SYS_SYSCALL_ENTRYPOINT "\n" - ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" - ".previous\n" - "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n" - : "=r"(entrypoint)); - return entrypoint; - } - - #define LSS_ENTRYPOINT \ - ".bss\n" \ - ".align 8\n" \ - ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ - ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ - ".previous\n" \ - "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \ - "mov 0(%%rcx), %%rcx\n" \ - "test %%rcx, %%rcx\n" \ - "jz 10001f\n" \ - "call *%%rcx\n" \ - "jmp 10002f\n" \ - "10001:syscall\n" \ - "10002:\n" - - #else - #define LSS_ENTRYPOINT "syscall\n" - #endif - - /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. - * We need to explicitly cast to an unsigned 64 bit type to avoid implicit - * sign extension. We can't cast pointers directly because those are - * 32 bits, and gcc will dump ugly warnings about casting from a pointer - * to an integer of a different size. - */ - #undef LSS_SYSCALL_ARG - #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) - #undef _LSS_RETURN - #define _LSS_RETURN(type, res, cast) \ - do { \ - if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ - LSS_ERRNO = -(res); \ - res = -1; \ - } \ - return (type)(cast)(res); \ - } while (0) - #undef LSS_RETURN - #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) - - #undef _LSS_BODY - #define _LSS_BODY(nr, type, name, cast, ...) \ - long long __res; \ - __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ - : "=a" (__res) \ - : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ - : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \ - _LSS_RETURN(type, __res, cast) - #undef LSS_BODY - #define LSS_BODY(nr, type, name, args...) \ - _LSS_BODY(nr, type, name, uintptr_t, ## args) - - #undef LSS_BODY_ASM0 - #undef LSS_BODY_ASM1 - #undef LSS_BODY_ASM2 - #undef LSS_BODY_ASM3 - #undef LSS_BODY_ASM4 - #undef LSS_BODY_ASM5 - #undef LSS_BODY_ASM6 - #define LSS_BODY_ASM0 - #define LSS_BODY_ASM1 LSS_BODY_ASM0 - #define LSS_BODY_ASM2 LSS_BODY_ASM1 - #define LSS_BODY_ASM3 LSS_BODY_ASM2 - #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" - #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" - #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" - - #undef LSS_BODY_CLOBBER0 - #undef LSS_BODY_CLOBBER1 - #undef LSS_BODY_CLOBBER2 - #undef LSS_BODY_CLOBBER3 - #undef LSS_BODY_CLOBBER4 - #undef LSS_BODY_CLOBBER5 - #undef LSS_BODY_CLOBBER6 - #define LSS_BODY_CLOBBER0 - #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0 - #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1 - #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2 - #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10", - #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8", - #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9", - - #undef LSS_BODY_ARG0 - #undef LSS_BODY_ARG1 - #undef LSS_BODY_ARG2 - #undef LSS_BODY_ARG3 - #undef LSS_BODY_ARG4 - #undef LSS_BODY_ARG5 - #undef LSS_BODY_ARG6 - #define LSS_BODY_ARG0() - #define LSS_BODY_ARG1(arg1) \ - LSS_BODY_ARG0(), "D" (arg1) - #define LSS_BODY_ARG2(arg1, arg2) \ - LSS_BODY_ARG1(arg1), "S" (arg2) - #define LSS_BODY_ARG3(arg1, arg2, arg3) \ - LSS_BODY_ARG2(arg1, arg2), "d" (arg3) - #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ - LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) - #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ - LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) - #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ - LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) - - #undef _syscall0 - #define _syscall0(type,name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(0, type, name); \ - } - #undef _syscall1 - #define _syscall1(type,name,type1,arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ - } - #undef _syscall2 - #define _syscall2(type,name,type1,arg1,type2,arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ - } - #undef _syscall3 - #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ - LSS_SYSCALL_ARG(arg3)); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ - LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\ - } - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ - LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ - LSS_SYSCALL_ARG(arg5)); \ - } - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ - LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ - LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\ - } - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long long __res; - { - __asm__ __volatile__(/* if (fn == NULL) - * return -EINVAL; - */ - "testq %4,%4\n" - "jz 1f\n" - - /* if (child_stack == NULL) - * return -EINVAL; - */ - "testq %5,%5\n" - "jz 1f\n" - - /* childstack -= 2*sizeof(void *); - */ - "subq $16,%5\n" - - /* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - "movq %7,8(%5)\n" - "movq %4,0(%5)\n" - - /* %rax = syscall(%rax = __NR_clone, - * %rdi = flags, - * %rsi = child_stack, - * %rdx = parent_tidptr, - * %r8 = new_tls, - * %r10 = child_tidptr) - */ - "movq %2,%%rax\n" - "movq %9,%%r8\n" - "movq %10,%%r10\n" - LSS_ENTRYPOINT - - /* if (%rax != 0) - * return; - */ - "testq %%rax,%%rax\n" - "jnz 1f\n" - - /* In the child. Terminate frame pointer chain. - */ - "xorq %%rbp,%%rbp\n" - - /* Call "fn(arg)". - */ - "popq %%rax\n" - "popq %%rdi\n" - "call *%%rax\n" - - /* Call _exit(%ebx). - */ - "movq %%rax,%%rdi\n" - "movq %3,%%rax\n" - LSS_ENTRYPOINT - - /* Return to parent. - */ - "1:\n" - : "=a" (__res) - : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), - "r"(LSS_SYSCALL_ARG(fn)), - "S"(LSS_SYSCALL_ARG(child_stack)), - "D"(LSS_SYSCALL_ARG(flags)), - "r"(LSS_SYSCALL_ARG(arg)), - "d"(LSS_SYSCALL_ARG(parent_tidptr)), - "r"(LSS_SYSCALL_ARG(newtls)), - "r"(LSS_SYSCALL_ARG(child_tidptr)) - : "rsp", "memory", "r8", "r10", "r11", "rcx"); - } - LSS_RETURN(int, __res); - } - LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) - - LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { - /* On x86-64, the kernel does not know how to return from - * a signal handler. Instead, it relies on user space to provide a - * restorer function that calls the rt_sigreturn() system call. - * Unfortunately, we cannot just reference the glibc version of this - * function, as glibc goes out of its way to make it inaccessible. - */ - long long res; - __asm__ __volatile__("jmp 2f\n" - ".align 16\n" - "1:movq %1,%%rax\n" - LSS_ENTRYPOINT - "2:leaq 1b(%%rip),%0\n" - : "=r" (res) - : "i" (__NR_rt_sigreturn)); - return (void (*)(void))(uintptr_t)res; - } - #elif defined(__ARM_ARCH_3__) - /* Most definitions of _syscallX() neglect to mark "memory" as being - * clobbered. This causes problems with compilers, that do a better job - * at optimizing across __asm__ calls. - * So, we just have to redefine all of the _syscallX() macros. - */ - #undef LSS_REG - #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a - #undef LSS_BODY - #define LSS_BODY(type,name,args...) \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ (__syscall(name) \ - : "=r"(__res_r0) : args : "lr", "memory"); \ - __res = __res_r0; \ - LSS_RETURN(type, __res) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(type, name); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ - } - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4)); \ - } - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4), "r"(__r5)); \ - } - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long __res; - { - register int __flags __asm__("r0") = flags; - register void *__stack __asm__("r1") = child_stack; - register void *__ptid __asm__("r2") = parent_tidptr; - register void *__tls __asm__("r3") = newtls; - register int *__ctid __asm__("r4") = child_tidptr; - __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) - * return -EINVAL; - */ - "cmp %2,#0\n" - "cmpne %3,#0\n" - "moveq %0,%1\n" - "beq 1f\n" - - /* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - "str %5,[%3,#-4]!\n" - "str %2,[%3,#-4]!\n" - - /* %r0 = syscall(%r0 = flags, - * %r1 = child_stack, - * %r2 = parent_tidptr, - * %r3 = newtls, - * %r4 = child_tidptr) - */ - __syscall(clone)"\n" - - /* if (%r0 != 0) - * return %r0; - */ - "movs %0,r0\n" - "bne 1f\n" - - /* In the child, now. Call "fn(arg)". - */ - "ldr r0,[sp, #4]\n" - "mov lr,pc\n" - "ldr pc,[sp]\n" - - /* Call _exit(%r0). - */ - __syscall(exit)"\n" - "1:\n" - : "=r" (__res) - : "i"(-EINVAL), - "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), - "r"(__ptid), "r"(__tls), "r"(__ctid) - : "cc", "lr", "memory"); - } - LSS_RETURN(int, __res); - } - #elif defined(__ARM_EABI__) - /* Most definitions of _syscallX() neglect to mark "memory" as being - * clobbered. This causes problems with compilers, that do a better job - * at optimizing across __asm__ calls. - * So, we just have to redefine all fo the _syscallX() macros. - */ - #undef LSS_REG - #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a - #undef LSS_BODY - #define LSS_BODY(type,name,args...) \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ("push {r7}\n" \ - "mov r7, %1\n" \ - "swi 0x0\n" \ - "pop {r7}\n" \ - : "=r"(__res_r0) \ - : "i"(__NR_##name) , ## args \ - : "lr", "memory"); \ - __res = __res_r0; \ - LSS_RETURN(type, __res) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(type, name); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ - } - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4)); \ - } - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4), "r"(__r5)); \ - } - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long __res; - { - register int __flags __asm__("r0") = flags; - register void *__stack __asm__("r1") = child_stack; - register void *__ptid __asm__("r2") = parent_tidptr; - register void *__tls __asm__("r3") = newtls; - register int *__ctid __asm__("r4") = child_tidptr; - __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) - * return -EINVAL; - */ - "cmp %2,#0\n" - "it ne\n" - "cmpne %3,#0\n" - "it eq\n" - "moveq %0,%1\n" - "beq 1f\n" - - /* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - "str %5,[%3,#-4]!\n" - "str %2,[%3,#-4]!\n" - - /* %r0 = syscall(%r0 = flags, - * %r1 = child_stack, - * %r2 = parent_tidptr, - * %r3 = newtls, - * %r4 = child_tidptr) - */ - "mov r7, %9\n" - "swi 0x0\n" - - /* if (%r0 != 0) - * return %r0; - */ - "movs %0,r0\n" - "bne 1f\n" - - /* In the child, now. Call "fn(arg)". - */ - "ldr r0,[sp, #4]\n" - - /* When compiling for Thumb-2 the "MOV LR,PC" here - * won't work because it loads PC+4 into LR, - * whereas the LDR is a 4-byte instruction. - * This results in the child thread always - * crashing with an "Illegal Instruction" when it - * returned into the middle of the LDR instruction - * The instruction sequence used instead was - * recommended by - * "https://wiki.edubuntu.org/ARM/Thumb2PortingHowto#Quick_Reference". - */ - #ifdef __thumb2__ - "ldr r7,[sp]\n" - "blx r7\n" - #else - "mov lr,pc\n" - "ldr pc,[sp]\n" - #endif - - /* Call _exit(%r0). - */ - "mov r7, %10\n" - "swi 0x0\n" - "1:\n" - : "=r" (__res) - : "i"(-EINVAL), - "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), - "r"(__ptid), "r"(__tls), "r"(__ctid), - "i"(__NR_clone), "i"(__NR_exit) - : "cc", "r7", "lr", "memory"); - } - LSS_RETURN(int, __res); - } - #elif defined(__aarch64__) - /* Most definitions of _syscallX() neglect to mark "memory" as being - * clobbered. This causes problems with compilers, that do a better job - * at optimizing across __asm__ calls. - * So, we just have to redefine all of the _syscallX() macros. - */ - #undef LSS_REG - #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a - #undef LSS_BODY - #define LSS_BODY(type,name,args...) \ - register int64_t __res_x0 __asm__("x0"); \ - int64_t __res; \ - __asm__ __volatile__ ("mov x8, %1\n" \ - "svc 0x0\n" \ - : "=r"(__res_x0) \ - : "i"(__NR_##name) , ## args \ - : "x8", "memory"); \ - __res = __res_x0; \ - LSS_RETURN(type, __res) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(type, name); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ - } - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4)); \ - } - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ - LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ - LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ - "r"(__r4), "r"(__r5)); \ - } - - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - int64_t __res; - { - register uint64_t __flags __asm__("x0") = flags; - register void *__stack __asm__("x1") = child_stack; - register void *__ptid __asm__("x2") = parent_tidptr; - register void *__tls __asm__("x3") = newtls; - register int *__ctid __asm__("x4") = child_tidptr; - __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - "stp %1, %4, [%2, #-16]!\n" - - /* %x0 = syscall(%x0 = flags, - * %x1 = child_stack, - * %x2 = parent_tidptr, - * %x3 = newtls, - * %x4 = child_tidptr) - */ - "mov x8, %8\n" - "svc 0x0\n" - - /* if (%r0 != 0) - * return %r0; - */ - "mov %0, x0\n" - "cbnz x0, 1f\n" - - /* In the child, now. Call "fn(arg)". - */ - "ldp x1, x0, [sp], #16\n" - "blr x1\n" - - /* Call _exit(%r0). - */ - "mov x8, %9\n" - "svc 0x0\n" - "1:\n" - : "=r" (__res) - : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), - "r"(__ptid), "r"(__tls), "r"(__ctid), - "i"(__NR_clone), "i"(__NR_exit) - : "cc", "x8", "memory"); - } - LSS_RETURN(int, __res); - } - #elif defined(__mips__) - #undef LSS_REG - #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ - (unsigned long)(a) - #undef LSS_BODY - #undef LSS_SYSCALL_CLOBBERS - #if _MIPS_SIM == _MIPS_SIM_ABI32 - #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \ - "$11", "$12", "$13", "$14", "$15", \ - "$24", "$25", "hi", "lo", "memory" - #else - #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \ - "$13", "$14", "$15", "$24", "$25", \ - "hi", "lo", "memory" - #endif - #define LSS_BODY(type,name,r7,...) \ - register unsigned long __v0 __asm__("$2") = __NR_##name; \ - __asm__ __volatile__ ("syscall\n" \ - : "=r"(__v0), r7 (__r7) \ - : "0"(__v0), ##__VA_ARGS__ \ - : LSS_SYSCALL_CLOBBERS); \ - LSS_RETURN(type, __v0, __r7) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - register unsigned long __r7 __asm__("$7"); \ - LSS_BODY(type, name, "=r"); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - register unsigned long __r7 __asm__("$7"); \ - LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - register unsigned long __r7 __asm__("$7"); \ - LSS_REG(4, arg1); LSS_REG(5, arg2); \ - LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - register unsigned long __r7 __asm__("$7"); \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ - } - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_REG(7, arg4); \ - LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ - } - #undef _syscall5 - #if _MIPS_SIM == _MIPS_SIM_ABI32 - /* The old 32bit MIPS system call API passes the fifth and sixth argument - * on the stack, whereas the new APIs use registers "r8" and "r9". - */ - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_REG(7, arg4); \ - register unsigned long __v0 __asm__("$2") = __NR_##name; \ - __asm__ __volatile__ (".set noreorder\n" \ - "subu $29, 32\n" \ - "sw %5, 16($29)\n" \ - "syscall\n" \ - "addiu $29, 32\n" \ - ".set reorder\n" \ - : "+r"(__v0), "+r" (__r7) \ - : "r"(__r4), "r"(__r5), \ - "r"(__r6), "r" ((unsigned long)arg5) \ - : "$8", "$9", "$10", "$11", "$12", \ - "$13", "$14", "$15", "$24", "$25", \ - "memory"); \ - LSS_RETURN(type, __v0, __r7); \ - } - #else - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_REG(7, arg4); LSS_REG(8, arg5); \ - LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ - "r"(__r8)); \ - } - #endif - #undef _syscall6 - #if _MIPS_SIM == _MIPS_SIM_ABI32 - /* The old 32bit MIPS system call API passes the fifth and sixth argument - * on the stack, whereas the new APIs use registers "r8" and "r9". - */ - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_REG(7, arg4); \ - register unsigned long __v0 __asm__("$2") = __NR_##name; \ - __asm__ __volatile__ (".set noreorder\n" \ - "subu $29, 32\n" \ - "sw %5, 16($29)\n" \ - "sw %6, 20($29)\n" \ - "syscall\n" \ - "addiu $29, 32\n" \ - ".set reorder\n" \ - : "+r"(__v0), "+r" (__r7) \ - : "r"(__r4), "r"(__r5), \ - "r"(__r6), "r" ((unsigned long)arg5), \ - "r" ((unsigned long)arg6) \ - : "$8", "$9", "$10", "$11", "$12", \ - "$13", "$14", "$15", "$24", "$25", \ - "memory"); \ - LSS_RETURN(type, __v0, __r7); \ - } - #else - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5,type6 arg6) { \ - LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ - LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ - LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ - "r"(__r8), "r"(__r9)); \ - } - #endif - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - register unsigned long __v0 __asm__("$2") = -EINVAL; - register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; - { - register int __flags __asm__("$4") = flags; - register void *__stack __asm__("$5") = child_stack; - register void *__ptid __asm__("$6") = parent_tidptr; - register int *__ctid __asm__("$8") = child_tidptr; - __asm__ __volatile__( - #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 - "subu $29,24\n" - #elif _MIPS_SIM == _MIPS_SIM_NABI32 - "sub $29,16\n" - #else - "dsubu $29,16\n" - #endif - - /* if (fn == NULL || child_stack == NULL) - * return -EINVAL; - */ - "beqz %4,1f\n" - "beqz %5,1f\n" - - /* Push "arg" and "fn" onto the stack that will be - * used by the child. - */ - #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 - "subu %5,32\n" - "sw %4,0(%5)\n" - "sw %7,4(%5)\n" - #elif _MIPS_SIM == _MIPS_SIM_NABI32 - "sub %5,32\n" - "sw %4,0(%5)\n" - "sw %7,8(%5)\n" - #else - "dsubu %5,32\n" - "sd %4,0(%5)\n" - "sd %7,8(%5)\n" - #endif - - /* $7 = syscall($4 = flags, - * $5 = child_stack, - * $6 = parent_tidptr, - * $7 = newtls, - * $8 = child_tidptr) - */ - "li $2,%2\n" - "syscall\n" - - /* if ($7 != 0) - * return $2; - */ - "bnez $7,1f\n" - "bnez $2,1f\n" - - /* In the child, now. Call "fn(arg)". - */ - #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 - "lw $25,0($29)\n" - "lw $4,4($29)\n" - #elif _MIPS_SIM == _MIPS_SIM_NABI32 - "lw $25,0($29)\n" - "lw $4,8($29)\n" - #else - "ld $25,0($29)\n" - "ld $4,8($29)\n" - #endif - "jalr $25\n" - - /* Call _exit($2) - */ - "move $4,$2\n" - "li $2,%3\n" - "syscall\n" - - "1:\n" - #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 - "addu $29, 24\n" - #elif _MIPS_SIM == _MIPS_SIM_NABI32 - "add $29, 16\n" - #else - "daddu $29,16\n" - #endif - : "+r" (__v0), "+r" (__r7) - : "i"(__NR_clone), "i"(__NR_exit), "r"(fn), - "r"(__stack), "r"(__flags), "r"(arg), - "r"(__ptid), "r"(__ctid) - : "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$24", "$25", "memory"); - } - LSS_RETURN(int, __v0, __r7); - } - #elif defined (__PPC__) - #undef LSS_LOADARGS_0 - #define LSS_LOADARGS_0(name, dummy...) \ - __sc_0 = __NR_##name - #undef LSS_LOADARGS_1 - #define LSS_LOADARGS_1(name, arg1) \ - LSS_LOADARGS_0(name); \ - __sc_3 = (unsigned long) (arg1) - #undef LSS_LOADARGS_2 - #define LSS_LOADARGS_2(name, arg1, arg2) \ - LSS_LOADARGS_1(name, arg1); \ - __sc_4 = (unsigned long) (arg2) - #undef LSS_LOADARGS_3 - #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ - LSS_LOADARGS_2(name, arg1, arg2); \ - __sc_5 = (unsigned long) (arg3) - #undef LSS_LOADARGS_4 - #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ - LSS_LOADARGS_3(name, arg1, arg2, arg3); \ - __sc_6 = (unsigned long) (arg4) - #undef LSS_LOADARGS_5 - #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ - LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ - __sc_7 = (unsigned long) (arg5) - #undef LSS_LOADARGS_6 - #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ - LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ - __sc_8 = (unsigned long) (arg6) - #undef LSS_ASMINPUT_0 - #define LSS_ASMINPUT_0 "0" (__sc_0) - #undef LSS_ASMINPUT_1 - #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) - #undef LSS_ASMINPUT_2 - #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) - #undef LSS_ASMINPUT_3 - #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) - #undef LSS_ASMINPUT_4 - #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) - #undef LSS_ASMINPUT_5 - #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) - #undef LSS_ASMINPUT_6 - #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) - #undef LSS_BODY - #define LSS_BODY(nr, type, name, args...) \ - long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - LSS_LOADARGS_##nr(name, args); \ - __asm__ __volatile__ \ - ("sc\n\t" \ - "mfcr %0" \ - : "=&r" (__sc_0), \ - "=&r" (__sc_3), "=&r" (__sc_4), \ - "=&r" (__sc_5), "=&r" (__sc_6), \ - "=&r" (__sc_7), "=&r" (__sc_8) \ - : LSS_ASMINPUT_##nr \ - : "cr0", "ctr", "memory", \ - "r9", "r10", "r11", "r12"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - LSS_RETURN(type, __sc_ret, __sc_err) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(0, type, name); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_BODY(1, type, name, arg1); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_BODY(2, type, name, arg1, arg2); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_BODY(3, type, name, arg1, arg2, arg3); \ - } - #undef _syscall4 - #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ - } - #undef _syscall5 - #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4, type5, arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ - } - #undef _syscall6 - #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4, type5, arg5, type6, arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ - } - /* clone function adapted from glibc 2.3.6 clone.S */ - /* TODO(csilvers): consider wrapping some args up in a struct, like we - * do for i386's _syscall6, so we can compile successfully on gcc 2.95 - */ - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long __ret, __err; - { - register int (*__fn)(void *) __asm__ ("r8") = fn; - register void *__cstack __asm__ ("r4") = child_stack; - register int __flags __asm__ ("r3") = flags; - register void * __arg __asm__ ("r9") = arg; - register int * __ptidptr __asm__ ("r5") = parent_tidptr; - register void * __newtls __asm__ ("r6") = newtls; - register int * __ctidptr __asm__ ("r7") = child_tidptr; - __asm__ __volatile__( - /* check for fn == NULL - * and child_stack == NULL - */ - "cmpwi cr0, %6, 0\n\t" - "cmpwi cr1, %7, 0\n\t" - "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" - "beq- cr0, 1f\n\t" - - /* set up stack frame for child */ - "clrrwi %7, %7, 4\n\t" - "li 0, 0\n\t" - "stwu 0, -16(%7)\n\t" - - /* fn, arg, child_stack are saved across the syscall: r28-30 */ - "mr 28, %6\n\t" - "mr 29, %7\n\t" - "mr 27, %9\n\t" - - /* syscall */ - "li 0, %4\n\t" - /* flags already in r3 - * child_stack already in r4 - * ptidptr already in r5 - * newtls already in r6 - * ctidptr already in r7 - */ - "sc\n\t" - - /* Test if syscall was successful */ - "cmpwi cr1, 3, 0\n\t" - "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" - "bne- cr1, 1f\n\t" - - /* Do the function call */ - "mtctr 28\n\t" - "mr 3, 27\n\t" - "bctrl\n\t" - - /* Call _exit(r3) */ - "li 0, %5\n\t" - "sc\n\t" - - /* Return to parent */ - "1:\n" - "mfcr %1\n\t" - "mr %0, 3\n\t" - : "=r" (__ret), "=r" (__err) - : "0" (-1), "1" (EINVAL), - "i" (__NR_clone), "i" (__NR_exit), - "r" (__fn), "r" (__cstack), "r" (__flags), - "r" (__arg), "r" (__ptidptr), "r" (__newtls), - "r" (__ctidptr) - : "cr0", "cr1", "memory", "ctr", - "r0", "r29", "r27", "r28"); - } - LSS_RETURN(int, __ret, __err); - } - #elif defined(__s390__) - #undef LSS_REG - #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a - #undef LSS_BODY - #define LSS_BODY(type, name, args...) \ - register unsigned long __nr __asm__("r1") \ - = (unsigned long)(__NR_##name); \ - register long __res_r2 __asm__("r2"); \ - long __res; \ - __asm__ __volatile__ \ - ("svc 0\n\t" \ - : "=d"(__res_r2) \ - : "d"(__nr), ## args \ - : "memory"); \ - __res = __res_r2; \ - LSS_RETURN(type, __res) - #undef _syscall0 - #define _syscall0(type, name) \ - type LSS_NAME(name)(void) { \ - LSS_BODY(type, name); \ - } - #undef _syscall1 - #define _syscall1(type, name, type1, arg1) \ - type LSS_NAME(name)(type1 arg1) { \ - LSS_REG(2, arg1); \ - LSS_BODY(type, name, "0"(__r2)); \ - } - #undef _syscall2 - #define _syscall2(type, name, type1, arg1, type2, arg2) \ - type LSS_NAME(name)(type1 arg1, type2 arg2) { \ - LSS_REG(2, arg1); LSS_REG(3, arg2); \ - LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \ - } - #undef _syscall3 - #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ - LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ - LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \ - } - #undef _syscall4 - #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ - type4 arg4) { \ - LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ - LSS_REG(5, arg4); \ - LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ - "d"(__r5)); \ - } - #undef _syscall5 - #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4, type5, arg5) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ - type4 arg4, type5 arg5) { \ - LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ - LSS_REG(5, arg4); LSS_REG(6, arg5); \ - LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ - "d"(__r5), "d"(__r6)); \ - } - #undef _syscall6 - #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ - type4, arg4, type5, arg5, type6, arg6) \ - type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ - type4 arg4, type5 arg5, type6 arg6) { \ - LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ - LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \ - LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ - "d"(__r5), "d"(__r6), "d"(__r7)); \ - } - LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, - int flags, void *arg, int *parent_tidptr, - void *newtls, int *child_tidptr) { - long __ret; - { - register int (*__fn)(void *) __asm__ ("r1") = fn; - register void *__cstack __asm__ ("r2") = child_stack; - register int __flags __asm__ ("r3") = flags; - register void *__arg __asm__ ("r0") = arg; - register int *__ptidptr __asm__ ("r4") = parent_tidptr; - register void *__newtls __asm__ ("r6") = newtls; - register int *__ctidptr __asm__ ("r5") = child_tidptr; - __asm__ __volatile__ ( - #ifndef __s390x__ - /* arg already in r0 */ - "ltr %4, %4\n\t" /* check fn, which is already in r1 */ - "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ - "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */ - "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ - /* flags already in r3 */ - /* parent_tidptr already in r4 */ - /* child_tidptr already in r5 */ - /* newtls already in r6 */ - "svc %2\n\t" /* invoke clone syscall */ - "ltr %0,%%r2\n\t" /* load return code into __ret and test */ - "jnz 1f\n\t" /* return to parent if non-zero */ - /* start child thread */ - "lr %%r2, %7\n\t" /* set first parameter to void *arg */ - "ahi %%r15, -96\n\t" /* make room on the stack for the save area */ - "xc 0(4,%%r15), 0(%%r15)\n\t" - "basr %%r14, %4\n\t" /* jump to fn */ - "svc %3\n" /* invoke exit syscall */ - "1:\n" - #else - /* arg already in r0 */ - "ltgr %4, %4\n\t" /* check fn, which is already in r1 */ - "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ - "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */ - "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ - /* flags already in r3 */ - /* parent_tidptr already in r4 */ - /* child_tidptr already in r5 */ - /* newtls already in r6 */ - "svc %2\n\t" /* invoke clone syscall */ - "ltgr %0, %%r2\n\t" /* load return code into __ret and test */ - "jnz 1f\n\t" /* return to parent if non-zero */ - /* start child thread */ - "lgr %%r2, %7\n\t" /* set first parameter to void *arg */ - "aghi %%r15, -160\n\t" /* make room on the stack for the save area */ - "xc 0(8,%%r15), 0(%%r15)\n\t" - "basr %%r14, %4\n\t" /* jump to fn */ - "svc %3\n" /* invoke exit syscall */ - "1:\n" - #endif - : "=r" (__ret) - : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit), - "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg), - "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr) - : "cc", "r14", "memory" - ); - } - LSS_RETURN(int, __ret); - } - #endif - #define __NR__exit __NR_exit - #define __NR__gettid __NR_gettid - #define __NR__mremap __NR_mremap - LSS_INLINE _syscall1(void *, brk, void *, e) - LSS_INLINE _syscall1(int, chdir, const char *,p) - LSS_INLINE _syscall1(int, close, int, f) - LSS_INLINE _syscall2(int, clock_getres, int, c, - struct kernel_timespec*, t) - LSS_INLINE _syscall2(int, clock_gettime, int, c, - struct kernel_timespec*, t) - LSS_INLINE _syscall1(int, dup, int, f) - #if !defined(__aarch64__) - // The dup2 syscall has been deprecated on aarch64. We polyfill it below. - LSS_INLINE _syscall2(int, dup2, int, s, - int, d) - #endif - LSS_INLINE _syscall3(int, execve, const char*, f, - const char*const*,a,const char*const*, e) - LSS_INLINE _syscall1(int, _exit, int, e) - LSS_INLINE _syscall1(int, exit_group, int, e) - LSS_INLINE _syscall3(int, fcntl, int, f, - int, c, long, a) - #if !defined(__aarch64__) - // The fork syscall has been deprecated on aarch64. We polyfill it below. - LSS_INLINE _syscall0(pid_t, fork) - #endif - LSS_INLINE _syscall2(int, fstat, int, f, - struct kernel_stat*, b) - LSS_INLINE _syscall2(int, fstatfs, int, f, - struct kernel_statfs*, b) - #if defined(__x86_64__) - /* Need to make sure off_t isn't truncated to 32-bits under x32. */ - LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) { - LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l)); - } - #else - LSS_INLINE _syscall2(int, ftruncate, int, f, - off_t, l) - #endif - LSS_INLINE _syscall4(int, futex, int*, a, - int, o, int, v, - struct kernel_timespec*, t) - LSS_INLINE _syscall3(int, getdents, int, f, - struct kernel_dirent*, d, int, c) - LSS_INLINE _syscall3(int, getdents64, int, f, - struct kernel_dirent64*, d, int, c) - LSS_INLINE _syscall0(gid_t, getegid) - LSS_INLINE _syscall0(uid_t, geteuid) - #if !defined(__aarch64__) - // The getgprp syscall has been deprecated on aarch64. - LSS_INLINE _syscall0(pid_t, getpgrp) - #endif - LSS_INLINE _syscall0(pid_t, getpid) - LSS_INLINE _syscall0(pid_t, getppid) - LSS_INLINE _syscall2(int, getpriority, int, a, - int, b) - LSS_INLINE _syscall3(int, getresgid, gid_t *, r, - gid_t *, e, gid_t *, s) - LSS_INLINE _syscall3(int, getresuid, uid_t *, r, - uid_t *, e, uid_t *, s) -#if !defined(__ARM_EABI__) - LSS_INLINE _syscall2(int, getrlimit, int, r, - struct kernel_rlimit*, l) -#endif - LSS_INLINE _syscall1(pid_t, getsid, pid_t, p) - LSS_INLINE _syscall0(pid_t, _gettid) - LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t, - void*, tz) - LSS_INLINE _syscall5(int, setxattr, const char *,p, - const char *, n, const void *,v, - size_t, s, int, f) - LSS_INLINE _syscall5(int, lsetxattr, const char *,p, - const char *, n, const void *,v, - size_t, s, int, f) - LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p, - const char *, n, void *, v, size_t, s) - LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p, - const char *, n, void *, v, size_t, s) - LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p, - char *, l, size_t, s) - LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, - char *, l, size_t, s) - LSS_INLINE _syscall3(int, ioctl, int, d, - int, r, void *, a) - LSS_INLINE _syscall2(int, ioprio_get, int, which, - int, who) - LSS_INLINE _syscall3(int, ioprio_set, int, which, - int, who, int, ioprio) - LSS_INLINE _syscall2(int, kill, pid_t, p, - int, s) - #if defined(__x86_64__) - /* Need to make sure off_t isn't truncated to 32-bits under x32. */ - LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) { - _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), - LSS_SYSCALL_ARG(w)); - } - #else - LSS_INLINE _syscall3(off_t, lseek, int, f, - off_t, o, int, w) - #endif - LSS_INLINE _syscall2(int, munmap, void*, s, - size_t, l) - LSS_INLINE _syscall6(long, move_pages, pid_t, p, - unsigned long, n, void **,g, int *, d, - int *, s, int, f) - LSS_INLINE _syscall3(int, mprotect, const void *,a, - size_t, l, int, p) - LSS_INLINE _syscall5(void*, _mremap, void*, o, - size_t, os, size_t, ns, - unsigned long, f, void *, a) - #if !defined(__aarch64__) - // The open and poll syscalls have been deprecated on aarch64. We polyfill - // them below. - LSS_INLINE _syscall3(int, open, const char*, p, - int, f, int, m) - LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u, - unsigned int, n, int, t) - #endif - LSS_INLINE _syscall5(int, prctl, int, option, - unsigned long, arg2, - unsigned long, arg3, - unsigned long, arg4, - unsigned long, arg5) - LSS_INLINE _syscall4(long, ptrace, int, r, - pid_t, p, void *, a, void *, d) - #if defined(__NR_quotactl) - // Defined on x86_64 / i386 only - LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special, - int, id, caddr_t, addr) - #endif - LSS_INLINE _syscall3(ssize_t, read, int, f, - void *, b, size_t, c) - #if !defined(__aarch64__) - // The readlink syscall has been deprecated on aarch64. We polyfill below. - LSS_INLINE _syscall3(int, readlink, const char*, p, - char*, b, size_t, s) - #endif - LSS_INLINE _syscall4(int, rt_sigaction, int, s, - const struct kernel_sigaction*, a, - struct kernel_sigaction*, o, size_t, c) - LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s, - size_t, c) - LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, - const struct kernel_sigset_t*, s, - struct kernel_sigset_t*, o, size_t, c) - LSS_INLINE _syscall2(int, rt_sigsuspend, - const struct kernel_sigset_t*, s, size_t, c) - LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p, - unsigned int, l, unsigned long *, m) - LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p, - unsigned int, l, unsigned long *, m) - LSS_INLINE _syscall0(int, sched_yield) - LSS_INLINE _syscall1(long, set_tid_address, int *, t) - LSS_INLINE _syscall1(int, setfsgid, gid_t, g) - LSS_INLINE _syscall1(int, setfsuid, uid_t, u) - LSS_INLINE _syscall1(int, setuid, uid_t, u) - LSS_INLINE _syscall1(int, setgid, gid_t, g) - LSS_INLINE _syscall2(int, setpgid, pid_t, p, - pid_t, g) - LSS_INLINE _syscall3(int, setpriority, int, a, - int, b, int, p) - LSS_INLINE _syscall3(int, setresgid, gid_t, r, - gid_t, e, gid_t, s) - LSS_INLINE _syscall3(int, setresuid, uid_t, r, - uid_t, e, uid_t, s) - LSS_INLINE _syscall2(int, setrlimit, int, r, - const struct kernel_rlimit*, l) - LSS_INLINE _syscall0(pid_t, setsid) - LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, - const stack_t*, o) - #if defined(__NR_sigreturn) - LSS_INLINE _syscall1(int, sigreturn, unsigned long, u) - #endif - #if !defined(__aarch64__) - // The stat syscall has been deprecated on aarch64. We polyfill it below. - LSS_INLINE _syscall2(int, stat, const char*, f, - struct kernel_stat*, b) - #endif - LSS_INLINE _syscall2(int, statfs, const char*, f, - struct kernel_statfs*, b) - LSS_INLINE _syscall3(int, tgkill, pid_t, p, - pid_t, t, int, s) - LSS_INLINE _syscall2(int, tkill, pid_t, p, - int, s) - #if !defined(__aarch64__) - // The unlink syscall has been deprecated on aarch64. We polyfill it below. - LSS_INLINE _syscall1(int, unlink, const char*, f) - #endif - LSS_INLINE _syscall3(ssize_t, write, int, f, - const void *, b, size_t, c) - LSS_INLINE _syscall3(ssize_t, writev, int, f, - const struct kernel_iovec*, v, size_t, c) - #if defined(__NR_getcpu) - LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, - unsigned *, node, void *, unused) - #endif - #if defined(__x86_64__) || \ - (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) - LSS_INLINE _syscall3(int, recvmsg, int, s, - struct kernel_msghdr*, m, int, f) - LSS_INLINE _syscall3(int, sendmsg, int, s, - const struct kernel_msghdr*, m, int, f) - LSS_INLINE _syscall6(int, sendto, int, s, - const void*, m, size_t, l, - int, f, - const struct kernel_sockaddr*, a, int, t) - LSS_INLINE _syscall2(int, shutdown, int, s, - int, h) - LSS_INLINE _syscall3(int, socket, int, d, - int, t, int, p) - LSS_INLINE _syscall4(int, socketpair, int, d, - int, t, int, p, int*, s) - #endif - #if defined(__NR_fadvise64) - #if defined(__x86_64__) - /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ - LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len, - int advice) { - LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset), - (uint64_t)(len), LSS_SYSCALL_ARG(advice)); - } - #else - LSS_INLINE _syscall4(int, fadvise64, - int, fd, loff_t, offset, loff_t, len, int, advice) - #endif - #elif defined(__i386__) - #define __NR__fadvise64_64 __NR_fadvise64_64 - LSS_INLINE _syscall6(int, _fadvise64_64, int, fd, - unsigned, offset_lo, unsigned, offset_hi, - unsigned, len_lo, unsigned, len_hi, - int, advice) - - LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, - loff_t len, int advice) { - return LSS_NAME(_fadvise64_64)(fd, - (unsigned)offset, (unsigned)(offset >>32), - (unsigned)len, (unsigned)(len >> 32), - advice); - } - - #elif defined(__s390__) && !defined(__s390x__) - #define __NR__fadvise64_64 __NR_fadvise64_64 - struct kernel_fadvise64_64_args { - int fd; - long long offset; - long long len; - int advice; - }; - - LSS_INLINE _syscall1(int, _fadvise64_64, - struct kernel_fadvise64_64_args *args) - - LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, - loff_t len, int advice) { - struct kernel_fadvise64_64_args args = { fd, offset, len, advice }; - return LSS_NAME(_fadvise64_64)(&args); - } - #endif - #if defined(__NR_fallocate) - #if defined(__x86_64__) - /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ - LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset, - loff_t len) { - LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode), - (uint64_t)(offset), (uint64_t)(len)); - } - #elif defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) - #define __NR__fallocate __NR_fallocate - LSS_INLINE _syscall6(int, _fallocate, int, fd, - int, mode, - unsigned, offset_lo, unsigned, offset_hi, - unsigned, len_lo, unsigned, len_hi) - - LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode, - loff_t offset, loff_t len) { - union { loff_t off; unsigned w[2]; } o = { offset }, l = { len }; - return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]); - } - #else - LSS_INLINE _syscall4(int, fallocate, - int, f, int, mode, loff_t, offset, loff_t, len) - #endif - #endif - #if defined(__x86_64__) || defined(__s390x__) - LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, - gid_t *egid, - gid_t *sgid) { - return LSS_NAME(getresgid)(rgid, egid, sgid); - } - - LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, - uid_t *euid, - uid_t *suid) { - return LSS_NAME(getresuid)(ruid, euid, suid); - } - LSS_INLINE _syscall4(int, newfstatat, int, d, - const char *, p, - struct kernel_stat*, b, int, f) - - LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { - return LSS_NAME(setfsgid)(gid); - } - - LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { - return LSS_NAME(setfsuid)(uid); - } - - LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { - return LSS_NAME(setresgid)(rgid, egid, sgid); - } - - LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { - return LSS_NAME(setresuid)(ruid, euid, suid); - } - - LSS_INLINE int LSS_NAME(sigaction)(int signum, - const struct kernel_sigaction *act, - struct kernel_sigaction *oldact) { - #if defined(__x86_64__) - /* On x86_64, the kernel requires us to always set our own - * SA_RESTORER in order to be able to return from a signal handler. - * This function must have a "magic" signature that the "gdb" - * (and maybe the kernel?) can recognize. - */ - if (act != NULL && !(act->sa_flags & SA_RESTORER)) { - struct kernel_sigaction a = *act; - a.sa_flags |= SA_RESTORER; - a.sa_restorer = LSS_NAME(restore_rt)(); - return LSS_NAME(rt_sigaction)(signum, &a, oldact, - (KERNEL_NSIG+7)/8); - } else - #endif - return LSS_NAME(rt_sigaction)(signum, act, oldact, - (KERNEL_NSIG+7)/8); - } - - LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { - return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); - } - - LSS_INLINE int LSS_NAME(sigprocmask)(int how, - const struct kernel_sigset_t *set, - struct kernel_sigset_t *oldset) { - return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); - } - - LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { - return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); - } - #endif - #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ - defined(__ARM_EABI__) || defined(__aarch64__) || \ - (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) || \ - defined(__s390__) - LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, - int*, s, int, o, - struct kernel_rusage*, r) - - LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){ - return LSS_NAME(wait4)(pid, status, options, 0); - } - #endif - #if defined(__NR_openat) - LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) - #endif - #if defined(__NR_unlinkat) - LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f) - #endif - #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ - (defined(__s390__) && !defined(__s390x__)) - #define __NR__getresgid32 __NR_getresgid32 - #define __NR__getresuid32 __NR_getresuid32 - #define __NR__setfsgid32 __NR_setfsgid32 - #define __NR__setfsuid32 __NR_setfsuid32 - #define __NR__setresgid32 __NR_setresgid32 - #define __NR__setresuid32 __NR_setresuid32 -#if defined(__ARM_EABI__) - LSS_INLINE _syscall2(int, ugetrlimit, int, r, - struct kernel_rlimit*, l) -#endif - LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r, - gid_t *, e, gid_t *, s) - LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r, - uid_t *, e, uid_t *, s) - LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f) - LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f) - LSS_INLINE _syscall3(int, _setresgid32, gid_t, r, - gid_t, e, gid_t, s) - LSS_INLINE _syscall3(int, _setresuid32, uid_t, r, - uid_t, e, uid_t, s) - - LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, - gid_t *egid, - gid_t *sgid) { - int rc; - if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) { - return EFAULT; - } - // Clear the high bits first, since getresgid only sets 16 bits - *rgid = *egid = *sgid = 0; - rc = LSS_NAME(getresgid)(rgid, egid, sgid); - } - return rc; - } - - LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, - uid_t *euid, - uid_t *suid) { - int rc; - if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) { - return EFAULT; - } - // Clear the high bits first, since getresuid only sets 16 bits - *ruid = *euid = *suid = 0; - rc = LSS_NAME(getresuid)(ruid, euid, suid); - } - return rc; - } - - LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { - int rc; - if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((unsigned int)gid & ~0xFFFFu) { - rc = EINVAL; - } else { - rc = LSS_NAME(setfsgid)(gid); - } - } - return rc; - } - - LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { - int rc; - if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((unsigned int)uid & ~0xFFFFu) { - rc = EINVAL; - } else { - rc = LSS_NAME(setfsuid)(uid); - } - } - return rc; - } - - LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { - int rc; - if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((unsigned int)rgid & ~0xFFFFu || - (unsigned int)egid & ~0xFFFFu || - (unsigned int)sgid & ~0xFFFFu) { - rc = EINVAL; - } else { - rc = LSS_NAME(setresgid)(rgid, egid, sgid); - } - } - return rc; - } - - LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { - int rc; - if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 && - LSS_ERRNO == ENOSYS) { - if ((unsigned int)ruid & ~0xFFFFu || - (unsigned int)euid & ~0xFFFFu || - (unsigned int)suid & ~0xFFFFu) { - rc = EINVAL; - } else { - rc = LSS_NAME(setresuid)(ruid, euid, suid); - } - } - return rc; - } - #endif - LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { - memset(&set->sig, 0, sizeof(set->sig)); - return 0; - } - - LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { - memset(&set->sig, -1, sizeof(set->sig)); - return 0; - } - - LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, - int signum) { - if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { - LSS_ERRNO = EINVAL; - return -1; - } else { - set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] - |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0]))); - return 0; - } - } - - LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, - int signum) { - if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { - LSS_ERRNO = EINVAL; - return -1; - } else { - set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] - &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0])))); - return 0; - } - } - - LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set, - int signum) { - if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { - LSS_ERRNO = EINVAL; - return -1; - } else { - return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] & - (1UL << ((signum - 1) % (8*sizeof(set->sig[0]))))); - } - } - #if defined(__i386__) || \ - defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ - (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ - defined(__PPC__) || \ - (defined(__s390__) && !defined(__s390x__)) - #define __NR__sigaction __NR_sigaction - #define __NR__sigpending __NR_sigpending - #define __NR__sigprocmask __NR_sigprocmask - #define __NR__sigsuspend __NR_sigsuspend - #define __NR__socketcall __NR_socketcall - LSS_INLINE _syscall2(int, fstat64, int, f, - struct kernel_stat64 *, b) - LSS_INLINE _syscall5(int, _llseek, uint, fd, - unsigned long, hi, unsigned long, lo, - loff_t *, res, uint, wh) -#if defined(__s390__) && !defined(__s390x__) - /* On s390, mmap2() arguments are passed in memory. */ - LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d, - off_t o) { - unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, - (unsigned long) p, (unsigned long) f, - (unsigned long) d, (unsigned long) o }; - LSS_REG(2, buf); - LSS_BODY(void*, mmap2, "0"(__r2)); - } -#else - #define __NR__mmap2 __NR_mmap2 - LSS_INLINE _syscall6(void*, _mmap2, void*, s, - size_t, l, int, p, - int, f, int, d, - off_t, o) -#endif - LSS_INLINE _syscall3(int, _sigaction, int, s, - const struct kernel_old_sigaction*, a, - struct kernel_old_sigaction*, o) - LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s) - LSS_INLINE _syscall3(int, _sigprocmask, int, h, - const unsigned long*, s, - unsigned long*, o) - #ifdef __PPC__ - LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s) - #else - LSS_INLINE _syscall3(int, _sigsuspend, const void*, a, - int, b, - unsigned long, s) - #endif - LSS_INLINE _syscall2(int, stat64, const char *, p, - struct kernel_stat64 *, b) - - LSS_INLINE int LSS_NAME(sigaction)(int signum, - const struct kernel_sigaction *act, - struct kernel_sigaction *oldact) { - int old_errno = LSS_ERRNO; - int rc; - struct kernel_sigaction a; - if (act != NULL) { - a = *act; - #ifdef __i386__ - /* On i386, the kernel requires us to always set our own - * SA_RESTORER when using realtime signals. Otherwise, it does not - * know how to return from a signal handler. This function must have - * a "magic" signature that the "gdb" (and maybe the kernel?) can - * recognize. - * Apparently, a SA_RESTORER is implicitly set by the kernel, when - * using non-realtime signals. - * - * TODO: Test whether ARM needs a restorer - */ - if (!(a.sa_flags & SA_RESTORER)) { - a.sa_flags |= SA_RESTORER; - a.sa_restorer = (a.sa_flags & SA_SIGINFO) - ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); - } - #endif - } - rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, - (KERNEL_NSIG+7)/8); - if (rc < 0 && LSS_ERRNO == ENOSYS) { - struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; - if (!act) { - ptr_a = NULL; - } else { - oa.sa_handler_ = act->sa_handler_; - memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); - #ifndef __mips__ - oa.sa_restorer = act->sa_restorer; - #endif - oa.sa_flags = act->sa_flags; - } - if (!oldact) { - ptr_oa = NULL; - } - LSS_ERRNO = old_errno; - rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); - if (rc == 0 && oldact) { - if (act) { - memcpy(oldact, act, sizeof(*act)); - } else { - memset(oldact, 0, sizeof(*oldact)); - } - oldact->sa_handler_ = ptr_oa->sa_handler_; - oldact->sa_flags = ptr_oa->sa_flags; - memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); - #ifndef __mips__ - oldact->sa_restorer = ptr_oa->sa_restorer; - #endif - } - } - return rc; - } - - LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { - int old_errno = LSS_ERRNO; - int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); - if (rc < 0 && LSS_ERRNO == ENOSYS) { - LSS_ERRNO = old_errno; - LSS_NAME(sigemptyset)(set); - rc = LSS_NAME(_sigpending)(&set->sig[0]); - } - return rc; - } - - LSS_INLINE int LSS_NAME(sigprocmask)(int how, - const struct kernel_sigset_t *set, - struct kernel_sigset_t *oldset) { - int olderrno = LSS_ERRNO; - int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); - if (rc < 0 && LSS_ERRNO == ENOSYS) { - LSS_ERRNO = olderrno; - if (oldset) { - LSS_NAME(sigemptyset)(oldset); - } - rc = LSS_NAME(_sigprocmask)(how, - set ? &set->sig[0] : NULL, - oldset ? &oldset->sig[0] : NULL); - } - return rc; - } - - LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { - int olderrno = LSS_ERRNO; - int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); - if (rc < 0 && LSS_ERRNO == ENOSYS) { - LSS_ERRNO = olderrno; - rc = LSS_NAME(_sigsuspend)( - #ifndef __PPC__ - set, 0, - #endif - set->sig[0]); - } - return rc; - } - #endif - #if defined(__i386__) || \ - defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ - (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ - defined(__PPC__) || \ - (defined(__s390__) && !defined(__s390x__)) - /* On these architectures, implement mmap() with mmap2(). */ - LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, - int64_t o) { - if (o % 4096) { - LSS_ERRNO = EINVAL; - return (void *) -1; - } - return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096)); - } - #elif defined(__s390x__) - /* On s390x, mmap() arguments are passed in memory. */ - LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, - int64_t o) { - unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, - (unsigned long) p, (unsigned long) f, - (unsigned long) d, (unsigned long) o }; - LSS_REG(2, buf); - LSS_BODY(void*, mmap, "0"(__r2)); - } - #elif defined(__x86_64__) - /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */ - LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, - int64_t o) { - LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), - LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), - LSS_SYSCALL_ARG(d), (uint64_t)(o)); - } - #else - /* Remaining 64-bit architectures. */ - LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot, - int, flags, int, fd, int64_t, offset) - #endif - #if defined(__PPC__) - #undef LSS_SC_LOADARGS_0 - #define LSS_SC_LOADARGS_0(dummy...) - #undef LSS_SC_LOADARGS_1 - #define LSS_SC_LOADARGS_1(arg1) \ - __sc_4 = (unsigned long) (arg1) - #undef LSS_SC_LOADARGS_2 - #define LSS_SC_LOADARGS_2(arg1, arg2) \ - LSS_SC_LOADARGS_1(arg1); \ - __sc_5 = (unsigned long) (arg2) - #undef LSS_SC_LOADARGS_3 - #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ - LSS_SC_LOADARGS_2(arg1, arg2); \ - __sc_6 = (unsigned long) (arg3) - #undef LSS_SC_LOADARGS_4 - #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ - LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ - __sc_7 = (unsigned long) (arg4) - #undef LSS_SC_LOADARGS_5 - #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ - LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ - __sc_8 = (unsigned long) (arg5) - #undef LSS_SC_BODY - #define LSS_SC_BODY(nr, type, opt, args...) \ - long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ - register unsigned long __sc_3 __asm__ ("r3") = opt; \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - LSS_SC_LOADARGS_##nr(args); \ - __asm__ __volatile__ \ - ("stwu 1, -48(1)\n\t" \ - "stw 4, 20(1)\n\t" \ - "stw 5, 24(1)\n\t" \ - "stw 6, 28(1)\n\t" \ - "stw 7, 32(1)\n\t" \ - "stw 8, 36(1)\n\t" \ - "addi 4, 1, 20\n\t" \ - "sc\n\t" \ - "mfcr %0" \ - : "=&r" (__sc_0), \ - "=&r" (__sc_3), "=&r" (__sc_4), \ - "=&r" (__sc_5), "=&r" (__sc_6), \ - "=&r" (__sc_7), "=&r" (__sc_8) \ - : LSS_ASMINPUT_##nr \ - : "cr0", "ctr", "memory"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - LSS_RETURN(type, __sc_ret, __sc_err) - - LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, - int flags){ - LSS_SC_BODY(3, ssize_t, 17, s, msg, flags); - } - - LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, - const struct kernel_msghdr *msg, - int flags) { - LSS_SC_BODY(3, ssize_t, 16, s, msg, flags); - } - - // TODO(csilvers): why is this ifdef'ed out? -#if 0 - LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, - int flags, - const struct kernel_sockaddr *to, - unsigned int tolen) { - LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen); - } -#endif - - LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { - LSS_SC_BODY(2, int, 13, s, how); - } - - LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { - LSS_SC_BODY(3, int, 1, domain, type, protocol); - } - - LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, - int sv[2]) { - LSS_SC_BODY(4, int, 8, d, type, protocol, sv); - } - #endif - #if defined(__ARM_EABI__) || defined (__aarch64__) - LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg, - int, flags) - LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*, - msg, int, flags) - LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len, - int, flags, const struct kernel_sockaddr*, to, - unsigned int, tolen) - LSS_INLINE _syscall2(int, shutdown, int, s, int, how) - LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol) - LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol, - int*, sv) - #endif - #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ - (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ - defined(__s390__) - #define __NR__socketcall __NR_socketcall - LSS_INLINE _syscall2(int, _socketcall, int, c, - va_list, a) - LSS_INLINE int LSS_NAME(socketcall)(int op, ...) { - int rc; - va_list ap; - va_start(ap, op); - rc = LSS_NAME(_socketcall)(op, ap); - va_end(ap); - return rc; - } - - LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, - int flags){ - return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags); - } - - LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, - const struct kernel_msghdr *msg, - int flags) { - return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags); - } - - LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, - int flags, - const struct kernel_sockaddr *to, - unsigned int tolen) { - return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen); - } - - LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { - return LSS_NAME(socketcall)(13, s, how); - } - - LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { - return LSS_NAME(socketcall)(1, domain, type, protocol); - } - - LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, - int sv[2]) { - return LSS_NAME(socketcall)(8, d, type, protocol, sv); - } - #endif - #if defined(__NR_fstatat64) - LSS_INLINE _syscall4(int, fstatat64, int, d, - const char *, p, - struct kernel_stat64 *, b, int, f) - #endif - #if defined(__i386__) || defined(__PPC__) || \ - (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) - LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, - int*, s, int, o) - #endif - #if defined(__mips__) - /* sys_pipe() on MIPS has non-standard calling conventions, as it returns - * both file handles through CPU registers. - */ - LSS_INLINE int LSS_NAME(pipe)(int *p) { - register unsigned long __v0 __asm__("$2") = __NR_pipe; - register unsigned long __v1 __asm__("$3"); - register unsigned long __r7 __asm__("$7"); - __asm__ __volatile__ ("syscall\n" - : "=r"(__v0), "=r"(__v1), "=r" (__r7) - : "0"(__v0) - : "$8", "$9", "$10", "$11", "$12", - "$13", "$14", "$15", "$24", "$25", "memory"); - if (__r7) { - unsigned long __errnovalue = __v0; - LSS_ERRNO = __errnovalue; - return -1; - } else { - p[0] = __v0; - p[1] = __v1; - return 0; - } - } - #elif !defined(__aarch64__) - // The unlink syscall has been deprecated on aarch64. We polyfill it below. - LSS_INLINE _syscall1(int, pipe, int *, p) - #endif - /* TODO(csilvers): see if ppc can/should support this as well */ - #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ - defined(__ARM_EABI__) || \ - (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \ - (defined(__s390__) && !defined(__s390x__)) - #define __NR__statfs64 __NR_statfs64 - #define __NR__fstatfs64 __NR_fstatfs64 - LSS_INLINE _syscall3(int, _statfs64, const char*, p, - size_t, s,struct kernel_statfs64*, b) - LSS_INLINE _syscall3(int, _fstatfs64, int, f, - size_t, s,struct kernel_statfs64*, b) - LSS_INLINE int LSS_NAME(statfs64)(const char *p, - struct kernel_statfs64 *b) { - return LSS_NAME(_statfs64)(p, sizeof(*b), b); - } - LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) { - return LSS_NAME(_fstatfs64)(f, sizeof(*b), b); - } - #endif - - LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) { - extern char **environ; - return LSS_NAME(execve)(path, argv, (const char *const *)environ); - } - - LSS_INLINE pid_t LSS_NAME(gettid)(void) { - pid_t tid = LSS_NAME(_gettid)(); - if (tid != -1) { - return tid; - } - return LSS_NAME(getpid)(); - } - - LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, - size_t new_size, int flags, ...) { - va_list ap; - void *new_address, *rc; - va_start(ap, flags); - new_address = va_arg(ap, void *); - rc = LSS_NAME(_mremap)(old_address, old_size, new_size, - flags, new_address); - va_end(ap); - return rc; - } - - LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) { - /* PTRACE_DETACH can sometimes forget to wake up the tracee and it - * then sends job control signals to the real parent, rather than to - * the tracer. We reduce the risk of this happening by starting a - * whole new time slice, and then quickly sending a SIGCONT signal - * right after detaching from the tracee. - * - * We use tkill to ensure that we only issue a wakeup for the thread being - * detached. Large multi threaded apps can take a long time in the kernel - * processing SIGCONT. - */ - int rc, err; - LSS_NAME(sched_yield)(); - rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); - err = LSS_ERRNO; - LSS_NAME(tkill)(pid, SIGCONT); - /* Old systems don't have tkill */ - if (LSS_ERRNO == ENOSYS) - LSS_NAME(kill)(pid, SIGCONT); - LSS_ERRNO = err; - return rc; - } - - LSS_INLINE int LSS_NAME(raise)(int sig) { - return LSS_NAME(kill)(LSS_NAME(getpid)(), sig); - } - - LSS_INLINE int LSS_NAME(setpgrp)(void) { - return LSS_NAME(setpgid)(0, 0); - } - - LSS_INLINE int LSS_NAME(sysconf)(int name) { - extern int __getpagesize(void); - switch (name) { - case _SC_OPEN_MAX: { - struct kernel_rlimit limit; -#if defined(__ARM_EABI__) - return LSS_NAME(ugetrlimit)(RLIMIT_NOFILE, &limit) < 0 - ? 8192 : limit.rlim_cur; -#else - return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0 - ? 8192 : limit.rlim_cur; -#endif - } - case _SC_PAGESIZE: - return __getpagesize(); - default: - LSS_ERRNO = ENOSYS; - return -1; - } - } - #if defined(__x86_64__) - /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ - LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) { - LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), - LSS_SYSCALL_ARG(c), (uint64_t)(o)); - } - - LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c, - loff_t o) { - LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), - LSS_SYSCALL_ARG(c), (uint64_t)(o)); - } - - LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) { - LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o), - LSS_SYSCALL_ARG(c)); - } - #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64 - LSS_INLINE _syscall4(ssize_t, pread64, int, f, - void *, b, size_t, c, - loff_t, o) - LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, - const void *, b, size_t, c, - loff_t, o) - LSS_INLINE _syscall3(int, readahead, int, f, - loff_t, o, unsigned, c) - LSS_INLINE _syscall6(void *, mmap, void *, addr, size_t, length, int, prot, - int, flags, int, fd, int64_t, offset) - #else - #define __NR__pread64 __NR_pread64 - #define __NR__pwrite64 __NR_pwrite64 - #define __NR__readahead __NR_readahead - #if defined(__ARM_EABI__) || defined(__mips__) - /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register - * pair. Hence these calls ignore their fourth argument (r3) so that their - * fifth and sixth make such a pair (r4,r5). - */ - #define LSS_LLARG_PAD 0, - LSS_INLINE _syscall6(ssize_t, _pread64, int, f, - void *, b, size_t, c, - unsigned, skip, unsigned, o1, unsigned, o2) - LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f, - const void *, b, size_t, c, - unsigned, skip, unsigned, o1, unsigned, o2) - LSS_INLINE _syscall5(int, _readahead, int, f, - unsigned, skip, - unsigned, o1, unsigned, o2, size_t, c) - #else - #define LSS_LLARG_PAD - LSS_INLINE _syscall5(ssize_t, _pread64, int, f, - void *, b, size_t, c, unsigned, o1, - unsigned, o2) - LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f, - const void *, b, size_t, c, unsigned, o1, - long, o2) - LSS_INLINE _syscall4(int, _readahead, int, f, - unsigned, o1, unsigned, o2, size_t, c) - #endif - /* We force 64bit-wide parameters onto the stack, then access each - * 32-bit component individually. This guarantees that we build the - * correct parameters independent of the native byte-order of the - * underlying architecture. - */ - LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count, - loff_t off) { - union { loff_t off; unsigned arg[2]; } o = { off }; - return LSS_NAME(_pread64)(fd, buf, count, - LSS_LLARG_PAD o.arg[0], o.arg[1]); - } - LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf, - size_t count, loff_t off) { - union { loff_t off; unsigned arg[2]; } o = { off }; - return LSS_NAME(_pwrite64)(fd, buf, count, - LSS_LLARG_PAD o.arg[0], o.arg[1]); - } - LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) { - union { loff_t off; unsigned arg[2]; } o = { off }; - return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], len); - } - #endif -#endif - -#if defined(__aarch64__) - LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f) - LSS_INLINE _syscall6(void *, mmap, void *, addr, size_t, length, int, prot, - int, flags, int, fd, int64_t, offset) - LSS_INLINE _syscall4(int, newfstatat, int, dirfd, const char *, pathname, - struct kernel_stat *, buf, int, flags) - LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags) - LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u, - unsigned int, n, const struct kernel_timespec *, t, - const struct kernel_sigset_t *, sigmask, size_t, s) - LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b, - size_t, s) -#endif - -/* - * Polyfills for deprecated syscalls. - */ - -#if defined(__aarch64__) - LSS_INLINE int LSS_NAME(dup2)(int s, int d) { - return LSS_NAME(dup3)(s, d, 0); - } - - LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) { - return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode); - } - - LSS_INLINE int LSS_NAME(unlink)(const char *pathname) { - return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0); - } - - LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer, - size_t size) { - return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size); - } - - LSS_INLINE pid_t LSS_NAME(pipe)(int *pipefd) { - return LSS_NAME(pipe2)(pipefd, 0); - } - - LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds, - int timeout) { - struct kernel_timespec timeout_ts; - struct kernel_timespec *timeout_ts_p = NULL; - - if (timeout >= 0) { - timeout_ts.tv_sec = timeout / 1000; - timeout_ts.tv_nsec = (timeout % 1000) * 1000000; - timeout_ts_p = &timeout_ts; - } - return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0); - } - - LSS_INLINE int LSS_NAME(stat)(const char *pathname, - struct kernel_stat *buf) { - return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0); - } - - LSS_INLINE pid_t LSS_NAME(fork)(void) { - // No fork syscall on aarch64 - implement by means of the clone syscall. - // Note that this does not reset glibc's cached view of the PID/TID, so - // some glibc interfaces might go wrong in the forked subprocess. - int flags = SIGCHLD; - void *child_stack = NULL; - void *parent_tidptr = NULL; - void *newtls = NULL; - void *child_tidptr = NULL; - - LSS_REG(0, flags); - LSS_REG(1, child_stack); - LSS_REG(2, parent_tidptr); - LSS_REG(3, newtls); - LSS_REG(4, child_tidptr); - LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), - "r"(__r4)); - } -#endif - -#ifdef __ANDROID__ - /* These restore the original values of these macros saved by the - * corresponding #pragma push_macro near the top of this file. */ -# pragma pop_macro("stat64") -# pragma pop_macro("fstat64") -# pragma pop_macro("lstat64") -#endif - -#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) -} -#endif - -#endif -#endif - diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/README b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/README deleted file mode 100644 index c681bb3d6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/README +++ /dev/null @@ -1,2 +0,0 @@ -These headers were copied from the Mac OS X 10.7 SDK to enable building -the Mac dump_syms code that processes Mach-O files on Linux. diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/architecture/byte_order.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/architecture/byte_order.h deleted file mode 100644 index b772d9f38..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/architecture/byte_order.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1999-2008 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1992 NeXT Computer, Inc. - * - * Byte ordering conversion. - * - */ -/* This file mostly left blank */ - -#ifndef _ARCHITECTURE_BYTE_ORDER_H_ -#define _ARCHITECTURE_BYTE_ORDER_H_ - -/* - * Identify the byte order - * of the current host. - */ - -enum NXByteOrder { - NX_UnknownByteOrder, - NX_LittleEndian, - NX_BigEndian -}; - -#endif /* _ARCHITECTURE_BYTE_ORDER_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/i386/_types.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/i386/_types.h deleted file mode 100644 index 2ed7fd675..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/i386/_types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -#ifndef _BSD_I386__TYPES_H_ -#define _BSD_I386__TYPES_H_ - -typedef long __darwin_intptr_t; -typedef unsigned int __darwin_natural_t; - -#endif /* _BSD_I386__TYPES_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/arch.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/arch.h deleted file mode 100644 index 526c10fc8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/arch.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _MACH_O_ARCH_H_ -#define _MACH_O_ARCH_H_ -/* - * Copyright (c) 1997 Apple Computer, Inc. - * - * Functions that deal with information about architectures. - * - */ - -#include -#include -#include - -/* The NXArchInfo structs contain the architectures symbolic name - * (such as "ppc"), its CPU type and CPU subtype as defined in - * mach/machine.h, the byte order for the architecture, and a - * describing string (such as "PowerPC"). - * There will both be entries for specific CPUs (such as ppc604e) as - * well as generic "family" entries (such as ppc). - */ -typedef struct { - const char *name; - cpu_type_t cputype; - cpu_subtype_t cpusubtype; - enum NXByteOrder byteorder; - const char *description; -} NXArchInfo; - -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* NXGetAllArchInfos() returns a pointer to an array of all known - * NXArchInfo structures. The last NXArchInfo is marked by a NULL name. - */ -extern const NXArchInfo *NXGetAllArchInfos(void); - -/* NXGetLocalArchInfo() returns the NXArchInfo for the local host, or NULL - * if none is known. - */ -extern const NXArchInfo *NXGetLocalArchInfo(void); - -/* NXGetArchInfoFromName() and NXGetArchInfoFromCpuType() return the - * NXArchInfo from the architecture's name or cputype/cpusubtype - * combination. A cpusubtype of CPU_SUBTYPE_MULTIPLE can be used - * to request the most general NXArchInfo known for the given cputype. - * NULL is returned if no matching NXArchInfo can be found. - */ -extern const NXArchInfo *NXGetArchInfoFromName(const char *name); -extern const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype, - cpu_subtype_t cpusubtype); - -/* NXFindBestFatArch() is passed a cputype and cpusubtype and a set of - * fat_arch structs and selects the best one that matches (if any) and returns - * a pointer to that fat_arch struct (or NULL). The fat_arch structs must be - * in the host byte order and correct such that the fat_archs really points to - * enough memory for nfat_arch structs. It is possible that this routine could - * fail if new cputypes or cpusubtypes are added and an old version of this - * routine is used. But if there is an exact match between the cputype and - * cpusubtype and one of the fat_arch structs this routine will always succeed. - */ -extern struct fat_arch *NXFindBestFatArch(cpu_type_t cputype, - cpu_subtype_t cpusubtype, - struct fat_arch *fat_archs, - uint32_t nfat_archs); - -/* NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two - * different cpusubtypes for the specified cputype. If the two cpusubtypes - * can't be combined (the specific subtypes are mutually exclusive) -1 is - * returned indicating it is an error to combine them. This can also fail and - * return -1 if new cputypes or cpusubtypes are added and an old version of - * this routine is used. But if the cpusubtypes are the same they can always - * be combined and this routine will return the cpusubtype pass in. - */ -extern cpu_subtype_t NXCombineCpuSubtypes(cpu_type_t cputype, - cpu_subtype_t cpusubtype1, - cpu_subtype_t cpusubtype2); - -#if __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _MACH_O_ARCH_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/fat.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/fat.h deleted file mode 100644 index e2bcf433d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/fat.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _MACH_O_FAT_H_ -#define _MACH_O_FAT_H_ -/* - * This header file describes the structures of the file format for "fat" - * architecture specific file (wrapper design). At the begining of the file - * there is one fat_header structure followed by a number of fat_arch - * structures. For each architecture in the file, specified by a pair of - * cputype and cpusubtype, the fat_header describes the file offset, file - * size and alignment in the file of the architecture specific member. - * The padded bytes in the file to place each member on it's specific alignment - * are defined to be read as zeros and can be left as "holes" if the file system - * can support them as long as they read as zeros. - * - * All structures defined here are always written and read to/from disk - * in big-endian order. - */ - -/* - * is needed here for the cpu_type_t and cpu_subtype_t types - * and contains the constants for the possible values of these types. - */ -#include -#include -#include - -#define FAT_MAGIC 0xcafebabe -#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */ - -struct fat_header { - uint32_t magic; /* FAT_MAGIC */ - uint32_t nfat_arch; /* number of structs that follow */ -}; - -struct fat_arch { - cpu_type_t cputype; /* cpu specifier (int) */ - cpu_subtype_t cpusubtype; /* machine specifier (int) */ - uint32_t offset; /* file offset to this object file */ - uint32_t size; /* size of this object file */ - uint32_t align; /* alignment as a power of 2 */ -}; - -#endif /* _MACH_O_FAT_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/loader.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/loader.h deleted file mode 100644 index ff18e29c7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/loader.h +++ /dev/null @@ -1,1402 +0,0 @@ -/* - * Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _MACHO_LOADER_H_ -#define _MACHO_LOADER_H_ - -/* - * This file describes the format of mach object files. - */ -#include - -/* - * is needed here for the cpu_type_t and cpu_subtype_t types - * and contains the constants for the possible values of these types. - */ -#include - -/* - * is needed here for the vm_prot_t type and contains the - * constants that are or'ed together for the possible values of this type. - */ -#include - -/* - * is expected to define the flavors of the thread - * states and the structures of those flavors for each machine. - */ -#include -#include - -/* - * The 32-bit mach header appears at the very beginning of the object file for - * 32-bit architectures. - */ -struct mach_header { - uint32_t magic; /* mach magic number identifier */ - cpu_type_t cputype; /* cpu specifier */ - cpu_subtype_t cpusubtype; /* machine specifier */ - uint32_t filetype; /* type of file */ - uint32_t ncmds; /* number of load commands */ - uint32_t sizeofcmds; /* the size of all the load commands */ - uint32_t flags; /* flags */ -}; - -/* Constant for the magic field of the mach_header (32-bit architectures) */ -#define MH_MAGIC 0xfeedface /* the mach magic number */ -#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ - -/* - * The 64-bit mach header appears at the very beginning of object files for - * 64-bit architectures. - */ -struct mach_header_64 { - uint32_t magic; /* mach magic number identifier */ - cpu_type_t cputype; /* cpu specifier */ - cpu_subtype_t cpusubtype; /* machine specifier */ - uint32_t filetype; /* type of file */ - uint32_t ncmds; /* number of load commands */ - uint32_t sizeofcmds; /* the size of all the load commands */ - uint32_t flags; /* flags */ - uint32_t reserved; /* reserved */ -}; - -/* Constant for the magic field of the mach_header_64 (64-bit architectures) */ -#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ -#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ - -/* - * The layout of the file depends on the filetype. For all but the MH_OBJECT - * file type the segments are padded out and aligned on a segment alignment - * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, - * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part - * of their first segment. - * - * The file type MH_OBJECT is a compact format intended as output of the - * assembler and input (and possibly output) of the link editor (the .o - * format). All sections are in one unnamed segment with no segment padding. - * This format is used as an executable format when the file is so small the - * segment padding greatly increases its size. - * - * The file type MH_PRELOAD is an executable format intended for things that - * are not executed under the kernel (proms, stand alones, kernels, etc). The - * format can be executed under the kernel but may demand paged it and not - * preload it before execution. - * - * A core file is in MH_CORE format and can be any in an arbritray legal - * Mach-O file. - * - * Constants for the filetype field of the mach_header - */ -#define MH_OBJECT 0x1 /* relocatable object file */ -#define MH_EXECUTE 0x2 /* demand paged executable file */ -#define MH_FVMLIB 0x3 /* fixed VM shared library file */ -#define MH_CORE 0x4 /* core file */ -#define MH_PRELOAD 0x5 /* preloaded executable file */ -#define MH_DYLIB 0x6 /* dynamically bound shared library */ -#define MH_DYLINKER 0x7 /* dynamic link editor */ -#define MH_BUNDLE 0x8 /* dynamically bound bundle file */ -#define MH_DYLIB_STUB 0x9 /* shared library stub for static */ - /* linking only, no section contents */ -#define MH_DSYM 0xa /* companion file with only debug */ - /* sections */ -#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ - -/* Constants for the flags field of the mach_header */ -#define MH_NOUNDEFS 0x1 /* the object file has no undefined - references */ -#define MH_INCRLINK 0x2 /* the object file is the output of an - incremental link against a base file - and can't be link edited again */ -#define MH_DYLDLINK 0x4 /* the object file is input for the - dynamic linker and can't be staticly - link edited again */ -#define MH_BINDATLOAD 0x8 /* the object file's undefined - references are bound by the dynamic - linker when loaded. */ -#define MH_PREBOUND 0x10 /* the file has its dynamic undefined - references prebound. */ -#define MH_SPLIT_SEGS 0x20 /* the file has its read-only and - read-write segments split */ -#define MH_LAZY_INIT 0x40 /* the shared library init routine is - to be run lazily via catching memory - faults to its writeable segments - (obsolete) */ -#define MH_TWOLEVEL 0x80 /* the image is using two-level name - space bindings */ -#define MH_FORCE_FLAT 0x100 /* the executable is forcing all images - to use flat name space bindings */ -#define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple - defintions of symbols in its - sub-images so the two-level namespace - hints can always be used. */ -#define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the - prebinding agent about this - executable */ -#define MH_PREBINDABLE 0x800 /* the binary is not prebound but can - have its prebinding redone. only used - when MH_PREBOUND is not set. */ -#define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to - all two-level namespace modules of - its dependent libraries. only used - when MH_PREBINDABLE and MH_TWOLEVEL - are both set. */ -#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into - sub-sections via symbols for dead - code stripping */ -#define MH_CANONICAL 0x4000 /* the binary has been canonicalized - via the unprebind operation */ -#define MH_WEAK_DEFINES 0x8000 /* the final linked image contains - external weak symbols */ -#define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses - weak symbols */ - -#define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks - in the task will be given stack - execution privilege. Only used in - MH_EXECUTE filetypes. */ -#define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary - declares it is safe for use in - processes with uid zero */ - -#define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary - declares it is safe for use in - processes when issetugid() is true */ - -#define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, - the static linker does not need to - examine dependent dylibs to see - if any are re-exported */ -#define MH_PIE 0x200000 /* When this bit is set, the OS will - load the main executable at a - random address. Only used in - MH_EXECUTE filetypes. */ -#define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When - linking against a dylib that - has this bit set, the static linker - will automatically not create a - LC_LOAD_DYLIB load command to the - dylib if no symbols are being - referenced from the dylib. */ -#define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type - S_THREAD_LOCAL_VARIABLES */ - -#define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will - run the main executable with - a non-executable heap even on - platforms (e.g. i386) that don't - require it. Only used in MH_EXECUTE - filetypes. */ - -/* - * The load commands directly follow the mach_header. The total size of all - * of the commands is given by the sizeofcmds field in the mach_header. All - * load commands must have as their first two fields cmd and cmdsize. The cmd - * field is filled in with a constant for that command type. Each command type - * has a structure specifically for it. The cmdsize field is the size in bytes - * of the particular load command structure plus anything that follows it that - * is a part of the load command (i.e. section structures, strings, etc.). To - * advance to the next load command the cmdsize can be added to the offset or - * pointer of the current load command. The cmdsize for 32-bit architectures - * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple - * of 8 bytes (these are forever the maximum alignment of any load commands). - * The padded bytes must be zero. All tables in the object file must also - * follow these rules so the file can be memory mapped. Otherwise the pointers - * to these tables will not work well or at all on some machines. With all - * padding zeroed like objects will compare byte for byte. - */ -struct load_command { - uint32_t cmd; /* type of load command */ - uint32_t cmdsize; /* total size of command in bytes */ -}; - -/* - * After MacOS X 10.1 when a new load command is added that is required to be - * understood by the dynamic linker for the image to execute properly the - * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic - * linker sees such a load command it it does not understand will issue a - * "unknown load command required for execution" error and refuse to use the - * image. Other load commands without this bit that are not understood will - * simply be ignored. - */ -#define LC_REQ_DYLD 0x80000000 - -/* Constants for the cmd field of all load commands, the type */ -#define LC_SEGMENT 0x1 /* segment of this file to be mapped */ -#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ -#define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ -#define LC_THREAD 0x4 /* thread */ -#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ -#define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ -#define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ -#define LC_IDENT 0x8 /* object identification info (obsolete) */ -#define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ -#define LC_PREPAGE 0xa /* prepage command (internal use) */ -#define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ -#define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ -#define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ -#define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ -#define LC_ID_DYLINKER 0xf /* dynamic linker identification */ -#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ - /* linked shared library */ -#define LC_ROUTINES 0x11 /* image routines */ -#define LC_SUB_FRAMEWORK 0x12 /* sub framework */ -#define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ -#define LC_SUB_CLIENT 0x14 /* sub client */ -#define LC_SUB_LIBRARY 0x15 /* sub library */ -#define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ -#define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ - -/* - * load a dynamically linked shared library that is allowed to be missing - * (all symbols are weak imported). - */ -#define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) - -#define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be - mapped */ -#define LC_ROUTINES_64 0x1a /* 64-bit image routines */ -#define LC_UUID 0x1b /* the uuid */ -#define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ -#define LC_CODE_SIGNATURE 0x1d /* local of code signature */ -#define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ -#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ -#define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ -#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ -#define LC_DYLD_INFO 0x22 /* compressed dyld information */ -#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ -#define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ -#define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ -#define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ -#define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ -#define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat - like environment variable */ - -/* - * A variable length string in a load command is represented by an lc_str - * union. The strings are stored just after the load command structure and - * the offset is from the start of the load command structure. The size - * of the string is reflected in the cmdsize field of the load command. - * Once again any padded bytes to bring the cmdsize field to a multiple - * of 4 bytes must be zero. - */ -union lc_str { - uint32_t offset; /* offset to the string */ -#ifndef __LP64__ - char *ptr; /* pointer to the string */ -#endif -}; - -/* - * The segment load command indicates that a part of this file is to be - * mapped into the task's address space. The size of this segment in memory, - * vmsize, maybe equal to or larger than the amount to map from this file, - * filesize. The file is mapped starting at fileoff to the beginning of - * the segment in memory, vmaddr. The rest of the memory of the segment, - * if any, is allocated zero fill on demand. The segment's maximum virtual - * memory protection and initial virtual memory protection are specified - * by the maxprot and initprot fields. If the segment has sections then the - * section structures directly follow the segment command and their size is - * reflected in cmdsize. - */ -struct segment_command { /* for 32-bit architectures */ - uint32_t cmd; /* LC_SEGMENT */ - uint32_t cmdsize; /* includes sizeof section structs */ - char segname[16]; /* segment name */ - uint32_t vmaddr; /* memory address of this segment */ - uint32_t vmsize; /* memory size of this segment */ - uint32_t fileoff; /* file offset of this segment */ - uint32_t filesize; /* amount to map from the file */ - vm_prot_t maxprot; /* maximum VM protection */ - vm_prot_t initprot; /* initial VM protection */ - uint32_t nsects; /* number of sections in segment */ - uint32_t flags; /* flags */ -}; - -/* - * The 64-bit segment load command indicates that a part of this file is to be - * mapped into a 64-bit task's address space. If the 64-bit segment has - * sections then section_64 structures directly follow the 64-bit segment - * command and their size is reflected in cmdsize. - */ -struct segment_command_64 { /* for 64-bit architectures */ - uint32_t cmd; /* LC_SEGMENT_64 */ - uint32_t cmdsize; /* includes sizeof section_64 structs */ - char segname[16]; /* segment name */ - uint64_t vmaddr; /* memory address of this segment */ - uint64_t vmsize; /* memory size of this segment */ - uint64_t fileoff; /* file offset of this segment */ - uint64_t filesize; /* amount to map from the file */ - vm_prot_t maxprot; /* maximum VM protection */ - vm_prot_t initprot; /* initial VM protection */ - uint32_t nsects; /* number of sections in segment */ - uint32_t flags; /* flags */ -}; - -/* Constants for the flags field of the segment_command */ -#define SG_HIGHVM 0x1 /* the file contents for this segment is for - the high part of the VM space, the low part - is zero filled (for stacks in core files) */ -#define SG_FVMLIB 0x2 /* this segment is the VM that is allocated by - a fixed VM library, for overlap checking in - the link editor */ -#define SG_NORELOC 0x4 /* this segment has nothing that was relocated - in it and nothing relocated to it, that is - it maybe safely replaced without relocation*/ -#define SG_PROTECTED_VERSION_1 0x8 /* This segment is protected. If the - segment starts at file offset 0, the - first page of the segment is not - protected. All other pages of the - segment are protected. */ - -/* - * A segment is made up of zero or more sections. Non-MH_OBJECT files have - * all of their segments with the proper sections in each, and padded to the - * specified segment alignment when produced by the link editor. The first - * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header - * and load commands of the object file before its first section. The zero - * fill sections are always last in their segment (in all formats). This - * allows the zeroed segment padding to be mapped into memory where zero fill - * sections might be. The gigabyte zero fill sections, those with the section - * type S_GB_ZEROFILL, can only be in a segment with sections of this type. - * These segments are then placed after all other segments. - * - * The MH_OBJECT format has all of its sections in one segment for - * compactness. There is no padding to a specified segment boundary and the - * mach_header and load commands are not part of the segment. - * - * Sections with the same section name, sectname, going into the same segment, - * segname, are combined by the link editor. The resulting section is aligned - * to the maximum alignment of the combined sections and is the new section's - * alignment. The combined sections are aligned to their original alignment in - * the combined section. Any padded bytes to get the specified alignment are - * zeroed. - * - * The format of the relocation entries referenced by the reloff and nreloc - * fields of the section structure for mach object files is described in the - * header file . - */ -struct section { /* for 32-bit architectures */ - char sectname[16]; /* name of this section */ - char segname[16]; /* segment this section goes in */ - uint32_t addr; /* memory address of this section */ - uint32_t size; /* size in bytes of this section */ - uint32_t offset; /* file offset of this section */ - uint32_t align; /* section alignment (power of 2) */ - uint32_t reloff; /* file offset of relocation entries */ - uint32_t nreloc; /* number of relocation entries */ - uint32_t flags; /* flags (section type and attributes)*/ - uint32_t reserved1; /* reserved (for offset or index) */ - uint32_t reserved2; /* reserved (for count or sizeof) */ -}; - -struct section_64 { /* for 64-bit architectures */ - char sectname[16]; /* name of this section */ - char segname[16]; /* segment this section goes in */ - uint64_t addr; /* memory address of this section */ - uint64_t size; /* size in bytes of this section */ - uint32_t offset; /* file offset of this section */ - uint32_t align; /* section alignment (power of 2) */ - uint32_t reloff; /* file offset of relocation entries */ - uint32_t nreloc; /* number of relocation entries */ - uint32_t flags; /* flags (section type and attributes)*/ - uint32_t reserved1; /* reserved (for offset or index) */ - uint32_t reserved2; /* reserved (for count or sizeof) */ - uint32_t reserved3; /* reserved */ -}; - -/* - * The flags field of a section structure is separated into two parts a section - * type and section attributes. The section types are mutually exclusive (it - * can only have one type) but the section attributes are not (it may have more - * than one attribute). - */ -#define SECTION_TYPE 0x000000ff /* 256 section types */ -#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ - -/* Constants for the type of a section */ -#define S_REGULAR 0x0 /* regular section */ -#define S_ZEROFILL 0x1 /* zero fill on demand section */ -#define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ -#define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ -#define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ -#define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ - /* literals */ -/* - * For the two types of symbol pointers sections and the symbol stubs section - * they have indirect symbol table entries. For each of the entries in the - * section the indirect symbol table entries, in corresponding order in the - * indirect symbol table, start at the index stored in the reserved1 field - * of the section structure. Since the indirect symbol table entries - * correspond to the entries in the section the number of indirect symbol table - * entries is inferred from the size of the section divided by the size of the - * entries in the section. For symbol pointers sections the size of the entries - * in the section is 4 bytes and for symbol stubs sections the byte size of the - * stubs is stored in the reserved2 field of the section structure. - */ -#define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy - symbol pointers */ -#define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol - pointers */ -#define S_SYMBOL_STUBS 0x8 /* section with only symbol - stubs, byte size of stub in - the reserved2 field */ -#define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function - pointers for initialization*/ -#define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function - pointers for termination */ -#define S_COALESCED 0xb /* section contains symbols that - are to be coalesced */ -#define S_GB_ZEROFILL 0xc /* zero fill on demand section - (that can be larger than 4 - gigabytes) */ -#define S_INTERPOSING 0xd /* section with only pairs of - function pointers for - interposing */ -#define S_16BYTE_LITERALS 0xe /* section with only 16 byte - literals */ -#define S_DTRACE_DOF 0xf /* section contains - DTrace Object Format */ -#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy - symbol pointers to lazy - loaded dylibs */ -/* - * Section types to support thread local variables - */ -#define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial - values for TLVs */ -#define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial - values for TLVs */ -#define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ -#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV - descriptors */ -#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call - to initialize TLV - values */ - -/* - * Constants for the section attributes part of the flags field of a section - * structure. - */ -#define SECTION_ATTRIBUTES_USR 0xff000000 /* User setable attributes */ -#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section contains only true - machine instructions */ -#define S_ATTR_NO_TOC 0x40000000 /* section contains coalesced - symbols that are not to be - in a ranlib table of - contents */ -#define S_ATTR_STRIP_STATIC_SYMS 0x20000000 /* ok to strip static symbols - in this section in files - with the MH_DYLDLINK flag */ -#define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ -#define S_ATTR_LIVE_SUPPORT 0x08000000 /* blocks are live if they - reference live blocks */ -#define S_ATTR_SELF_MODIFYING_CODE 0x04000000 /* Used with i386 code stubs - written on by dyld */ -/* - * If a segment contains any sections marked with S_ATTR_DEBUG then all - * sections in that segment must have this attribute. No section other than - * a section marked with this attribute may reference the contents of this - * section. A section with this attribute may contain no symbols and must have - * a section type S_REGULAR. The static linker will not copy section contents - * from sections with this attribute into its output file. These sections - * generally contain DWARF debugging info. - */ -#define S_ATTR_DEBUG 0x02000000 /* a debug section */ -#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ -#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some - machine instructions */ -#define S_ATTR_EXT_RELOC 0x00000200 /* section has external - relocation entries */ -#define S_ATTR_LOC_RELOC 0x00000100 /* section has local - relocation entries */ - - -/* - * The names of segments and sections in them are mostly meaningless to the - * link-editor. But there are few things to support traditional UNIX - * executables that require the link-editor and assembler to use some names - * agreed upon by convention. - * - * The initial protection of the "__TEXT" segment has write protection turned - * off (not writeable). - * - * The link-editor will allocate common symbols at the end of the "__common" - * section in the "__DATA" segment. It will create the section and segment - * if needed. - */ - -/* The currently known segment names and the section names in those segments */ - -#define SEG_PAGEZERO "__PAGEZERO" /* the pagezero segment which has no */ - /* protections and catches NULL */ - /* references for MH_EXECUTE files */ - - -#define SEG_TEXT "__TEXT" /* the tradition UNIX text segment */ -#define SECT_TEXT "__text" /* the real text part of the text */ - /* section no headers, and no padding */ -#define SECT_FVMLIB_INIT0 "__fvmlib_init0" /* the fvmlib initialization */ - /* section */ -#define SECT_FVMLIB_INIT1 "__fvmlib_init1" /* the section following the */ - /* fvmlib initialization */ - /* section */ - -#define SEG_DATA "__DATA" /* the tradition UNIX data segment */ -#define SECT_DATA "__data" /* the real initialized data section */ - /* no padding, no bss overlap */ -#define SECT_BSS "__bss" /* the real uninitialized data section*/ - /* no padding */ -#define SECT_COMMON "__common" /* the section common symbols are */ - /* allocated in by the link editor */ - -#define SEG_OBJC "__OBJC" /* objective-C runtime segment */ -#define SECT_OBJC_SYMBOLS "__symbol_table" /* symbol table */ -#define SECT_OBJC_MODULES "__module_info" /* module information */ -#define SECT_OBJC_STRINGS "__selector_strs" /* string table */ -#define SECT_OBJC_REFS "__selector_refs" /* string table */ - -#define SEG_ICON "__ICON" /* the icon segment */ -#define SECT_ICON_HEADER "__header" /* the icon headers */ -#define SECT_ICON_TIFF "__tiff" /* the icons in tiff format */ - -#define SEG_LINKEDIT "__LINKEDIT" /* the segment containing all structs */ - /* created and maintained by the link */ - /* editor. Created with -seglinkedit */ - /* option to ld(1) for MH_EXECUTE and */ - /* FVMLIB file types only */ - -#define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */ - -#define SEG_IMPORT "__IMPORT" /* the segment for the self (dyld) */ - /* modifing code stubs that has read, */ - /* write and execute permissions */ - -/* - * Fixed virtual memory shared libraries are identified by two things. The - * target pathname (the name of the library as found for execution), and the - * minor version number. The address of where the headers are loaded is in - * header_addr. (THIS IS OBSOLETE and no longer supported). - */ -struct fvmlib { - union lc_str name; /* library's target pathname */ - uint32_t minor_version; /* library's minor version number */ - uint32_t header_addr; /* library's header address */ -}; - -/* - * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) - * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library. - * An object that uses a fixed virtual shared library also contains a - * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. - * (THIS IS OBSOLETE and no longer supported). - */ -struct fvmlib_command { - uint32_t cmd; /* LC_IDFVMLIB or LC_LOADFVMLIB */ - uint32_t cmdsize; /* includes pathname string */ - struct fvmlib fvmlib; /* the library identification */ -}; - -/* - * Dynamicly linked shared libraries are identified by two things. The - * pathname (the name of the library as found for execution), and the - * compatibility version number. The pathname must match and the compatibility - * number in the user of the library must be greater than or equal to the - * library being used. The time stamp is used to record the time a library was - * built and copied into user so it can be use to determined if the library used - * at runtime is exactly the same as used to built the program. - */ -struct dylib { - union lc_str name; /* library's path name */ - uint32_t timestamp; /* library's build time stamp */ - uint32_t current_version; /* library's current version number */ - uint32_t compatibility_version; /* library's compatibility vers number*/ -}; - -/* - * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) - * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. - * An object that uses a dynamically linked shared library also contains a - * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or - * LC_REEXPORT_DYLIB) for each library it uses. - */ -struct dylib_command { - uint32_t cmd; /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, - LC_REEXPORT_DYLIB */ - uint32_t cmdsize; /* includes pathname string */ - struct dylib dylib; /* the library identification */ -}; - -/* - * A dynamically linked shared library may be a subframework of an umbrella - * framework. If so it will be linked with "-umbrella umbrella_name" where - * Where "umbrella_name" is the name of the umbrella framework. A subframework - * can only be linked against by its umbrella framework or other subframeworks - * that are part of the same umbrella framework. Otherwise the static link - * editor produces an error and states to link against the umbrella framework. - * The name of the umbrella framework for subframeworks is recorded in the - * following structure. - */ -struct sub_framework_command { - uint32_t cmd; /* LC_SUB_FRAMEWORK */ - uint32_t cmdsize; /* includes umbrella string */ - union lc_str umbrella; /* the umbrella framework name */ -}; - -/* - * For dynamically linked shared libraries that are subframework of an umbrella - * framework they can allow clients other than the umbrella framework or other - * subframeworks in the same umbrella framework. To do this the subframework - * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load - * command is created for each -allowable_client flag. The client_name is - * usually a framework name. It can also be a name used for bundles clients - * where the bundle is built with "-client_name client_name". - */ -struct sub_client_command { - uint32_t cmd; /* LC_SUB_CLIENT */ - uint32_t cmdsize; /* includes client string */ - union lc_str client; /* the client name */ -}; - -/* - * A dynamically linked shared library may be a sub_umbrella of an umbrella - * framework. If so it will be linked with "-sub_umbrella umbrella_name" where - * Where "umbrella_name" is the name of the sub_umbrella framework. When - * staticly linking when -twolevel_namespace is in effect a twolevel namespace - * umbrella framework will only cause its subframeworks and those frameworks - * listed as sub_umbrella frameworks to be implicited linked in. Any other - * dependent dynamic libraries will not be linked it when -twolevel_namespace - * is in effect. The primary library recorded by the static linker when - * resolving a symbol in these libraries will be the umbrella framework. - * Zero or more sub_umbrella frameworks may be use by an umbrella framework. - * The name of a sub_umbrella framework is recorded in the following structure. - */ -struct sub_umbrella_command { - uint32_t cmd; /* LC_SUB_UMBRELLA */ - uint32_t cmdsize; /* includes sub_umbrella string */ - union lc_str sub_umbrella; /* the sub_umbrella framework name */ -}; - -/* - * A dynamically linked shared library may be a sub_library of another shared - * library. If so it will be linked with "-sub_library library_name" where - * Where "library_name" is the name of the sub_library shared library. When - * staticly linking when -twolevel_namespace is in effect a twolevel namespace - * shared library will only cause its subframeworks and those frameworks - * listed as sub_umbrella frameworks and libraries listed as sub_libraries to - * be implicited linked in. Any other dependent dynamic libraries will not be - * linked it when -twolevel_namespace is in effect. The primary library - * recorded by the static linker when resolving a symbol in these libraries - * will be the umbrella framework (or dynamic library). Zero or more sub_library - * shared libraries may be use by an umbrella framework or (or dynamic library). - * The name of a sub_library framework is recorded in the following structure. - * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". - */ -struct sub_library_command { - uint32_t cmd; /* LC_SUB_LIBRARY */ - uint32_t cmdsize; /* includes sub_library string */ - union lc_str sub_library; /* the sub_library name */ -}; - -/* - * A program (filetype == MH_EXECUTE) that is - * prebound to its dynamic libraries has one of these for each library that - * the static linker used in prebinding. It contains a bit vector for the - * modules in the library. The bits indicate which modules are bound (1) and - * which are not (0) from the library. The bit for module 0 is the low bit - * of the first byte. So the bit for the Nth module is: - * (linked_modules[N/8] >> N%8) & 1 - */ -struct prebound_dylib_command { - uint32_t cmd; /* LC_PREBOUND_DYLIB */ - uint32_t cmdsize; /* includes strings */ - union lc_str name; /* library's path name */ - uint32_t nmodules; /* number of modules in library */ - union lc_str linked_modules; /* bit vector of linked modules */ -}; - -/* - * A program that uses a dynamic linker contains a dylinker_command to identify - * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker - * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). - * A file can have at most one of these. - * This struct is also used for the LC_DYLD_ENVIRONMENT load command and - * contains string for dyld to treat like environment variable. - */ -struct dylinker_command { - uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or - LC_DYLD_ENVIRONMENT */ - uint32_t cmdsize; /* includes pathname string */ - union lc_str name; /* dynamic linker's path name */ -}; - -/* - * Thread commands contain machine-specific data structures suitable for - * use in the thread state primitives. The machine specific data structures - * follow the struct thread_command as follows. - * Each flavor of machine specific data structure is preceded by an unsigned - * long constant for the flavor of that data structure, an uint32_t - * that is the count of longs of the size of the state data structure and then - * the state data structure follows. This triple may be repeated for many - * flavors. The constants for the flavors, counts and state data structure - * definitions are expected to be in the header file . - * These machine specific data structures sizes must be multiples of - * 4 bytes The cmdsize reflects the total size of the thread_command - * and all of the sizes of the constants for the flavors, counts and state - * data structures. - * - * For executable objects that are unix processes there will be one - * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor. - * This is the same as a LC_THREAD, except that a stack is automatically - * created (based on the shell's limit for the stack size). Command arguments - * and environment variables are copied onto that stack. - */ -struct thread_command { - uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */ - uint32_t cmdsize; /* total size of this command */ - /* uint32_t flavor flavor of thread state */ - /* uint32_t count count of longs in thread state */ - /* struct XXX_thread_state state thread state for this flavor */ - /* ... */ -}; - -/* - * The routines command contains the address of the dynamic shared library - * initialization routine and an index into the module table for the module - * that defines the routine. Before any modules are used from the library the - * dynamic linker fully binds the module that defines the initialization routine - * and then calls it. This gets called before any module initialization - * routines (used for C++ static constructors) in the library. - */ -struct routines_command { /* for 32-bit architectures */ - uint32_t cmd; /* LC_ROUTINES */ - uint32_t cmdsize; /* total size of this command */ - uint32_t init_address; /* address of initialization routine */ - uint32_t init_module; /* index into the module table that */ - /* the init routine is defined in */ - uint32_t reserved1; - uint32_t reserved2; - uint32_t reserved3; - uint32_t reserved4; - uint32_t reserved5; - uint32_t reserved6; -}; - -/* - * The 64-bit routines command. Same use as above. - */ -struct routines_command_64 { /* for 64-bit architectures */ - uint32_t cmd; /* LC_ROUTINES_64 */ - uint32_t cmdsize; /* total size of this command */ - uint64_t init_address; /* address of initialization routine */ - uint64_t init_module; /* index into the module table that */ - /* the init routine is defined in */ - uint64_t reserved1; - uint64_t reserved2; - uint64_t reserved3; - uint64_t reserved4; - uint64_t reserved5; - uint64_t reserved6; -}; - -/* - * The symtab_command contains the offsets and sizes of the link-edit 4.3BSD - * "stab" style symbol table information as described in the header files - * and . - */ -struct symtab_command { - uint32_t cmd; /* LC_SYMTAB */ - uint32_t cmdsize; /* sizeof(struct symtab_command) */ - uint32_t symoff; /* symbol table offset */ - uint32_t nsyms; /* number of symbol table entries */ - uint32_t stroff; /* string table offset */ - uint32_t strsize; /* string table size in bytes */ -}; - -/* - * This is the second set of the symbolic information which is used to support - * the data structures for the dynamically link editor. - * - * The original set of symbolic information in the symtab_command which contains - * the symbol and string tables must also be present when this load command is - * present. When this load command is present the symbol table is organized - * into three groups of symbols: - * local symbols (static and debugging symbols) - grouped by module - * defined external symbols - grouped by module (sorted by name if not lib) - * undefined external symbols (sorted by name if MH_BINDATLOAD is not set, - * and in order the were seen by the static - * linker if MH_BINDATLOAD is set) - * In this load command there are offsets and counts to each of the three groups - * of symbols. - * - * This load command contains a the offsets and sizes of the following new - * symbolic information tables: - * table of contents - * module table - * reference symbol table - * indirect symbol table - * The first three tables above (the table of contents, module table and - * reference symbol table) are only present if the file is a dynamically linked - * shared library. For executable and object modules, which are files - * containing only one module, the information that would be in these three - * tables is determined as follows: - * table of contents - the defined external symbols are sorted by name - * module table - the file contains only one module so everything in the - * file is part of the module. - * reference symbol table - is the defined and undefined external symbols - * - * For dynamically linked shared library files this load command also contains - * offsets and sizes to the pool of relocation entries for all sections - * separated into two groups: - * external relocation entries - * local relocation entries - * For executable and object modules the relocation entries continue to hang - * off the section structures. - */ -struct dysymtab_command { - uint32_t cmd; /* LC_DYSYMTAB */ - uint32_t cmdsize; /* sizeof(struct dysymtab_command) */ - - /* - * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command - * are grouped into the following three groups: - * local symbols (further grouped by the module they are from) - * defined external symbols (further grouped by the module they are from) - * undefined symbols - * - * The local symbols are used only for debugging. The dynamic binding - * process may have to use them to indicate to the debugger the local - * symbols for a module that is being bound. - * - * The last two groups are used by the dynamic binding process to do the - * binding (indirectly through the module table and the reference symbol - * table when this is a dynamically linked shared library file). - */ - uint32_t ilocalsym; /* index to local symbols */ - uint32_t nlocalsym; /* number of local symbols */ - - uint32_t iextdefsym;/* index to externally defined symbols */ - uint32_t nextdefsym;/* number of externally defined symbols */ - - uint32_t iundefsym; /* index to undefined symbols */ - uint32_t nundefsym; /* number of undefined symbols */ - - /* - * For the for the dynamic binding process to find which module a symbol - * is defined in the table of contents is used (analogous to the ranlib - * structure in an archive) which maps defined external symbols to modules - * they are defined in. This exists only in a dynamically linked shared - * library file. For executable and object modules the defined external - * symbols are sorted by name and is use as the table of contents. - */ - uint32_t tocoff; /* file offset to table of contents */ - uint32_t ntoc; /* number of entries in table of contents */ - - /* - * To support dynamic binding of "modules" (whole object files) the symbol - * table must reflect the modules that the file was created from. This is - * done by having a module table that has indexes and counts into the merged - * tables for each module. The module structure that these two entries - * refer to is described below. This exists only in a dynamically linked - * shared library file. For executable and object modules the file only - * contains one module so everything in the file belongs to the module. - */ - uint32_t modtaboff; /* file offset to module table */ - uint32_t nmodtab; /* number of module table entries */ - - /* - * To support dynamic module binding the module structure for each module - * indicates the external references (defined and undefined) each module - * makes. For each module there is an offset and a count into the - * reference symbol table for the symbols that the module references. - * This exists only in a dynamically linked shared library file. For - * executable and object modules the defined external symbols and the - * undefined external symbols indicates the external references. - */ - uint32_t extrefsymoff; /* offset to referenced symbol table */ - uint32_t nextrefsyms; /* number of referenced symbol table entries */ - - /* - * The sections that contain "symbol pointers" and "routine stubs" have - * indexes and (implied counts based on the size of the section and fixed - * size of the entry) into the "indirect symbol" table for each pointer - * and stub. For every section of these two types the index into the - * indirect symbol table is stored in the section header in the field - * reserved1. An indirect symbol table entry is simply a 32bit index into - * the symbol table to the symbol that the pointer or stub is referring to. - * The indirect symbol table is ordered to match the entries in the section. - */ - uint32_t indirectsymoff; /* file offset to the indirect symbol table */ - uint32_t nindirectsyms; /* number of indirect symbol table entries */ - - /* - * To support relocating an individual module in a library file quickly the - * external relocation entries for each module in the library need to be - * accessed efficiently. Since the relocation entries can't be accessed - * through the section headers for a library file they are separated into - * groups of local and external entries further grouped by module. In this - * case the presents of this load command who's extreloff, nextrel, - * locreloff and nlocrel fields are non-zero indicates that the relocation - * entries of non-merged sections are not referenced through the section - * structures (and the reloff and nreloc fields in the section headers are - * set to zero). - * - * Since the relocation entries are not accessed through the section headers - * this requires the r_address field to be something other than a section - * offset to identify the item to be relocated. In this case r_address is - * set to the offset from the vmaddr of the first LC_SEGMENT command. - * For MH_SPLIT_SEGS images r_address is set to the the offset from the - * vmaddr of the first read-write LC_SEGMENT command. - * - * The relocation entries are grouped by module and the module table - * entries have indexes and counts into them for the group of external - * relocation entries for that the module. - * - * For sections that are merged across modules there must not be any - * remaining external relocation entries for them (for merged sections - * remaining relocation entries must be local). - */ - uint32_t extreloff; /* offset to external relocation entries */ - uint32_t nextrel; /* number of external relocation entries */ - - /* - * All the local relocation entries are grouped together (they are not - * grouped by their module since they are only used if the object is moved - * from it staticly link edited address). - */ - uint32_t locreloff; /* offset to local relocation entries */ - uint32_t nlocrel; /* number of local relocation entries */ - -}; - -/* - * An indirect symbol table entry is simply a 32bit index into the symbol table - * to the symbol that the pointer or stub is refering to. Unless it is for a - * non-lazy symbol pointer section for a defined symbol which strip(1) as - * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the - * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. - */ -#define INDIRECT_SYMBOL_LOCAL 0x80000000 -#define INDIRECT_SYMBOL_ABS 0x40000000 - - -/* a table of contents entry */ -struct dylib_table_of_contents { - uint32_t symbol_index; /* the defined external symbol - (index into the symbol table) */ - uint32_t module_index; /* index into the module table this symbol - is defined in */ -}; - -/* a module table entry */ -struct dylib_module { - uint32_t module_name; /* the module name (index into string table) */ - - uint32_t iextdefsym; /* index into externally defined symbols */ - uint32_t nextdefsym; /* number of externally defined symbols */ - uint32_t irefsym; /* index into reference symbol table */ - uint32_t nrefsym; /* number of reference symbol table entries */ - uint32_t ilocalsym; /* index into symbols for local symbols */ - uint32_t nlocalsym; /* number of local symbols */ - - uint32_t iextrel; /* index into external relocation entries */ - uint32_t nextrel; /* number of external relocation entries */ - - uint32_t iinit_iterm; /* low 16 bits are the index into the init - section, high 16 bits are the index into - the term section */ - uint32_t ninit_nterm; /* low 16 bits are the number of init section - entries, high 16 bits are the number of - term section entries */ - - uint32_t /* for this module address of the start of */ - objc_module_info_addr; /* the (__OBJC,__module_info) section */ - uint32_t /* for this module size of */ - objc_module_info_size; /* the (__OBJC,__module_info) section */ -}; - -/* a 64-bit module table entry */ -struct dylib_module_64 { - uint32_t module_name; /* the module name (index into string table) */ - - uint32_t iextdefsym; /* index into externally defined symbols */ - uint32_t nextdefsym; /* number of externally defined symbols */ - uint32_t irefsym; /* index into reference symbol table */ - uint32_t nrefsym; /* number of reference symbol table entries */ - uint32_t ilocalsym; /* index into symbols for local symbols */ - uint32_t nlocalsym; /* number of local symbols */ - - uint32_t iextrel; /* index into external relocation entries */ - uint32_t nextrel; /* number of external relocation entries */ - - uint32_t iinit_iterm; /* low 16 bits are the index into the init - section, high 16 bits are the index into - the term section */ - uint32_t ninit_nterm; /* low 16 bits are the number of init section - entries, high 16 bits are the number of - term section entries */ - - uint32_t /* for this module size of */ - objc_module_info_size; /* the (__OBJC,__module_info) section */ - uint64_t /* for this module address of the start of */ - objc_module_info_addr; /* the (__OBJC,__module_info) section */ -}; - -/* - * The entries in the reference symbol table are used when loading the module - * (both by the static and dynamic link editors) and if the module is unloaded - * or replaced. Therefore all external symbols (defined and undefined) are - * listed in the module's reference table. The flags describe the type of - * reference that is being made. The constants for the flags are defined in - * as they are also used for symbol table entries. - */ -struct dylib_reference { - uint32_t isym:24, /* index into the symbol table */ - flags:8; /* flags to indicate the type of reference */ -}; - -/* - * The twolevel_hints_command contains the offset and number of hints in the - * two-level namespace lookup hints table. - */ -struct twolevel_hints_command { - uint32_t cmd; /* LC_TWOLEVEL_HINTS */ - uint32_t cmdsize; /* sizeof(struct twolevel_hints_command) */ - uint32_t offset; /* offset to the hint table */ - uint32_t nhints; /* number of hints in the hint table */ -}; - -/* - * The entries in the two-level namespace lookup hints table are twolevel_hint - * structs. These provide hints to the dynamic link editor where to start - * looking for an undefined symbol in a two-level namespace image. The - * isub_image field is an index into the sub-images (sub-frameworks and - * sub-umbrellas list) that made up the two-level image that the undefined - * symbol was found in when it was built by the static link editor. If - * isub-image is 0 the the symbol is expected to be defined in library and not - * in the sub-images. If isub-image is non-zero it is an index into the array - * of sub-images for the umbrella with the first index in the sub-images being - * 1. The array of sub-images is the ordered list of sub-images of the umbrella - * that would be searched for a symbol that has the umbrella recorded as its - * primary library. The table of contents index is an index into the - * library's table of contents. This is used as the starting point of the - * binary search or a directed linear search. - */ -struct twolevel_hint { - uint32_t - isub_image:8, /* index into the sub images */ - itoc:24; /* index into the table of contents */ -}; - -/* - * The prebind_cksum_command contains the value of the original check sum for - * prebound files or zero. When a prebound file is first created or modified - * for other than updating its prebinding information the value of the check sum - * is set to zero. When the file has it prebinding re-done and if the value of - * the check sum is zero the original check sum is calculated and stored in - * cksum field of this load command in the output file. If when the prebinding - * is re-done and the cksum field is non-zero it is left unchanged from the - * input file. - */ -struct prebind_cksum_command { - uint32_t cmd; /* LC_PREBIND_CKSUM */ - uint32_t cmdsize; /* sizeof(struct prebind_cksum_command) */ - uint32_t cksum; /* the check sum or zero */ -}; - -/* - * The uuid load command contains a single 128-bit unique random number that - * identifies an object produced by the static link editor. - */ -struct uuid_command { - uint32_t cmd; /* LC_UUID */ - uint32_t cmdsize; /* sizeof(struct uuid_command) */ - uint8_t uuid[16]; /* the 128-bit uuid */ -}; - -/* - * The rpath_command contains a path which at runtime should be added to - * the current run path used to find @rpath prefixed dylibs. - */ -struct rpath_command { - uint32_t cmd; /* LC_RPATH */ - uint32_t cmdsize; /* includes string */ - union lc_str path; /* path to add to run path */ -}; - -/* - * The linkedit_data_command contains the offsets and sizes of a blob - * of data in the __LINKEDIT segment. - */ -struct linkedit_data_command { - uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, - or LC_FUNCTION_STARTS */ - uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */ - uint32_t dataoff; /* file offset of data in __LINKEDIT segment */ - uint32_t datasize; /* file size of data in __LINKEDIT segment */ -}; - -/* - * The encryption_info_command contains the file offset and size of an - * of an encrypted segment. - */ -struct encryption_info_command { - uint32_t cmd; /* LC_ENCRYPTION_INFO */ - uint32_t cmdsize; /* sizeof(struct encryption_info_command) */ - uint32_t cryptoff; /* file offset of encrypted range */ - uint32_t cryptsize; /* file size of encrypted range */ - uint32_t cryptid; /* which enryption system, - 0 means not-encrypted yet */ -}; - -/* - * The version_min_command contains the min OS version on which this - * binary was built to run. - */ -struct version_min_command { - uint32_t cmd; /* LC_VERSION_MIN_MACOSX or - LC_VERSION_MIN_IPHONEOS */ - uint32_t cmdsize; /* sizeof(struct min_version_command) */ - uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ - uint32_t reserved; /* zero */ -}; - -/* - * The dyld_info_command contains the file offsets and sizes of - * the new compressed form of the information dyld needs to - * load the image. This information is used by dyld on Mac OS X - * 10.6 and later. All information pointed to by this command - * is encoded using byte streams, so no endian swapping is needed - * to interpret it. - */ -struct dyld_info_command { - uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ - uint32_t cmdsize; /* sizeof(struct dyld_info_command) */ - - /* - * Dyld rebases an image whenever dyld loads it at an address different - * from its preferred address. The rebase information is a stream - * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. - * Conceptually the rebase information is a table of tuples: - * - * The opcodes are a compressed way to encode the table by only - * encoding when a column changes. In addition simple patterns - * like "every n'th offset for m times" can be encoded in a few - * bytes. - */ - uint32_t rebase_off; /* file offset to rebase info */ - uint32_t rebase_size; /* size of rebase info */ - - /* - * Dyld binds an image during the loading process, if the image - * requires any pointers to be initialized to symbols in other images. - * The bind information is a stream of byte sized - * opcodes whose symbolic names start with BIND_OPCODE_. - * Conceptually the bind information is a table of tuples: - * - * The opcodes are a compressed way to encode the table by only - * encoding when a column changes. In addition simple patterns - * like for runs of pointers initialzed to the same value can be - * encoded in a few bytes. - */ - uint32_t bind_off; /* file offset to binding info */ - uint32_t bind_size; /* size of binding info */ - - /* - * Some C++ programs require dyld to unique symbols so that all - * images in the process use the same copy of some code/data. - * This step is done after binding. The content of the weak_bind - * info is an opcode stream like the bind_info. But it is sorted - * alphabetically by symbol name. This enable dyld to walk - * all images with weak binding information in order and look - * for collisions. If there are no collisions, dyld does - * no updating. That means that some fixups are also encoded - * in the bind_info. For instance, all calls to "operator new" - * are first bound to libstdc++.dylib using the information - * in bind_info. Then if some image overrides operator new - * that is detected when the weak_bind information is processed - * and the call to operator new is then rebound. - */ - uint32_t weak_bind_off; /* file offset to weak binding info */ - uint32_t weak_bind_size; /* size of weak binding info */ - - /* - * Some uses of external symbols do not need to be bound immediately. - * Instead they can be lazily bound on first use. The lazy_bind - * are contains a stream of BIND opcodes to bind all lazy symbols. - * Normal use is that dyld ignores the lazy_bind section when - * loading an image. Instead the static linker arranged for the - * lazy pointer to initially point to a helper function which - * pushes the offset into the lazy_bind area for the symbol - * needing to be bound, then jumps to dyld which simply adds - * the offset to lazy_bind_off to get the information on what - * to bind. - */ - uint32_t lazy_bind_off; /* file offset to lazy binding info */ - uint32_t lazy_bind_size; /* size of lazy binding infs */ - - /* - * The symbols exported by a dylib are encoded in a trie. This - * is a compact representation that factors out common prefixes. - * It also reduces LINKEDIT pages in RAM because it encodes all - * information (name, address, flags) in one small, contiguous range. - * The export area is a stream of nodes. The first node sequentially - * is the start node for the trie. - * - * Nodes for a symbol start with a uleb128 that is the length of - * the exported symbol information for the string so far. - * If there is no exported symbol, the node starts with a zero byte. - * If there is exported info, it follows the length. First is - * a uleb128 containing flags. Normally, it is followed by a - * uleb128 encoded offset which is location of the content named - * by the symbol from the mach_header for the image. If the flags - * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is - * a uleb128 encoded library ordinal, then a zero terminated - * UTF8 string. If the string is zero length, then the symbol - * is re-export from the specified dylib with the same name. - * - * After the optional exported symbol information is a byte of - * how many edges (0-255) that this node has leaving it, - * followed by each edge. - * Each edge is a zero terminated UTF8 of the addition chars - * in the symbol, followed by a uleb128 offset for the node that - * edge points to. - * - */ - uint32_t export_off; /* file offset to lazy binding info */ - uint32_t export_size; /* size of lazy binding infs */ -}; - -/* - * The following are used to encode rebasing information - */ -#define REBASE_TYPE_POINTER 1 -#define REBASE_TYPE_TEXT_ABSOLUTE32 2 -#define REBASE_TYPE_TEXT_PCREL32 3 - -#define REBASE_OPCODE_MASK 0xF0 -#define REBASE_IMMEDIATE_MASK 0x0F -#define REBASE_OPCODE_DONE 0x00 -#define REBASE_OPCODE_SET_TYPE_IMM 0x10 -#define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 -#define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 -#define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 -#define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 -#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 -#define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 -#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 - - -/* - * The following are used to encode binding information - */ -#define BIND_TYPE_POINTER 1 -#define BIND_TYPE_TEXT_ABSOLUTE32 2 -#define BIND_TYPE_TEXT_PCREL32 3 - -#define BIND_SPECIAL_DYLIB_SELF 0 -#define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 -#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 - -#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 -#define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 - -#define BIND_OPCODE_MASK 0xF0 -#define BIND_IMMEDIATE_MASK 0x0F -#define BIND_OPCODE_DONE 0x00 -#define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 -#define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 -#define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 -#define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 -#define BIND_OPCODE_SET_TYPE_IMM 0x50 -#define BIND_OPCODE_SET_ADDEND_SLEB 0x60 -#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 -#define BIND_OPCODE_ADD_ADDR_ULEB 0x80 -#define BIND_OPCODE_DO_BIND 0x90 -#define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 -#define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 -#define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 - - -/* - * The following are used on the flags byte of a terminal node - * in the export information. - */ -#define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 -#define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 -#define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 -#define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 -#define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 -#define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 - -/* - * The symseg_command contains the offset and size of the GNU style - * symbol table information as described in the header file . - * The symbol roots of the symbol segments must also be aligned properly - * in the file. So the requirement of keeping the offsets aligned to a - * multiple of a 4 bytes translates to the length field of the symbol - * roots also being a multiple of a long. Also the padding must again be - * zeroed. (THIS IS OBSOLETE and no longer supported). - */ -struct symseg_command { - uint32_t cmd; /* LC_SYMSEG */ - uint32_t cmdsize; /* sizeof(struct symseg_command) */ - uint32_t offset; /* symbol segment offset */ - uint32_t size; /* symbol segment size in bytes */ -}; - -/* - * The ident_command contains a free format string table following the - * ident_command structure. The strings are null terminated and the size of - * the command is padded out with zero bytes to a multiple of 4 bytes/ - * (THIS IS OBSOLETE and no longer supported). - */ -struct ident_command { - uint32_t cmd; /* LC_IDENT */ - uint32_t cmdsize; /* strings that follow this command */ -}; - -/* - * The fvmfile_command contains a reference to a file to be loaded at the - * specified virtual address. (Presently, this command is reserved for - * internal use. The kernel ignores this command when loading a program into - * memory). - */ -struct fvmfile_command { - uint32_t cmd; /* LC_FVMFILE */ - uint32_t cmdsize; /* includes pathname string */ - union lc_str name; /* files pathname */ - uint32_t header_addr; /* files virtual address */ -}; - -/* - * Sections of type S_THREAD_LOCAL_VARIABLES contain an array - * of tlv_descriptor structures. - */ -struct tlv_descriptor -{ - void* (*thunk)(struct tlv_descriptor*); - unsigned long key; - unsigned long offset; -}; - -#endif /* _MACHO_LOADER_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/nlist.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/nlist.h deleted file mode 100644 index 1c1941012..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach-o/nlist.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _MACHO_NLIST_H_ -#define _MACHO_NLIST_H_ -/* $NetBSD: nlist.h,v 1.5 1994/10/26 00:56:11 cgd Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nlist.h 8.2 (Berkeley) 1/21/94 - */ -#include - -/* - * Format of a symbol table entry of a Mach-O file for 32-bit architectures. - * Modified from the BSD format. The modifications from the original format - * were changing n_other (an unused field) to n_sect and the addition of the - * N_SECT type. These modifications are required to support symbols in a larger - * number of sections not just the three sections (text, data and bss) in a BSD - * file. - */ -struct nlist { - union { -#ifndef __LP64__ - char *n_name; /* for use when in-core */ -#endif - int32_t n_strx; /* index into the string table */ - } n_un; - uint8_t n_type; /* type flag, see below */ - uint8_t n_sect; /* section number or NO_SECT */ - int16_t n_desc; /* see */ - uint32_t n_value; /* value of this symbol (or stab offset) */ -}; - -/* - * This is the symbol table entry structure for 64-bit architectures. - */ -struct nlist_64 { - union { - uint32_t n_strx; /* index into the string table */ - } n_un; - uint8_t n_type; /* type flag, see below */ - uint8_t n_sect; /* section number or NO_SECT */ - uint16_t n_desc; /* see */ - uint64_t n_value; /* value of this symbol (or stab offset) */ -}; - -/* - * Symbols with a index into the string table of zero (n_un.n_strx == 0) are - * defined to have a null, "", name. Therefore all string indexes to non null - * names must not have a zero string index. This is bit historical information - * that has never been well documented. - */ - -/* - * The n_type field really contains four fields: - * unsigned char N_STAB:3, - * N_PEXT:1, - * N_TYPE:3, - * N_EXT:1; - * which are used via the following masks. - */ -#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */ -#define N_PEXT 0x10 /* private external symbol bit */ -#define N_TYPE 0x0e /* mask for the type bits */ -#define N_EXT 0x01 /* external symbol bit, set for external symbols */ - -/* - * Only symbolic debugging entries have some of the N_STAB bits set and if any - * of these bits are set then it is a symbolic debugging entry (a stab). In - * which case then the values of the n_type field (the entire field) are given - * in - */ - -/* - * Values for N_TYPE bits of the n_type field. - */ -#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */ -#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */ -#define N_SECT 0xe /* defined in section number n_sect */ -#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */ -#define N_INDR 0xa /* indirect */ - -/* - * If the type is N_INDR then the symbol is defined to be the same as another - * symbol. In this case the n_value field is an index into the string table - * of the other symbol's name. When the other symbol is defined then they both - * take on the defined type and value. - */ - -/* - * If the type is N_SECT then the n_sect field contains an ordinal of the - * section the symbol is defined in. The sections are numbered from 1 and - * refer to sections in order they appear in the load commands for the file - * they are in. This means the same ordinal may very well refer to different - * sections in different files. - * - * The n_value field for all symbol table entries (including N_STAB's) gets - * updated by the link editor based on the value of it's n_sect field and where - * the section n_sect references gets relocated. If the value of the n_sect - * field is NO_SECT then it's n_value field is not changed by the link editor. - */ -#define NO_SECT 0 /* symbol is not in any section */ -#define MAX_SECT 255 /* 1 thru 255 inclusive */ - -/* - * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types - * who's values (n_value) are non-zero. In which case the value of the n_value - * field is the size (in bytes) of the common symbol. The n_sect field is set - * to NO_SECT. The alignment of a common symbol may be set as a power of 2 - * between 2^1 and 2^15 as part of the n_desc field using the macros below. If - * the alignment is not set (a value of zero) then natural alignment based on - * the size is used. - */ -#define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f) -#define SET_COMM_ALIGN(n_desc,align) \ - (n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8)) - -/* - * To support the lazy binding of undefined symbols in the dynamic link-editor, - * the undefined symbols in the symbol table (the nlist structures) are marked - * with the indication if the undefined reference is a lazy reference or - * non-lazy reference. If both a non-lazy reference and a lazy reference is - * made to the same symbol the non-lazy reference takes precedence. A reference - * is lazy only when all references to that symbol are made through a symbol - * pointer in a lazy symbol pointer section. - * - * The implementation of marking nlist structures in the symbol table for - * undefined symbols will be to use some of the bits of the n_desc field as a - * reference type. The mask REFERENCE_TYPE will be applied to the n_desc field - * of an nlist structure for an undefined symbol to determine the type of - * undefined reference (lazy or non-lazy). - * - * The constants for the REFERENCE FLAGS are propagated to the reference table - * in a shared library file. In that case the constant for a defined symbol, - * REFERENCE_FLAG_DEFINED, is also used. - */ -/* Reference type bits of the n_desc field of undefined symbols */ -#define REFERENCE_TYPE 0x7 -/* types of references */ -#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0 -#define REFERENCE_FLAG_UNDEFINED_LAZY 1 -#define REFERENCE_FLAG_DEFINED 2 -#define REFERENCE_FLAG_PRIVATE_DEFINED 3 -#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4 -#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5 - -/* - * To simplify stripping of objects that use are used with the dynamic link - * editor, the static link editor marks the symbols defined an object that are - * referenced by a dynamicly bound object (dynamic shared libraries, bundles). - * With this marking strip knows not to strip these symbols. - */ -#define REFERENCED_DYNAMICALLY 0x0010 - -/* - * For images created by the static link editor with the -twolevel_namespace - * option in effect the flags field of the mach header is marked with - * MH_TWOLEVEL. And the binding of the undefined references of the image are - * determined by the static link editor. Which library an undefined symbol is - * bound to is recorded by the static linker in the high 8 bits of the n_desc - * field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded - * references the libraries listed in the Mach-O's LC_LOAD_DYLIB, - * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and - * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the - * headers. The library ordinals start from 1. - * For a dynamic library that is built as a two-level namespace image the - * undefined references from module defined in another use the same nlist struct - * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For - * defined symbols in all images they also must have the library ordinal set to - * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable - * image for references from plugins that refer to the executable that loads - * them. - * - * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace - * image that are looked up by the dynamic linker with flat namespace semantics. - * This ordinal was added as a feature in Mac OS X 10.3 by reducing the - * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries - * or binaries built with older tools to have 0xfe (254) dynamic libraries. In - * this case the ordinal value 0xfe (254) must be treated as a library ordinal - * for compatibility. - */ -#define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff) -#define SET_LIBRARY_ORDINAL(n_desc,ordinal) \ - (n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)) -#define SELF_LIBRARY_ORDINAL 0x0 -#define MAX_LIBRARY_ORDINAL 0xfd -#define DYNAMIC_LOOKUP_ORDINAL 0xfe -#define EXECUTABLE_ORDINAL 0xff - -/* - * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes - * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED. - */ - -/* - * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a - * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the - * static link editor it is never to dead strip the symbol. - */ -#define N_NO_DEAD_STRIP 0x0020 /* symbol is not to be dead stripped */ - -/* - * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image. - * But is used in very rare cases by the dynamic link editor to mark an in - * memory symbol as discared and longer used for linking. - */ -#define N_DESC_DISCARDED 0x0020 /* symbol is discarded */ - -/* - * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that - * the undefined symbol is allowed to be missing and is to have the address of - * zero when missing. - */ -#define N_WEAK_REF 0x0040 /* symbol is weak referenced */ - -/* - * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic - * linkers that the symbol definition is weak, allowing a non-weak symbol to - * also be used which causes the weak definition to be discared. Currently this - * is only supported for symbols in coalesed sections. - */ -#define N_WEAK_DEF 0x0080 /* coalesed symbol is a weak definition */ - -/* - * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker - * that the undefined symbol should be resolved using flat namespace searching. - */ -#define N_REF_TO_WEAK 0x0080 /* reference to a weak symbol */ - -/* - * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is - * a defintion of a Thumb function. - */ -#define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */ - -/* - * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the - * that the function is actually a resolver function and should - * be called to get the address of the real function to use. - * This bit is only available in .o files (MH_OBJECT filetype) - */ -#define N_SYMBOL_RESOLVER 0x0100 - -#ifndef __STRICT_BSD__ -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -/* - * The function nlist(3) from the C library. - */ -extern int nlist (const char *filename, struct nlist *list); -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __STRICT_BSD__ */ - -#endif /* _MACHO_LIST_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/boolean.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/boolean.h deleted file mode 100644 index 641c3962d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/boolean.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ -/* - * File: mach/boolean.h - * - * Boolean data type. - * - */ - -#ifndef _MACH_BOOLEAN_H_ -#define _MACH_BOOLEAN_H_ - -/* - * Pick up "boolean_t" type definition - */ - -#ifndef ASSEMBLER -#include -#endif /* ASSEMBLER */ - -/* - * Define TRUE and FALSE if not defined. - */ - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ - -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -#endif /* _MACH_BOOLEAN_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/boolean.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/boolean.h deleted file mode 100644 index 100f7e7b5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/boolean.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ - -/* - * File: boolean.h - * - * Boolean type, for I386. - */ - -#ifndef _MACH_I386_BOOLEAN_H_ -#define _MACH_I386_BOOLEAN_H_ - -#if defined(__x86_64__) && !defined(KERNEL) -typedef unsigned int boolean_t; -#else -typedef int boolean_t; -#endif - -#endif /* _MACH_I386_BOOLEAN_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_param.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_param.h deleted file mode 100644 index edcb83496..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_param.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Copyright (c) 1994 The University of Utah and - * the Computer Systems Laboratory at the University of Utah (CSL). - * All rights reserved. - * - * Permission to use, copy, modify and distribute this software is hereby - * granted provided that (1) source code retains these copyright, permission, - * and disclaimer notices, and (2) redistributions including binaries - * reproduce the notices in supporting documentation, and (3) all advertising - * materials mentioning features or use of this software display the following - * acknowledgement: ``This product includes software developed by the - * Computer Systems Laboratory at the University of Utah.'' - * - * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS - * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF - * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * CSL requests users of this software to return to csl-dist@cs.utah.edu any - * improvements that they make and grant CSL redistribution rights. - * - */ - -/* - * File: vm_param.h - * Author: Avadis Tevanian, Jr. - * Date: 1985 - * - * I386 machine dependent virtual memory parameters. - * Most of the declarations are preceeded by I386_ (or i386_) - * which is OK because only I386 specific code will be using - * them. - */ - -#ifndef _MACH_I386_VM_PARAM_H_ -#define _MACH_I386_VM_PARAM_H_ - -#define BYTE_SIZE 8 /* byte size in bits */ - -#define I386_PGBYTES 4096 /* bytes per 80386 page */ -#define I386_PGSHIFT 12 /* bitshift for pages */ - -#define PAGE_SIZE I386_PGBYTES -#define PAGE_SHIFT I386_PGSHIFT -#define PAGE_MASK (PAGE_SIZE - 1) - -#define I386_LPGBYTES 2*1024*1024 /* bytes per large page */ -#define I386_LPGSHIFT 21 /* bitshift for large pages */ -#define I386_LPGMASK (I386_LPGBYTES-1) - -/* - * Convert bytes to pages and convert pages to bytes. - * No rounding is used. - */ - -#define i386_btop(x) ((ppnum_t)((x) >> I386_PGSHIFT)) -#define machine_btop(x) i386_btop(x) -#define i386_ptob(x) (((pmap_paddr_t)(x)) << I386_PGSHIFT) - -/* - * Round off or truncate to the nearest page. These will work - * for either addresses or counts. (i.e. 1 byte rounds to 1 page - * bytes. - */ - -#define i386_round_page(x) ((((pmap_paddr_t)(x)) + I386_PGBYTES - 1) & \ - ~(I386_PGBYTES-1)) -#define i386_trunc_page(x) (((pmap_paddr_t)(x)) & ~(I386_PGBYTES-1)) - - - -#define VM_MIN_ADDRESS64 ((user_addr_t) 0x0000000000000000ULL) -/* - * default top of user stack... it grows down from here - */ -#define VM_USRSTACK64 ((user_addr_t) 0x00007FFF5FC00000ULL) -#define VM_DYLD64 ((user_addr_t) 0x00007FFF5FC00000ULL) -#define VM_LIB64_SHR_DATA ((user_addr_t) 0x00007FFF60000000ULL) -#define VM_LIB64_SHR_TEXT ((user_addr_t) 0x00007FFF80000000ULL) -/* - * the end of the usable user address space , for now about 47 bits. - * the 64 bit commpage is past the end of this - */ -#define VM_MAX_PAGE_ADDRESS ((user_addr_t) 0x00007FFFFFE00000ULL) -/* - * canonical end of user address space for limits checking - */ -#define VM_MAX_USER_PAGE_ADDRESS ((user_addr_t)0x00007FFFFFFFF000ULL) - - -/* system-wide values */ -#define MACH_VM_MIN_ADDRESS ((mach_vm_offset_t) 0) -#define MACH_VM_MAX_ADDRESS ((mach_vm_offset_t) VM_MAX_PAGE_ADDRESS) - -/* process-relative values (all 32-bit legacy only for now) */ -#define VM_MIN_ADDRESS ((vm_offset_t) 0) -#define VM_USRSTACK32 ((vm_offset_t) 0xC0000000) -#define VM_MAX_ADDRESS ((vm_offset_t) 0xFFE00000) - - - -#endif /* _MACH_I386_VM_PARAM_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_types.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_types.h deleted file mode 100644 index 2c38fa2d7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/i386/vm_types.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ - -/* - * File: vm_types.h - * Author: Avadis Tevanian, Jr. - * Date: 1985 - * - * Header file for VM data types. I386 version. - */ - -#ifndef _MACH_I386_VM_TYPES_H_ -#define _MACH_I386_VM_TYPES_H_ - -#ifndef ASSEMBLER - -#include -#include -#include - -/* - * natural_t and integer_t are Mach's legacy types for machine- - * independent integer types (unsigned, and signed, respectively). - * Their original purpose was to define other types in a machine/ - * compiler independent way. - * - * They also had an implicit "same size as pointer" characteristic - * to them (i.e. Mach's traditional types are very ILP32 or ILP64 - * centric). We support x86 ABIs that do not follow either of - * these models (specifically LP64). Therefore, we had to make a - * choice between making these types scale with pointers or stay - * tied to integers. Because their use is predominantly tied to - * to the size of an integer, we are keeping that association and - * breaking free from pointer size guarantees. - * - * New use of these types is discouraged. - */ -typedef __darwin_natural_t natural_t; -typedef int integer_t; - -/* - * A vm_offset_t is a type-neutral pointer, - * e.g. an offset into a virtual memory space. - */ -#ifdef __LP64__ -typedef uintptr_t vm_offset_t; -#else /* __LP64__ */ -typedef natural_t vm_offset_t; -#endif /* __LP64__ */ - -/* - * A vm_size_t is the proper type for e.g. - * expressing the difference between two - * vm_offset_t entities. - */ -#ifdef __LP64__ -typedef uintptr_t vm_size_t; -#else /* __LP64__ */ -typedef natural_t vm_size_t; -#endif /* __LP64__ */ - -/* - * This new type is independent of a particular vm map's - * implementation size - and represents appropriate types - * for all possible maps. This is used for interfaces - * where the size of the map is not known - or we don't - * want to have to distinguish. - */ -typedef uint64_t mach_vm_address_t; -typedef uint64_t mach_vm_offset_t; -typedef uint64_t mach_vm_size_t; - -typedef uint64_t vm_map_offset_t; -typedef uint64_t vm_map_address_t; -typedef uint64_t vm_map_size_t; - - -#endif /* ASSEMBLER */ - -/* - * If composing messages by hand (please do not) - */ -#define MACH_MSG_TYPE_INTEGER_T MACH_MSG_TYPE_INTEGER_32 - -#endif /* _MACH_I386_VM_TYPES_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine.h deleted file mode 100644 index 91d9d709b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (c) 2000-2007 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* File: machine.h - * Author: Avadis Tevanian, Jr. - * Date: 1986 - * - * Machine independent machine abstraction. - */ - -#ifndef _MACH_MACHINE_H_ -#define _MACH_MACHINE_H_ - -#include -#include -#include - -typedef integer_t cpu_type_t; -typedef integer_t cpu_subtype_t; -typedef integer_t cpu_threadtype_t; - -#define CPU_STATE_MAX 4 - -#define CPU_STATE_USER 0 -#define CPU_STATE_SYSTEM 1 -#define CPU_STATE_IDLE 2 -#define CPU_STATE_NICE 3 - - - -/* - * Capability bits used in the definition of cpu_type. - */ -#define CPU_ARCH_MASK 0xff000000 /* mask for architecture bits */ -#define CPU_ARCH_ABI64 0x01000000 /* 64 bit ABI */ - -/* - * Machine types known by all. - */ - -#define CPU_TYPE_ANY ((cpu_type_t) -1) - -#define CPU_TYPE_VAX ((cpu_type_t) 1) -/* skip ((cpu_type_t) 2) */ -/* skip ((cpu_type_t) 3) */ -/* skip ((cpu_type_t) 4) */ -/* skip ((cpu_type_t) 5) */ -#define CPU_TYPE_MC680x0 ((cpu_type_t) 6) -#define CPU_TYPE_X86 ((cpu_type_t) 7) -#define CPU_TYPE_I386 CPU_TYPE_X86 /* compatibility */ -#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) - -/* skip CPU_TYPE_MIPS ((cpu_type_t) 8) */ -/* skip ((cpu_type_t) 9) */ -#define CPU_TYPE_MC98000 ((cpu_type_t) 10) -#define CPU_TYPE_HPPA ((cpu_type_t) 11) -#define CPU_TYPE_ARM ((cpu_type_t) 12) -#define CPU_TYPE_MC88000 ((cpu_type_t) 13) -#define CPU_TYPE_SPARC ((cpu_type_t) 14) -#define CPU_TYPE_I860 ((cpu_type_t) 15) -/* skip CPU_TYPE_ALPHA ((cpu_type_t) 16) */ -/* skip ((cpu_type_t) 17) */ -#define CPU_TYPE_POWERPC ((cpu_type_t) 18) -#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) - -/* - * Machine subtypes (these are defined here, instead of in a machine - * dependent directory, so that any program can get all definitions - * regardless of where is it compiled). - */ - -/* - * Capability bits used in the definition of cpu_subtype. - */ -#define CPU_SUBTYPE_MASK 0xff000000 /* mask for feature flags */ -#define CPU_SUBTYPE_LIB64 0x80000000 /* 64 bit libraries */ - - -/* - * Object files that are hand-crafted to run on any - * implementation of an architecture are tagged with - * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as - * the "ALL" subtype of an architecture except that it allows us - * to easily find object files that may need to be modified - * whenever a new implementation of an architecture comes out. - * - * It is the responsibility of the implementor to make sure the - * software handles unsupported implementations elegantly. - */ -#define CPU_SUBTYPE_MULTIPLE ((cpu_subtype_t) -1) -#define CPU_SUBTYPE_LITTLE_ENDIAN ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_BIG_ENDIAN ((cpu_subtype_t) 1) - -/* - * Machine threadtypes. - * This is none - not defined - for most machine types/subtypes. - */ -#define CPU_THREADTYPE_NONE ((cpu_threadtype_t) 0) - -/* - * VAX subtypes (these do *not* necessary conform to the actual cpu - * ID assigned by DEC available via the SID register). - */ - -#define CPU_SUBTYPE_VAX_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_VAX780 ((cpu_subtype_t) 1) -#define CPU_SUBTYPE_VAX785 ((cpu_subtype_t) 2) -#define CPU_SUBTYPE_VAX750 ((cpu_subtype_t) 3) -#define CPU_SUBTYPE_VAX730 ((cpu_subtype_t) 4) -#define CPU_SUBTYPE_UVAXI ((cpu_subtype_t) 5) -#define CPU_SUBTYPE_UVAXII ((cpu_subtype_t) 6) -#define CPU_SUBTYPE_VAX8200 ((cpu_subtype_t) 7) -#define CPU_SUBTYPE_VAX8500 ((cpu_subtype_t) 8) -#define CPU_SUBTYPE_VAX8600 ((cpu_subtype_t) 9) -#define CPU_SUBTYPE_VAX8650 ((cpu_subtype_t) 10) -#define CPU_SUBTYPE_VAX8800 ((cpu_subtype_t) 11) -#define CPU_SUBTYPE_UVAXIII ((cpu_subtype_t) 12) - -/* - * 680x0 subtypes - * - * The subtype definitions here are unusual for historical reasons. - * NeXT used to consider 68030 code as generic 68000 code. For - * backwards compatability: - * - * CPU_SUBTYPE_MC68030 symbol has been preserved for source code - * compatability. - * - * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same - * subtype as CPU_SUBTYPE_MC68030 for binary comatability. - * - * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object - * files to be tagged as containing 68030-specific instructions. - */ - -#define CPU_SUBTYPE_MC680x0_ALL ((cpu_subtype_t) 1) -#define CPU_SUBTYPE_MC68030 ((cpu_subtype_t) 1) /* compat */ -#define CPU_SUBTYPE_MC68040 ((cpu_subtype_t) 2) -#define CPU_SUBTYPE_MC68030_ONLY ((cpu_subtype_t) 3) - -/* - * I386 subtypes - */ - -#define CPU_SUBTYPE_INTEL(f, m) ((cpu_subtype_t) (f) + ((m) << 4)) - -#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0) -#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0) -#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0) -#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8) // 8 << 4 = 128 -#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0) -#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0) -#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1) -#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3) -#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5) -#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6) -#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7) -#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0) -#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1) -#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2) -#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0) -#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0) -#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1) -#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0) -#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1) -#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0) -#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1) - -#define CPU_SUBTYPE_INTEL_FAMILY(x) ((x) & 15) -#define CPU_SUBTYPE_INTEL_FAMILY_MAX 15 - -#define CPU_SUBTYPE_INTEL_MODEL(x) ((x) >> 4) -#define CPU_SUBTYPE_INTEL_MODEL_ALL 0 - -/* - * X86 subtypes. - */ - -#define CPU_SUBTYPE_X86_ALL ((cpu_subtype_t)3) -#define CPU_SUBTYPE_X86_64_ALL ((cpu_subtype_t)3) -#define CPU_SUBTYPE_X86_ARCH1 ((cpu_subtype_t)4) - - -#define CPU_THREADTYPE_INTEL_HTT ((cpu_threadtype_t) 1) - -/* - * Mips subtypes. - */ - -#define CPU_SUBTYPE_MIPS_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_MIPS_R2300 ((cpu_subtype_t) 1) -#define CPU_SUBTYPE_MIPS_R2600 ((cpu_subtype_t) 2) -#define CPU_SUBTYPE_MIPS_R2800 ((cpu_subtype_t) 3) -#define CPU_SUBTYPE_MIPS_R2000a ((cpu_subtype_t) 4) /* pmax */ -#define CPU_SUBTYPE_MIPS_R2000 ((cpu_subtype_t) 5) -#define CPU_SUBTYPE_MIPS_R3000a ((cpu_subtype_t) 6) /* 3max */ -#define CPU_SUBTYPE_MIPS_R3000 ((cpu_subtype_t) 7) - -/* - * MC98000 (PowerPC) subtypes - */ -#define CPU_SUBTYPE_MC98000_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_MC98601 ((cpu_subtype_t) 1) - -/* - * HPPA subtypes for Hewlett-Packard HP-PA family of - * risc processors. Port by NeXT to 700 series. - */ - -#define CPU_SUBTYPE_HPPA_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_HPPA_7100 ((cpu_subtype_t) 0) /* compat */ -#define CPU_SUBTYPE_HPPA_7100LC ((cpu_subtype_t) 1) - -/* - * MC88000 subtypes. - */ -#define CPU_SUBTYPE_MC88000_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_MC88100 ((cpu_subtype_t) 1) -#define CPU_SUBTYPE_MC88110 ((cpu_subtype_t) 2) - -/* - * SPARC subtypes - */ -#define CPU_SUBTYPE_SPARC_ALL ((cpu_subtype_t) 0) - -/* - * I860 subtypes - */ -#define CPU_SUBTYPE_I860_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_I860_860 ((cpu_subtype_t) 1) - -/* - * PowerPC subtypes - */ -#define CPU_SUBTYPE_POWERPC_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_POWERPC_601 ((cpu_subtype_t) 1) -#define CPU_SUBTYPE_POWERPC_602 ((cpu_subtype_t) 2) -#define CPU_SUBTYPE_POWERPC_603 ((cpu_subtype_t) 3) -#define CPU_SUBTYPE_POWERPC_603e ((cpu_subtype_t) 4) -#define CPU_SUBTYPE_POWERPC_603ev ((cpu_subtype_t) 5) -#define CPU_SUBTYPE_POWERPC_604 ((cpu_subtype_t) 6) -#define CPU_SUBTYPE_POWERPC_604e ((cpu_subtype_t) 7) -#define CPU_SUBTYPE_POWERPC_620 ((cpu_subtype_t) 8) -#define CPU_SUBTYPE_POWERPC_750 ((cpu_subtype_t) 9) -#define CPU_SUBTYPE_POWERPC_7400 ((cpu_subtype_t) 10) -#define CPU_SUBTYPE_POWERPC_7450 ((cpu_subtype_t) 11) -#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) - -/* - * ARM subtypes - */ -#define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t) 0) -#define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) -#define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) -#define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) -#define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) -#define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) - -/* - * CPU families (sysctl hw.cpufamily) - * - * These are meant to identify the CPU's marketing name - an - * application can map these to (possibly) localized strings. - * NB: the encodings of the CPU families are intentionally arbitrary. - * There is no ordering, and you should never try to deduce whether - * or not some feature is available based on the family. - * Use feature flags (eg, hw.optional.altivec) to test for optional - * functionality. - */ -#define CPUFAMILY_UNKNOWN 0 -#define CPUFAMILY_POWERPC_G3 0xcee41549 -#define CPUFAMILY_POWERPC_G4 0x77c184ae -#define CPUFAMILY_POWERPC_G5 0xed76d8aa -#define CPUFAMILY_INTEL_6_13 0xaa33392b -#define CPUFAMILY_INTEL_YONAH 0x73d67300 -#define CPUFAMILY_INTEL_MEROM 0x426f69ef -#define CPUFAMILY_INTEL_PENRYN 0x78ea4fbc -#define CPUFAMILY_INTEL_NEHALEM 0x6b5a4cd2 -#define CPUFAMILY_INTEL_WESTMERE 0x573b5eec -#define CPUFAMILY_INTEL_SANDYBRIDGE 0x5490b78c -#define CPUFAMILY_ARM_9 0xe73283ae -#define CPUFAMILY_ARM_11 0x8ff620d8 -#define CPUFAMILY_ARM_XSCALE 0x53b005f5 -#define CPUFAMILY_ARM_13 0x0cc90e64 -#define CPUFAMILY_ARM_14 0x96077ef1 - -/* The following synonyms are deprecated: */ -#define CPUFAMILY_INTEL_6_14 CPUFAMILY_INTEL_YONAH -#define CPUFAMILY_INTEL_6_15 CPUFAMILY_INTEL_MEROM -#define CPUFAMILY_INTEL_6_23 CPUFAMILY_INTEL_PENRYN -#define CPUFAMILY_INTEL_6_26 CPUFAMILY_INTEL_NEHALEM - -#define CPUFAMILY_INTEL_CORE CPUFAMILY_INTEL_YONAH -#define CPUFAMILY_INTEL_CORE2 CPUFAMILY_INTEL_MEROM - - -#endif /* _MACH_MACHINE_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/boolean.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/boolean.h deleted file mode 100644 index ffdc2390a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/boolean.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2000-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#ifndef _MACH_MACHINE_BOOLEAN_H_ -#define _MACH_MACHINE_BOOLEAN_H_ - -#if defined (__i386__) || defined(__x86_64__) -#include "mach/i386/boolean.h" -#elif defined (__arm__) -#include "mach/arm/boolean.h" -#else -#error architecture not supported -#endif - -#endif /* _MACH_MACHINE_BOOLEAN_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_state.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_state.h deleted file mode 100644 index 1547acac7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_state.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * This file is a stub with the bare minimum needed to make things work. - */ -#ifndef _MACH_MACHINE_THREAD_STATE_H_ -#define _MACH_MACHINE_THREAD_STATE_H_ - -#define THREAD_STATE_MAX 1 - -#endif /* _MACH_MACHINE_THREAD_STATE_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_status.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_status.h deleted file mode 100644 index d1ab56ad5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/thread_status.h +++ /dev/null @@ -1 +0,0 @@ -/* This file intentionally left blank */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/vm_types.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/vm_types.h deleted file mode 100644 index 8ccd24be5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/machine/vm_types.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2000-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#ifndef _MACH_MACHINE_VM_TYPES_H_ -#define _MACH_MACHINE_VM_TYPES_H_ - -#if defined (__i386__) || defined(__x86_64__) -#include "mach/i386/vm_types.h" -#elif defined (__arm__) -#include "mach/arm/vm_types.h" -#else -#error architecture not supported -#endif - -#endif /* _MACH_MACHINE_VM_TYPES_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/thread_status.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/thread_status.h deleted file mode 100644 index aead09bf9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/thread_status.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ -/* - * File: mach/thread_status.h - * Author: Avadis Tevanian, Jr. - * - * This file contains the structure definitions for the user-visible - * thread state. This thread state is examined with the thread_get_state - * kernel call and may be changed with the thread_set_state kernel call. - * - */ - -#ifndef _MACH_THREAD_STATUS_H_ -#define _MACH_THREAD_STATUS_H_ - -/* - * The actual structure that comprises the thread state is defined - * in the machine dependent module. - */ -#include -#include -#include - -/* - * Generic definition for machine-dependent thread status. - */ - -typedef natural_t *thread_state_t; /* Variable-length array */ - -/* THREAD_STATE_MAX is now defined in */ -typedef natural_t thread_state_data_t[THREAD_STATE_MAX]; - -#define THREAD_STATE_FLAVOR_LIST 0 /* List of valid flavors */ -#define THREAD_STATE_FLAVOR_LIST_NEW 128 - -typedef int thread_state_flavor_t; -typedef thread_state_flavor_t *thread_state_flavor_array_t; - -#endif /* _MACH_THREAD_STATUS_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/vm_prot.h b/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/vm_prot.h deleted file mode 100644 index 07c2114e5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/mach/vm_prot.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * @OSF_COPYRIGHT@ - */ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - */ -/* - * File: mach/vm_prot.h - * Author: Avadis Tevanian, Jr., Michael Wayne Young - * - * Virtual memory protection definitions. - * - */ - -#ifndef _MACH_VM_PROT_H_ -#define _MACH_VM_PROT_H_ - -/* - * Types defined: - * - * vm_prot_t VM protection values. - */ - -typedef int vm_prot_t; - -/* - * Protection values, defined as bits within the vm_prot_t type - */ - -#define VM_PROT_NONE ((vm_prot_t) 0x00) - -#define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ -#define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ -#define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ - -/* - * The default protection for newly-created virtual memory - */ - -#define VM_PROT_DEFAULT (VM_PROT_READ|VM_PROT_WRITE) - -/* - * The maximum privileges possible, for parameter checking. - */ - -#define VM_PROT_ALL (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) - -/* - * An invalid protection value. - * Used only by memory_object_lock_request to indicate no change - * to page locks. Using -1 here is a bad idea because it - * looks like VM_PROT_ALL and then some. - */ - -#define VM_PROT_NO_CHANGE ((vm_prot_t) 0x08) - -/* - * When a caller finds that he cannot obtain write permission on a - * mapped entry, the following flag can be used. The entry will - * be made "needs copy" effectively copying the object (using COW), - * and write permission will be added to the maximum protections - * for the associated entry. - */ - -#define VM_PROT_COPY ((vm_prot_t) 0x10) - - -/* - * Another invalid protection value. - * Used only by memory_object_data_request upon an object - * which has specified a copy_call copy strategy. It is used - * when the kernel wants a page belonging to a copy of the - * object, and is only asking the object as a result of - * following a shadow chain. This solves the race between pages - * being pushed up by the memory manager and the kernel - * walking down the shadow chain. - */ - -#define VM_PROT_WANTS_COPY ((vm_prot_t) 0x10) - - -/* - * Another invalid protection value. - * Indicates that the other protection bits are to be applied as a mask - * against the actual protection bits of the map entry. - */ -#define VM_PROT_IS_MASK ((vm_prot_t) 0x40) - -#endif /* _MACH_VM_PROT_H_ */ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/musl/COPYRIGHT b/toolkit/crashreporter/google-breakpad/src/third_party/musl/COPYRIGHT deleted file mode 100644 index f0ee3b78d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/musl/COPYRIGHT +++ /dev/null @@ -1,163 +0,0 @@ -musl as a whole is licensed under the following standard MIT license: - ----------------------------------------------------------------------- -Copyright © 2005-2014 Rich Felker, et al. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- - -Authors/contributors include: - -Alex Dowad -Alexander Monakov -Anthony G. Basile -Arvid Picciani -Bobby Bingham -Boris Brezillon -Brent Cook -Chris Spiegel -Clément Vasseur -Daniel Micay -Denys Vlasenko -Emil Renner Berthing -Felix Fietkau -Felix Janda -Gianluca Anzolin -Hauke Mehrtens -Hiltjo Posthuma -Isaac Dunham -Jaydeep Patil -Jens Gustedt -Jeremy Huntwork -Jo-Philipp Wich -Joakim Sindholt -John Spencer -Josiah Worcester -Justin Cormack -Khem Raj -Kylie McClain -Luca Barbato -Luka Perkov -M Farkas-Dyck (Strake) -Mahesh Bodapati -Michael Forney -Natanael Copa -Nicholas J. Kain -orc -Pascal Cuoq -Petr Hosek -Pierre Carrier -Rich Felker -Richard Pennington -Shiz -sin -Solar Designer -Stefan Kristiansson -Szabolcs Nagy -Timo Teräs -Trutz Behn -Valentin Ochs -William Haddon - -Portions of this software are derived from third-party works licensed -under terms compatible with the above MIT license: - -The TRE regular expression implementation (src/regex/reg* and -src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed -under a 2-clause BSD license (license text in the source files). The -included version has been heavily modified by Rich Felker in 2012, in -the interests of size, simplicity, and namespace cleanliness. - -Much of the math library code (src/math/* and src/complex/*) is -Copyright © 1993,2004 Sun Microsystems or -Copyright © 2003-2011 David Schultz or -Copyright © 2003-2009 Steven G. Kargl or -Copyright © 2003-2009 Bruce D. Evans or -Copyright © 2008 Stephen L. Moshier -and labelled as such in comments in the individual source files. All -have been licensed under extremely permissive terms. - -The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright © 2008 -The Android Open Source Project and is licensed under a two-clause BSD -license. It was taken from Bionic libc, used on Android. - -The implementation of DES for crypt (src/crypt/crypt_des.c) is -Copyright © 1994 David Burren. It is licensed under a BSD license. - -The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was -originally written by Solar Designer and placed into the public -domain. The code also comes with a fallback permissive license for use -in jurisdictions that may not recognize the public domain. - -The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 -Valentin Ochs and is licensed under an MIT-style license. - -The BSD PRNG implementation (src/prng/random.c) and XSI search API -(src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and -licensed under following terms: "Permission to use, copy, modify, -and/or distribute this code for any purpose with or without fee is -hereby granted. There is no warranty." - -The x86_64 port was written by Nicholas J. Kain and is licensed under -the standard MIT terms. - -The mips and microblaze ports were originally written by Richard -Pennington for use in the ellcc project. The original code was adapted -by Rich Felker for build system and code conventions during upstream -integration. It is licensed under the standard MIT terms. - -The mips64 port was contributed by Imagination Technologies and is -licensed under the standard MIT terms. - -The powerpc port was also originally written by Richard Pennington, -and later supplemented and integrated by John Spencer. It is licensed -under the standard MIT terms. - -All other files which have no copyright comments are original works -produced specifically for use as part of this library, written either -by Rich Felker, the main author of the library, or by one or more -contibutors listed above. Details on authorship of individual files -can be found in the git version control history of the project. The -omission of copyright and license comments in each file is in the -interest of source tree size. - -In addition, permission is hereby granted for all public header files -(include/* and arch/*/bits/*) and crt files intended to be linked into -applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit -the copyright notice and permission notice otherwise required by the -license, and to use these files without any requirement of -attribution. These files include substantial contributions from: - -Bobby Bingham -John Spencer -Nicholas J. Kain -Rich Felker -Richard Pennington -Stefan Kristiansson -Szabolcs Nagy - -all of whom have explicitly granted such permission. - -This file previously contained text expressing a belief that most of -the files covered by the above exception were sufficiently trivial not -to be subject to copyright, resulting in confusion over whether it -negated the permissions granted in the license. In the spirit of -permissive licensing, and of not having licensing issues being an -obstacle to adoption, that text has been removed. diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/musl/README b/toolkit/crashreporter/google-breakpad/src/third_party/musl/README deleted file mode 100644 index a30eb1127..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/musl/README +++ /dev/null @@ -1,23 +0,0 @@ - - musl libc - -musl, pronounced like the word "mussel", is an MIT-licensed -implementation of the standard C library targetting the Linux syscall -API, suitable for use in a wide range of deployment environments. musl -offers efficient static and dynamic linking support, lightweight code -and low runtime overhead, strong fail-safe guarantees under correct -usage, and correctness in the sense of standards conformance and -safety. musl is built on the principle that these goals are best -achieved through simple code that is easy to understand and maintain. - -The 1.1 release series for musl features coverage for all interfaces -defined in ISO C99 and POSIX 2008 base, along with a number of -non-standardized interfaces for compatibility with Linux, BSD, and -glibc functionality. - -For basic installation instructions, see the included INSTALL file. -Information on full musl-targeted compiler toolchains, system -bootstrapping, and Linux distributions built on musl can be found on -the project website: - - http://www.musl-libc.org/ diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/musl/README.breakpad b/toolkit/crashreporter/google-breakpad/src/third_party/musl/README.breakpad deleted file mode 100644 index f500c4359..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/musl/README.breakpad +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains the elf header from -https://git.musl-libc.org/cgit/musl/tree/ -that is required to get ELF working in dump_syms on Mac OS X. diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/musl/VERSION b/toolkit/crashreporter/google-breakpad/src/third_party/musl/VERSION deleted file mode 100644 index e9bc14996..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/musl/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.1.14 diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/musl/include/elf.h b/toolkit/crashreporter/google-breakpad/src/third_party/musl/include/elf.h deleted file mode 100644 index 8b3cd3ed3..000000000 --- a/toolkit/crashreporter/google-breakpad/src/third_party/musl/include/elf.h +++ /dev/null @@ -1,2827 +0,0 @@ -#ifndef _ELF_H -#define _ELF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef uint16_t Elf32_Half; -typedef uint16_t Elf64_Half; - -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; - -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -typedef uint32_t Elf32_Addr; -typedef uint64_t Elf64_Addr; - -typedef uint32_t Elf32_Off; -typedef uint64_t Elf64_Off; - -typedef uint16_t Elf32_Section; -typedef uint16_t Elf64_Section; - -typedef Elf32_Half Elf32_Versym; -typedef Elf64_Half Elf64_Versym; - -#define EI_NIDENT (16) - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; -} Elf64_Ehdr; - -#define EI_MAG0 0 -#define ELFMAG0 0x7f - -#define EI_MAG1 1 -#define ELFMAG1 'E' - -#define EI_MAG2 2 -#define ELFMAG2 'L' - -#define EI_MAG3 3 -#define ELFMAG3 'F' - - -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 -#define ELFCLASSNONE 0 -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define EI_DATA 5 -#define ELFDATANONE 0 -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 -#define ELFDATANUM 3 - -#define EI_VERSION 6 - - -#define EI_OSABI 7 -#define ELFOSABI_NONE 0 -#define ELFOSABI_SYSV 0 -#define ELFOSABI_HPUX 1 -#define ELFOSABI_NETBSD 2 -#define ELFOSABI_LINUX 3 -#define ELFOSABI_GNU 3 -#define ELFOSABI_SOLARIS 6 -#define ELFOSABI_AIX 7 -#define ELFOSABI_IRIX 8 -#define ELFOSABI_FREEBSD 9 -#define ELFOSABI_TRU64 10 -#define ELFOSABI_MODESTO 11 -#define ELFOSABI_OPENBSD 12 -#define ELFOSABI_ARM 97 -#define ELFOSABI_STANDALONE 255 - -#define EI_ABIVERSION 8 - -#define EI_PAD 9 - - - -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 -#define ET_NUM 5 -#define ET_LOOS 0xfe00 -#define ET_HIOS 0xfeff -#define ET_LOPROC 0xff00 -#define ET_HIPROC 0xffff - - - -#define EM_NONE 0 -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_860 7 -#define EM_MIPS 8 -#define EM_S370 9 -#define EM_MIPS_RS3_LE 10 - -#define EM_PARISC 15 -#define EM_VPP500 17 -#define EM_SPARC32PLUS 18 -#define EM_960 19 -#define EM_PPC 20 -#define EM_PPC64 21 -#define EM_S390 22 - -#define EM_V800 36 -#define EM_FR20 37 -#define EM_RH32 38 -#define EM_RCE 39 -#define EM_ARM 40 -#define EM_FAKE_ALPHA 41 -#define EM_SH 42 -#define EM_SPARCV9 43 -#define EM_TRICORE 44 -#define EM_ARC 45 -#define EM_H8_300 46 -#define EM_H8_300H 47 -#define EM_H8S 48 -#define EM_H8_500 49 -#define EM_IA_64 50 -#define EM_MIPS_X 51 -#define EM_COLDFIRE 52 -#define EM_68HC12 53 -#define EM_MMA 54 -#define EM_PCP 55 -#define EM_NCPU 56 -#define EM_NDR1 57 -#define EM_STARCORE 58 -#define EM_ME16 59 -#define EM_ST100 60 -#define EM_TINYJ 61 -#define EM_X86_64 62 -#define EM_PDSP 63 - -#define EM_FX66 66 -#define EM_ST9PLUS 67 -#define EM_ST7 68 -#define EM_68HC16 69 -#define EM_68HC11 70 -#define EM_68HC08 71 -#define EM_68HC05 72 -#define EM_SVX 73 -#define EM_ST19 74 -#define EM_VAX 75 -#define EM_CRIS 76 -#define EM_JAVELIN 77 -#define EM_FIREPATH 78 -#define EM_ZSP 79 -#define EM_MMIX 80 -#define EM_HUANY 81 -#define EM_PRISM 82 -#define EM_AVR 83 -#define EM_FR30 84 -#define EM_D10V 85 -#define EM_D30V 86 -#define EM_V850 87 -#define EM_M32R 88 -#define EM_MN10300 89 -#define EM_MN10200 90 -#define EM_PJ 91 -#define EM_OR1K 92 -#define EM_ARC_A5 93 -#define EM_XTENSA 94 -#define EM_AARCH64 183 -#define EM_TILEPRO 188 -#define EM_MICROBLAZE 189 -#define EM_TILEGX 191 -#define EM_NUM 192 -#define EM_ALPHA 0x9026 - -#define EV_NONE 0 -#define EV_CURRENT 1 -#define EV_NUM 2 - -typedef struct { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -} Elf32_Shdr; - -typedef struct { - Elf64_Word sh_name; - Elf64_Word sh_type; - Elf64_Xword sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf64_Xword sh_size; - Elf64_Word sh_link; - Elf64_Word sh_info; - Elf64_Xword sh_addralign; - Elf64_Xword sh_entsize; -} Elf64_Shdr; - - - -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_BEFORE 0xff00 - -#define SHN_AFTER 0xff01 - -#define SHN_HIPROC 0xff1f -#define SHN_LOOS 0xff20 -#define SHN_HIOS 0xff3f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_XINDEX 0xffff -#define SHN_HIRESERVE 0xffff - - - -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_INIT_ARRAY 14 -#define SHT_FINI_ARRAY 15 -#define SHT_PREINIT_ARRAY 16 -#define SHT_GROUP 17 -#define SHT_SYMTAB_SHNDX 18 -#define SHT_NUM 19 -#define SHT_LOOS 0x60000000 -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 -#define SHT_GNU_HASH 0x6ffffff6 -#define SHT_GNU_LIBLIST 0x6ffffff7 -#define SHT_CHECKSUM 0x6ffffff8 -#define SHT_LOSUNW 0x6ffffffa -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd -#define SHT_GNU_verneed 0x6ffffffe -#define SHT_GNU_versym 0x6fffffff -#define SHT_HISUNW 0x6fffffff -#define SHT_HIOS 0x6fffffff -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0x8fffffff - -#define SHF_WRITE (1 << 0) -#define SHF_ALLOC (1 << 1) -#define SHF_EXECINSTR (1 << 2) -#define SHF_MERGE (1 << 4) -#define SHF_STRINGS (1 << 5) -#define SHF_INFO_LINK (1 << 6) -#define SHF_LINK_ORDER (1 << 7) -#define SHF_OS_NONCONFORMING (1 << 8) - -#define SHF_GROUP (1 << 9) -#define SHF_TLS (1 << 10) -#define SHF_MASKOS 0x0ff00000 -#define SHF_MASKPROC 0xf0000000 -#define SHF_ORDERED (1 << 30) -#define SHF_EXCLUDE (1U << 31) - -#define GRP_COMDAT 0x1 - -typedef struct { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Section st_shndx; -} Elf32_Sym; - -typedef struct { - Elf64_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf64_Section st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; -} Elf64_Sym; - -typedef struct { - Elf32_Half si_boundto; - Elf32_Half si_flags; -} Elf32_Syminfo; - -typedef struct { - Elf64_Half si_boundto; - Elf64_Half si_flags; -} Elf64_Syminfo; - -#define SYMINFO_BT_SELF 0xffff -#define SYMINFO_BT_PARENT 0xfffe -#define SYMINFO_BT_LOWRESERVE 0xff00 - -#define SYMINFO_FLG_DIRECT 0x0001 -#define SYMINFO_FLG_PASSTHRU 0x0002 -#define SYMINFO_FLG_COPY 0x0004 -#define SYMINFO_FLG_LAZYLOAD 0x0008 - -#define SYMINFO_NONE 0 -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) - -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_NUM 3 -#define STB_LOOS 10 -#define STB_GNU_UNIQUE 10 -#define STB_HIOS 12 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_COMMON 5 -#define STT_TLS 6 -#define STT_NUM 7 -#define STT_LOOS 10 -#define STT_GNU_IFUNC 10 -#define STT_HIOS 12 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - -#define STN_UNDEF 0 - -#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) - -#define STV_DEFAULT 0 -#define STV_INTERNAL 1 -#define STV_HIDDEN 2 -#define STV_PROTECTED 3 - - - - -typedef struct -{ - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct { - Elf64_Addr r_offset; - Elf64_Xword r_info; -} Elf64_Rel; - - - -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -typedef struct { - Elf64_Addr r_offset; - Elf64_Xword r_info; - Elf64_Sxword r_addend; -} Elf64_Rela; - - - -#define ELF32_R_SYM(val) ((val) >> 8) -#define ELF32_R_TYPE(val) ((val) & 0xff) -#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) - - - -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -typedef struct { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; - Elf64_Xword p_memsz; - Elf64_Xword p_align; -} Elf64_Phdr; - - - -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_TLS 7 -#define PT_NUM 8 -#define PT_LOOS 0x60000000 -#define PT_GNU_EH_FRAME 0x6474e550 -#define PT_GNU_STACK 0x6474e551 -#define PT_GNU_RELRO 0x6474e552 -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa -#define PT_SUNWSTACK 0x6ffffffb -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff - - -#define PN_XNUM 0xffff - - -#define PF_X (1 << 0) -#define PF_W (1 << 1) -#define PF_R (1 << 2) -#define PF_MASKOS 0x0ff00000 -#define PF_MASKPROC 0xf0000000 - - - -#define NT_PRSTATUS 1 -#define NT_FPREGSET 2 -#define NT_PRPSINFO 3 -#define NT_PRXREG 4 -#define NT_TASKSTRUCT 4 -#define NT_PLATFORM 5 -#define NT_AUXV 6 -#define NT_GWINDOWS 7 -#define NT_ASRS 8 -#define NT_PSTATUS 10 -#define NT_PSINFO 13 -#define NT_PRCRED 14 -#define NT_UTSNAME 15 -#define NT_LWPSTATUS 16 -#define NT_LWPSINFO 17 -#define NT_PRFPXREG 20 -#define NT_SIGINFO 0x53494749 -#define NT_FILE 0x46494c45 -#define NT_PRXFPREG 0x46e62b7f -#define NT_PPC_VMX 0x100 -#define NT_PPC_SPE 0x101 -#define NT_PPC_VSX 0x102 -#define NT_386_TLS 0x200 -#define NT_386_IOPERM 0x201 -#define NT_X86_XSTATE 0x202 -#define NT_S390_HIGH_GPRS 0x300 -#define NT_S390_TIMER 0x301 -#define NT_S390_TODCMP 0x302 -#define NT_S390_TODPREG 0x303 -#define NT_S390_CTRS 0x304 -#define NT_S390_PREFIX 0x305 -#define NT_S390_LAST_BREAK 0x306 -#define NT_S390_SYSTEM_CALL 0x307 -#define NT_S390_TDB 0x308 -#define NT_ARM_VFP 0x400 -#define NT_ARM_TLS 0x401 -#define NT_ARM_HW_BREAK 0x402 -#define NT_ARM_HW_WATCH 0x403 -#define NT_METAG_CBUF 0x500 -#define NT_METAG_RPIPE 0x501 -#define NT_METAG_TLS 0x502 -#define NT_VERSION 1 - - - - -typedef struct { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - -typedef struct { - Elf64_Sxword d_tag; - union { - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; -} Elf64_Dyn; - - - -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_BIND_NOW 24 -#define DT_INIT_ARRAY 25 -#define DT_FINI_ARRAY 26 -#define DT_INIT_ARRAYSZ 27 -#define DT_FINI_ARRAYSZ 28 -#define DT_RUNPATH 29 -#define DT_FLAGS 30 -#define DT_ENCODING 32 -#define DT_PREINIT_ARRAY 32 -#define DT_PREINIT_ARRAYSZ 33 -#define DT_NUM 34 -#define DT_LOOS 0x6000000d -#define DT_HIOS 0x6ffff000 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff -#define DT_PROCNUM DT_MIPS_NUM - -#define DT_VALRNGLO 0x6ffffd00 -#define DT_GNU_PRELINKED 0x6ffffdf5 -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 -#define DT_CHECKSUM 0x6ffffdf8 -#define DT_PLTPADSZ 0x6ffffdf9 -#define DT_MOVEENT 0x6ffffdfa -#define DT_MOVESZ 0x6ffffdfb -#define DT_FEATURE_1 0x6ffffdfc -#define DT_POSFLAG_1 0x6ffffdfd - -#define DT_SYMINSZ 0x6ffffdfe -#define DT_SYMINENT 0x6ffffdff -#define DT_VALRNGHI 0x6ffffdff -#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) -#define DT_VALNUM 12 - -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_GNU_HASH 0x6ffffef5 -#define DT_TLSDESC_PLT 0x6ffffef6 -#define DT_TLSDESC_GOT 0x6ffffef7 -#define DT_GNU_CONFLICT 0x6ffffef8 -#define DT_GNU_LIBLIST 0x6ffffef9 -#define DT_CONFIG 0x6ffffefa -#define DT_DEPAUDIT 0x6ffffefb -#define DT_AUDIT 0x6ffffefc -#define DT_PLTPAD 0x6ffffefd -#define DT_MOVETAB 0x6ffffefe -#define DT_SYMINFO 0x6ffffeff -#define DT_ADDRRNGHI 0x6ffffeff -#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) -#define DT_ADDRNUM 11 - - - -#define DT_VERSYM 0x6ffffff0 - -#define DT_RELACOUNT 0x6ffffff9 -#define DT_RELCOUNT 0x6ffffffa - - -#define DT_FLAGS_1 0x6ffffffb -#define DT_VERDEF 0x6ffffffc - -#define DT_VERDEFNUM 0x6ffffffd -#define DT_VERNEED 0x6ffffffe - -#define DT_VERNEEDNUM 0x6fffffff -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) -#define DT_VERSIONTAGNUM 16 - - - -#define DT_AUXILIARY 0x7ffffffd -#define DT_FILTER 0x7fffffff -#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -#define DT_EXTRANUM 3 - - -#define DF_ORIGIN 0x00000001 -#define DF_SYMBOLIC 0x00000002 -#define DF_TEXTREL 0x00000004 -#define DF_BIND_NOW 0x00000008 -#define DF_STATIC_TLS 0x00000010 - - - -#define DF_1_NOW 0x00000001 -#define DF_1_GLOBAL 0x00000002 -#define DF_1_GROUP 0x00000004 -#define DF_1_NODELETE 0x00000008 -#define DF_1_LOADFLTR 0x00000010 -#define DF_1_INITFIRST 0x00000020 -#define DF_1_NOOPEN 0x00000040 -#define DF_1_ORIGIN 0x00000080 -#define DF_1_DIRECT 0x00000100 -#define DF_1_TRANS 0x00000200 -#define DF_1_INTERPOSE 0x00000400 -#define DF_1_NODEFLIB 0x00000800 -#define DF_1_NODUMP 0x00001000 -#define DF_1_CONFALT 0x00002000 -#define DF_1_ENDFILTEE 0x00004000 -#define DF_1_DISPRELDNE 0x00008000 -#define DF_1_DISPRELPND 0x00010000 -#define DF_1_NODIRECT 0x00020000 -#define DF_1_IGNMULDEF 0x00040000 -#define DF_1_NOKSYMS 0x00080000 -#define DF_1_NOHDR 0x00100000 -#define DF_1_EDITED 0x00200000 -#define DF_1_NORELOC 0x00400000 -#define DF_1_SYMINTPOSE 0x00800000 -#define DF_1_GLOBAUDIT 0x01000000 -#define DF_1_SINGLETON 0x02000000 - -#define DTF_1_PARINIT 0x00000001 -#define DTF_1_CONFEXP 0x00000002 - - -#define DF_P1_LAZYLOAD 0x00000001 -#define DF_P1_GROUPPERM 0x00000002 - - - - -typedef struct { - Elf32_Half vd_version; - Elf32_Half vd_flags; - Elf32_Half vd_ndx; - Elf32_Half vd_cnt; - Elf32_Word vd_hash; - Elf32_Word vd_aux; - Elf32_Word vd_next; -} Elf32_Verdef; - -typedef struct { - Elf64_Half vd_version; - Elf64_Half vd_flags; - Elf64_Half vd_ndx; - Elf64_Half vd_cnt; - Elf64_Word vd_hash; - Elf64_Word vd_aux; - Elf64_Word vd_next; -} Elf64_Verdef; - - - -#define VER_DEF_NONE 0 -#define VER_DEF_CURRENT 1 -#define VER_DEF_NUM 2 - - -#define VER_FLG_BASE 0x1 -#define VER_FLG_WEAK 0x2 - - -#define VER_NDX_LOCAL 0 -#define VER_NDX_GLOBAL 1 -#define VER_NDX_LORESERVE 0xff00 -#define VER_NDX_ELIMINATE 0xff01 - - - -typedef struct { - Elf32_Word vda_name; - Elf32_Word vda_next; -} Elf32_Verdaux; - -typedef struct { - Elf64_Word vda_name; - Elf64_Word vda_next; -} Elf64_Verdaux; - - - - -typedef struct { - Elf32_Half vn_version; - Elf32_Half vn_cnt; - Elf32_Word vn_file; - Elf32_Word vn_aux; - Elf32_Word vn_next; -} Elf32_Verneed; - -typedef struct { - Elf64_Half vn_version; - Elf64_Half vn_cnt; - Elf64_Word vn_file; - Elf64_Word vn_aux; - Elf64_Word vn_next; -} Elf64_Verneed; - - - -#define VER_NEED_NONE 0 -#define VER_NEED_CURRENT 1 -#define VER_NEED_NUM 2 - - - -typedef struct { - Elf32_Word vna_hash; - Elf32_Half vna_flags; - Elf32_Half vna_other; - Elf32_Word vna_name; - Elf32_Word vna_next; -} Elf32_Vernaux; - -typedef struct { - Elf64_Word vna_hash; - Elf64_Half vna_flags; - Elf64_Half vna_other; - Elf64_Word vna_name; - Elf64_Word vna_next; -} Elf64_Vernaux; - - - -#define VER_FLG_WEAK 0x2 - - - -typedef struct { - uint32_t a_type; - union { - uint32_t a_val; - } a_un; -} Elf32_auxv_t; - -typedef struct { - uint64_t a_type; - union { - uint64_t a_val; - } a_un; -} Elf64_auxv_t; - - - -#define AT_NULL 0 -#define AT_IGNORE 1 -#define AT_EXECFD 2 -#define AT_PHDR 3 -#define AT_PHENT 4 -#define AT_PHNUM 5 -#define AT_PAGESZ 6 -#define AT_BASE 7 -#define AT_FLAGS 8 -#define AT_ENTRY 9 -#define AT_NOTELF 10 -#define AT_UID 11 -#define AT_EUID 12 -#define AT_GID 13 -#define AT_EGID 14 -#define AT_CLKTCK 17 - - -#define AT_PLATFORM 15 -#define AT_HWCAP 16 - - - - -#define AT_FPUCW 18 - - -#define AT_DCACHEBSIZE 19 -#define AT_ICACHEBSIZE 20 -#define AT_UCACHEBSIZE 21 - - - -#define AT_IGNOREPPC 22 - -#define AT_SECURE 23 - -#define AT_BASE_PLATFORM 24 - -#define AT_RANDOM 25 - -#define AT_HWCAP2 26 - -#define AT_EXECFN 31 - - - -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - - - -#define AT_L1I_CACHESHAPE 34 -#define AT_L1D_CACHESHAPE 35 -#define AT_L2_CACHESHAPE 36 -#define AT_L3_CACHESHAPE 37 - - - - -typedef struct { - Elf32_Word n_namesz; - Elf32_Word n_descsz; - Elf32_Word n_type; -} Elf32_Nhdr; - -typedef struct { - Elf64_Word n_namesz; - Elf64_Word n_descsz; - Elf64_Word n_type; -} Elf64_Nhdr; - - - - -#define ELF_NOTE_SOLARIS "SUNW Solaris" - - -#define ELF_NOTE_GNU "GNU" - - - - - -#define ELF_NOTE_PAGESIZE_HINT 1 - - -#define NT_GNU_ABI_TAG 1 -#define ELF_NOTE_ABI NT_GNU_ABI_TAG - - - -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 -#define ELF_NOTE_OS_FREEBSD 3 - -#define NT_GNU_BUILD_ID 3 -#define NT_GNU_GOLD_VERSION 4 - - - -typedef struct { - Elf32_Xword m_value; - Elf32_Word m_info; - Elf32_Word m_poffset; - Elf32_Half m_repeat; - Elf32_Half m_stride; -} Elf32_Move; - -typedef struct { - Elf64_Xword m_value; - Elf64_Xword m_info; - Elf64_Xword m_poffset; - Elf64_Half m_repeat; - Elf64_Half m_stride; -} Elf64_Move; - - -#define ELF32_M_SYM(info) ((info) >> 8) -#define ELF32_M_SIZE(info) ((unsigned char) (info)) -#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) - -#define ELF64_M_SYM(info) ELF32_M_SYM (info) -#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) - -#define EF_CPU32 0x00810000 - -#define R_68K_NONE 0 -#define R_68K_32 1 -#define R_68K_16 2 -#define R_68K_8 3 -#define R_68K_PC32 4 -#define R_68K_PC16 5 -#define R_68K_PC8 6 -#define R_68K_GOT32 7 -#define R_68K_GOT16 8 -#define R_68K_GOT8 9 -#define R_68K_GOT32O 10 -#define R_68K_GOT16O 11 -#define R_68K_GOT8O 12 -#define R_68K_PLT32 13 -#define R_68K_PLT16 14 -#define R_68K_PLT8 15 -#define R_68K_PLT32O 16 -#define R_68K_PLT16O 17 -#define R_68K_PLT8O 18 -#define R_68K_COPY 19 -#define R_68K_GLOB_DAT 20 -#define R_68K_JMP_SLOT 21 -#define R_68K_RELATIVE 22 -#define R_68K_NUM 23 - -#define R_386_NONE 0 -#define R_386_32 1 -#define R_386_PC32 2 -#define R_386_GOT32 3 -#define R_386_PLT32 4 -#define R_386_COPY 5 -#define R_386_GLOB_DAT 6 -#define R_386_JMP_SLOT 7 -#define R_386_RELATIVE 8 -#define R_386_GOTOFF 9 -#define R_386_GOTPC 10 -#define R_386_32PLT 11 -#define R_386_TLS_TPOFF 14 -#define R_386_TLS_IE 15 -#define R_386_TLS_GOTIE 16 -#define R_386_TLS_LE 17 -#define R_386_TLS_GD 18 -#define R_386_TLS_LDM 19 -#define R_386_16 20 -#define R_386_PC16 21 -#define R_386_8 22 -#define R_386_PC8 23 -#define R_386_TLS_GD_32 24 -#define R_386_TLS_GD_PUSH 25 -#define R_386_TLS_GD_CALL 26 -#define R_386_TLS_GD_POP 27 -#define R_386_TLS_LDM_32 28 -#define R_386_TLS_LDM_PUSH 29 -#define R_386_TLS_LDM_CALL 30 -#define R_386_TLS_LDM_POP 31 -#define R_386_TLS_LDO_32 32 -#define R_386_TLS_IE_32 33 -#define R_386_TLS_LE_32 34 -#define R_386_TLS_DTPMOD32 35 -#define R_386_TLS_DTPOFF32 36 -#define R_386_TLS_TPOFF32 37 -#define R_386_SIZE32 38 -#define R_386_TLS_GOTDESC 39 -#define R_386_TLS_DESC_CALL 40 -#define R_386_TLS_DESC 41 -#define R_386_IRELATIVE 42 -#define R_386_NUM 43 - - - - - -#define STT_SPARC_REGISTER 13 - - - -#define EF_SPARCV9_MM 3 -#define EF_SPARCV9_TSO 0 -#define EF_SPARCV9_PSO 1 -#define EF_SPARCV9_RMO 2 -#define EF_SPARC_LEDATA 0x800000 -#define EF_SPARC_EXT_MASK 0xFFFF00 -#define EF_SPARC_32PLUS 0x000100 -#define EF_SPARC_SUN_US1 0x000200 -#define EF_SPARC_HAL_R1 0x000400 -#define EF_SPARC_SUN_US3 0x000800 - - - -#define R_SPARC_NONE 0 -#define R_SPARC_8 1 -#define R_SPARC_16 2 -#define R_SPARC_32 3 -#define R_SPARC_DISP8 4 -#define R_SPARC_DISP16 5 -#define R_SPARC_DISP32 6 -#define R_SPARC_WDISP30 7 -#define R_SPARC_WDISP22 8 -#define R_SPARC_HI22 9 -#define R_SPARC_22 10 -#define R_SPARC_13 11 -#define R_SPARC_LO10 12 -#define R_SPARC_GOT10 13 -#define R_SPARC_GOT13 14 -#define R_SPARC_GOT22 15 -#define R_SPARC_PC10 16 -#define R_SPARC_PC22 17 -#define R_SPARC_WPLT30 18 -#define R_SPARC_COPY 19 -#define R_SPARC_GLOB_DAT 20 -#define R_SPARC_JMP_SLOT 21 -#define R_SPARC_RELATIVE 22 -#define R_SPARC_UA32 23 - - - -#define R_SPARC_PLT32 24 -#define R_SPARC_HIPLT22 25 -#define R_SPARC_LOPLT10 26 -#define R_SPARC_PCPLT32 27 -#define R_SPARC_PCPLT22 28 -#define R_SPARC_PCPLT10 29 -#define R_SPARC_10 30 -#define R_SPARC_11 31 -#define R_SPARC_64 32 -#define R_SPARC_OLO10 33 -#define R_SPARC_HH22 34 -#define R_SPARC_HM10 35 -#define R_SPARC_LM22 36 -#define R_SPARC_PC_HH22 37 -#define R_SPARC_PC_HM10 38 -#define R_SPARC_PC_LM22 39 -#define R_SPARC_WDISP16 40 -#define R_SPARC_WDISP19 41 -#define R_SPARC_GLOB_JMP 42 -#define R_SPARC_7 43 -#define R_SPARC_5 44 -#define R_SPARC_6 45 -#define R_SPARC_DISP64 46 -#define R_SPARC_PLT64 47 -#define R_SPARC_HIX22 48 -#define R_SPARC_LOX10 49 -#define R_SPARC_H44 50 -#define R_SPARC_M44 51 -#define R_SPARC_L44 52 -#define R_SPARC_REGISTER 53 -#define R_SPARC_UA64 54 -#define R_SPARC_UA16 55 -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 -#define R_SPARC_GOTDATA_HIX22 80 -#define R_SPARC_GOTDATA_LOX10 81 -#define R_SPARC_GOTDATA_OP_HIX22 82 -#define R_SPARC_GOTDATA_OP_LOX10 83 -#define R_SPARC_GOTDATA_OP 84 -#define R_SPARC_H34 85 -#define R_SPARC_SIZE32 86 -#define R_SPARC_SIZE64 87 -#define R_SPARC_GNU_VTINHERIT 250 -#define R_SPARC_GNU_VTENTRY 251 -#define R_SPARC_REV32 252 - -#define R_SPARC_NUM 253 - - - -#define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - - -#define EF_MIPS_NOREORDER 1 -#define EF_MIPS_PIC 2 -#define EF_MIPS_CPIC 4 -#define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 -#define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_NAN2008 1024 -#define EF_MIPS_ARCH 0xf0000000 - - - -#define EF_MIPS_ARCH_1 0x00000000 -#define EF_MIPS_ARCH_2 0x10000000 -#define EF_MIPS_ARCH_3 0x20000000 -#define EF_MIPS_ARCH_4 0x30000000 -#define EF_MIPS_ARCH_5 0x40000000 -#define EF_MIPS_ARCH_32 0x50000000 -#define EF_MIPS_ARCH_64 0x60000000 -#define EF_MIPS_ARCH_32R2 0x70000000 -#define EF_MIPS_ARCH_64R2 0x80000000 - - -#define E_MIPS_ARCH_1 0x00000000 -#define E_MIPS_ARCH_2 0x10000000 -#define E_MIPS_ARCH_3 0x20000000 -#define E_MIPS_ARCH_4 0x30000000 -#define E_MIPS_ARCH_5 0x40000000 -#define E_MIPS_ARCH_32 0x50000000 -#define E_MIPS_ARCH_64 0x60000000 - - - -#define SHN_MIPS_ACOMMON 0xff00 -#define SHN_MIPS_TEXT 0xff01 -#define SHN_MIPS_DATA 0xff02 -#define SHN_MIPS_SCOMMON 0xff03 -#define SHN_MIPS_SUNDEFINED 0xff04 - - - -#define SHT_MIPS_LIBLIST 0x70000000 -#define SHT_MIPS_MSYM 0x70000001 -#define SHT_MIPS_CONFLICT 0x70000002 -#define SHT_MIPS_GPTAB 0x70000003 -#define SHT_MIPS_UCODE 0x70000004 -#define SHT_MIPS_DEBUG 0x70000005 -#define SHT_MIPS_REGINFO 0x70000006 -#define SHT_MIPS_PACKAGE 0x70000007 -#define SHT_MIPS_PACKSYM 0x70000008 -#define SHT_MIPS_RELD 0x70000009 -#define SHT_MIPS_IFACE 0x7000000b -#define SHT_MIPS_CONTENT 0x7000000c -#define SHT_MIPS_OPTIONS 0x7000000d -#define SHT_MIPS_SHDR 0x70000010 -#define SHT_MIPS_FDESC 0x70000011 -#define SHT_MIPS_EXTSYM 0x70000012 -#define SHT_MIPS_DENSE 0x70000013 -#define SHT_MIPS_PDESC 0x70000014 -#define SHT_MIPS_LOCSYM 0x70000015 -#define SHT_MIPS_AUXSYM 0x70000016 -#define SHT_MIPS_OPTSYM 0x70000017 -#define SHT_MIPS_LOCSTR 0x70000018 -#define SHT_MIPS_LINE 0x70000019 -#define SHT_MIPS_RFDESC 0x7000001a -#define SHT_MIPS_DELTASYM 0x7000001b -#define SHT_MIPS_DELTAINST 0x7000001c -#define SHT_MIPS_DELTACLASS 0x7000001d -#define SHT_MIPS_DWARF 0x7000001e -#define SHT_MIPS_DELTADECL 0x7000001f -#define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 -#define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 -#define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 -#define SHT_MIPS_EH_REGION 0x70000027 -#define SHT_MIPS_XLATE_OLD 0x70000028 -#define SHT_MIPS_PDR_EXCEPTION 0x70000029 - - - -#define SHF_MIPS_GPREL 0x10000000 -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 -#define SHF_MIPS_STRINGS 0x80000000 -#define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 - - - - - -#define STO_MIPS_DEFAULT 0x0 -#define STO_MIPS_INTERNAL 0x1 -#define STO_MIPS_HIDDEN 0x2 -#define STO_MIPS_PROTECTED 0x3 -#define STO_MIPS_PLT 0x8 -#define STO_MIPS_SC_ALIGN_UNUSED 0xff - - -#define STB_MIPS_SPLIT_COMMON 13 - - - -typedef union { - struct { - Elf32_Word gt_current_g_value; - Elf32_Word gt_unused; - } gt_header; - struct { - Elf32_Word gt_g_value; - Elf32_Word gt_bytes; - } gt_entry; -} Elf32_gptab; - - - -typedef struct { - Elf32_Word ri_gprmask; - Elf32_Word ri_cprmask[4]; - Elf32_Sword ri_gp_value; -} Elf32_RegInfo; - - - -typedef struct { - unsigned char kind; - - unsigned char size; - Elf32_Section section; - - Elf32_Word info; -} Elf_Options; - - - -#define ODK_NULL 0 -#define ODK_REGINFO 1 -#define ODK_EXCEPTIONS 2 -#define ODK_PAD 3 -#define ODK_HWPATCH 4 -#define ODK_FILL 5 -#define ODK_TAGS 6 -#define ODK_HWAND 7 -#define ODK_HWOR 8 - - - -#define OEX_FPU_MIN 0x1f -#define OEX_FPU_MAX 0x1f00 -#define OEX_PAGE0 0x10000 -#define OEX_SMM 0x20000 -#define OEX_FPDBUG 0x40000 -#define OEX_PRECISEFP OEX_FPDBUG -#define OEX_DISMISS 0x80000 - -#define OEX_FPU_INVAL 0x10 -#define OEX_FPU_DIV0 0x08 -#define OEX_FPU_OFLO 0x04 -#define OEX_FPU_UFLO 0x02 -#define OEX_FPU_INEX 0x01 - - - -#define OHW_R4KEOP 0x1 -#define OHW_R8KPFETCH 0x2 -#define OHW_R5KEOP 0x4 -#define OHW_R5KCVTL 0x8 - -#define OPAD_PREFIX 0x1 -#define OPAD_POSTFIX 0x2 -#define OPAD_SYMBOL 0x4 - - - -typedef struct { - Elf32_Word hwp_flags1; - Elf32_Word hwp_flags2; -} Elf_Options_Hw; - - - -#define OHWA0_R4KEOP_CHECKED 0x00000001 -#define OHWA1_R4KEOP_CLEAN 0x00000002 - - - -#define R_MIPS_NONE 0 -#define R_MIPS_16 1 -#define R_MIPS_32 2 -#define R_MIPS_REL32 3 -#define R_MIPS_26 4 -#define R_MIPS_HI16 5 -#define R_MIPS_LO16 6 -#define R_MIPS_GPREL16 7 -#define R_MIPS_LITERAL 8 -#define R_MIPS_GOT16 9 -#define R_MIPS_PC16 10 -#define R_MIPS_CALL16 11 -#define R_MIPS_GPREL32 12 - -#define R_MIPS_SHIFT5 16 -#define R_MIPS_SHIFT6 17 -#define R_MIPS_64 18 -#define R_MIPS_GOT_DISP 19 -#define R_MIPS_GOT_PAGE 20 -#define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 -#define R_MIPS_SUB 24 -#define R_MIPS_INSERT_A 25 -#define R_MIPS_INSERT_B 26 -#define R_MIPS_DELETE 27 -#define R_MIPS_HIGHER 28 -#define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 -#define R_MIPS_SCN_DISP 32 -#define R_MIPS_REL16 33 -#define R_MIPS_ADD_IMMEDIATE 34 -#define R_MIPS_PJUMP 35 -#define R_MIPS_RELGOT 36 -#define R_MIPS_JALR 37 -#define R_MIPS_TLS_DTPMOD32 38 -#define R_MIPS_TLS_DTPREL32 39 -#define R_MIPS_TLS_DTPMOD64 40 -#define R_MIPS_TLS_DTPREL64 41 -#define R_MIPS_TLS_GD 42 -#define R_MIPS_TLS_LDM 43 -#define R_MIPS_TLS_DTPREL_HI16 44 -#define R_MIPS_TLS_DTPREL_LO16 45 -#define R_MIPS_TLS_GOTTPREL 46 -#define R_MIPS_TLS_TPREL32 47 -#define R_MIPS_TLS_TPREL64 48 -#define R_MIPS_TLS_TPREL_HI16 49 -#define R_MIPS_TLS_TPREL_LO16 50 -#define R_MIPS_GLOB_DAT 51 -#define R_MIPS_COPY 126 -#define R_MIPS_JUMP_SLOT 127 - -#define R_MIPS_NUM 128 - - - -#define PT_MIPS_REGINFO 0x70000000 -#define PT_MIPS_RTPROC 0x70000001 -#define PT_MIPS_OPTIONS 0x70000002 - - - -#define PF_MIPS_LOCAL 0x10000000 - - - -#define DT_MIPS_RLD_VERSION 0x70000001 -#define DT_MIPS_TIME_STAMP 0x70000002 -#define DT_MIPS_ICHECKSUM 0x70000003 -#define DT_MIPS_IVERSION 0x70000004 -#define DT_MIPS_FLAGS 0x70000005 -#define DT_MIPS_BASE_ADDRESS 0x70000006 -#define DT_MIPS_MSYM 0x70000007 -#define DT_MIPS_CONFLICT 0x70000008 -#define DT_MIPS_LIBLIST 0x70000009 -#define DT_MIPS_LOCAL_GOTNO 0x7000000a -#define DT_MIPS_CONFLICTNO 0x7000000b -#define DT_MIPS_LIBLISTNO 0x70000010 -#define DT_MIPS_SYMTABNO 0x70000011 -#define DT_MIPS_UNREFEXTNO 0x70000012 -#define DT_MIPS_GOTSYM 0x70000013 -#define DT_MIPS_HIPAGENO 0x70000014 -#define DT_MIPS_RLD_MAP 0x70000016 -#define DT_MIPS_DELTA_CLASS 0x70000017 -#define DT_MIPS_DELTA_CLASS_NO 0x70000018 - -#define DT_MIPS_DELTA_INSTANCE 0x70000019 -#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a - -#define DT_MIPS_DELTA_RELOC 0x7000001b -#define DT_MIPS_DELTA_RELOC_NO 0x7000001c - -#define DT_MIPS_DELTA_SYM 0x7000001d - -#define DT_MIPS_DELTA_SYM_NO 0x7000001e - -#define DT_MIPS_DELTA_CLASSSYM 0x70000020 - -#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 - -#define DT_MIPS_CXX_FLAGS 0x70000022 -#define DT_MIPS_PIXIE_INIT 0x70000023 -#define DT_MIPS_SYMBOL_LIB 0x70000024 -#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -#define DT_MIPS_OPTIONS 0x70000029 -#define DT_MIPS_INTERFACE 0x7000002a -#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -#define DT_MIPS_INTERFACE_SIZE 0x7000002c -#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d - -#define DT_MIPS_PERF_SUFFIX 0x7000002e - -#define DT_MIPS_COMPACT_SIZE 0x7000002f -#define DT_MIPS_GP_VALUE 0x70000030 -#define DT_MIPS_AUX_DYNAMIC 0x70000031 - -#define DT_MIPS_PLTGOT 0x70000032 - -#define DT_MIPS_RWPLT 0x70000034 -#define DT_MIPS_NUM 0x35 - - - -#define RHF_NONE 0 -#define RHF_QUICKSTART (1 << 0) -#define RHF_NOTPOT (1 << 1) -#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) -#define RHF_NO_MOVE (1 << 3) -#define RHF_SGI_ONLY (1 << 4) -#define RHF_GUARANTEE_INIT (1 << 5) -#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -#define RHF_GUARANTEE_START_INIT (1 << 7) -#define RHF_PIXIE (1 << 8) -#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -#define RHF_REQUICKSTART (1 << 10) -#define RHF_REQUICKSTARTED (1 << 11) -#define RHF_CORD (1 << 12) -#define RHF_NO_UNRES_UNDEF (1 << 13) -#define RHF_RLD_ORDER_SAFE (1 << 14) - - - -typedef struct -{ - Elf32_Word l_name; - Elf32_Word l_time_stamp; - Elf32_Word l_checksum; - Elf32_Word l_version; - Elf32_Word l_flags; -} Elf32_Lib; - -typedef struct -{ - Elf64_Word l_name; - Elf64_Word l_time_stamp; - Elf64_Word l_checksum; - Elf64_Word l_version; - Elf64_Word l_flags; -} Elf64_Lib; - - - - -#define LL_NONE 0 -#define LL_EXACT_MATCH (1 << 0) -#define LL_IGNORE_INT_VER (1 << 1) -#define LL_REQUIRE_MINOR (1 << 2) -#define LL_EXPORTS (1 << 3) -#define LL_DELAY_LOAD (1 << 4) -#define LL_DELTA (1 << 5) - - - -typedef Elf32_Addr Elf32_Conflict; - - - - - - -#define EF_PARISC_TRAPNIL 0x00010000 -#define EF_PARISC_EXT 0x00020000 -#define EF_PARISC_LSB 0x00040000 -#define EF_PARISC_WIDE 0x00080000 -#define EF_PARISC_NO_KABP 0x00100000 - -#define EF_PARISC_LAZYSWAP 0x00400000 -#define EF_PARISC_ARCH 0x0000ffff - - - -#define EFA_PARISC_1_0 0x020b -#define EFA_PARISC_1_1 0x0210 -#define EFA_PARISC_2_0 0x0214 - - - -#define SHN_PARISC_ANSI_COMMON 0xff00 - -#define SHN_PARISC_HUGE_COMMON 0xff01 - - - -#define SHT_PARISC_EXT 0x70000000 -#define SHT_PARISC_UNWIND 0x70000001 -#define SHT_PARISC_DOC 0x70000002 - - - -#define SHF_PARISC_SHORT 0x20000000 -#define SHF_PARISC_HUGE 0x40000000 -#define SHF_PARISC_SBP 0x80000000 - - - -#define STT_PARISC_MILLICODE 13 - -#define STT_HP_OPAQUE (STT_LOOS + 0x1) -#define STT_HP_STUB (STT_LOOS + 0x2) - - - -#define R_PARISC_NONE 0 -#define R_PARISC_DIR32 1 -#define R_PARISC_DIR21L 2 -#define R_PARISC_DIR17R 3 -#define R_PARISC_DIR17F 4 -#define R_PARISC_DIR14R 6 -#define R_PARISC_PCREL32 9 -#define R_PARISC_PCREL21L 10 -#define R_PARISC_PCREL17R 11 -#define R_PARISC_PCREL17F 12 -#define R_PARISC_PCREL14R 14 -#define R_PARISC_DPREL21L 18 -#define R_PARISC_DPREL14R 22 -#define R_PARISC_GPREL21L 26 -#define R_PARISC_GPREL14R 30 -#define R_PARISC_LTOFF21L 34 -#define R_PARISC_LTOFF14R 38 -#define R_PARISC_SECREL32 41 -#define R_PARISC_SEGBASE 48 -#define R_PARISC_SEGREL32 49 -#define R_PARISC_PLTOFF21L 50 -#define R_PARISC_PLTOFF14R 54 -#define R_PARISC_LTOFF_FPTR32 57 -#define R_PARISC_LTOFF_FPTR21L 58 -#define R_PARISC_LTOFF_FPTR14R 62 -#define R_PARISC_FPTR64 64 -#define R_PARISC_PLABEL32 65 -#define R_PARISC_PLABEL21L 66 -#define R_PARISC_PLABEL14R 70 -#define R_PARISC_PCREL64 72 -#define R_PARISC_PCREL22F 74 -#define R_PARISC_PCREL14WR 75 -#define R_PARISC_PCREL14DR 76 -#define R_PARISC_PCREL16F 77 -#define R_PARISC_PCREL16WF 78 -#define R_PARISC_PCREL16DF 79 -#define R_PARISC_DIR64 80 -#define R_PARISC_DIR14WR 83 -#define R_PARISC_DIR14DR 84 -#define R_PARISC_DIR16F 85 -#define R_PARISC_DIR16WF 86 -#define R_PARISC_DIR16DF 87 -#define R_PARISC_GPREL64 88 -#define R_PARISC_GPREL14WR 91 -#define R_PARISC_GPREL14DR 92 -#define R_PARISC_GPREL16F 93 -#define R_PARISC_GPREL16WF 94 -#define R_PARISC_GPREL16DF 95 -#define R_PARISC_LTOFF64 96 -#define R_PARISC_LTOFF14WR 99 -#define R_PARISC_LTOFF14DR 100 -#define R_PARISC_LTOFF16F 101 -#define R_PARISC_LTOFF16WF 102 -#define R_PARISC_LTOFF16DF 103 -#define R_PARISC_SECREL64 104 -#define R_PARISC_SEGREL64 112 -#define R_PARISC_PLTOFF14WR 115 -#define R_PARISC_PLTOFF14DR 116 -#define R_PARISC_PLTOFF16F 117 -#define R_PARISC_PLTOFF16WF 118 -#define R_PARISC_PLTOFF16DF 119 -#define R_PARISC_LTOFF_FPTR64 120 -#define R_PARISC_LTOFF_FPTR14WR 123 -#define R_PARISC_LTOFF_FPTR14DR 124 -#define R_PARISC_LTOFF_FPTR16F 125 -#define R_PARISC_LTOFF_FPTR16WF 126 -#define R_PARISC_LTOFF_FPTR16DF 127 -#define R_PARISC_LORESERVE 128 -#define R_PARISC_COPY 128 -#define R_PARISC_IPLT 129 -#define R_PARISC_EPLT 130 -#define R_PARISC_TPREL32 153 -#define R_PARISC_TPREL21L 154 -#define R_PARISC_TPREL14R 158 -#define R_PARISC_LTOFF_TP21L 162 -#define R_PARISC_LTOFF_TP14R 166 -#define R_PARISC_LTOFF_TP14F 167 -#define R_PARISC_TPREL64 216 -#define R_PARISC_TPREL14WR 219 -#define R_PARISC_TPREL14DR 220 -#define R_PARISC_TPREL16F 221 -#define R_PARISC_TPREL16WF 222 -#define R_PARISC_TPREL16DF 223 -#define R_PARISC_LTOFF_TP64 224 -#define R_PARISC_LTOFF_TP14WR 227 -#define R_PARISC_LTOFF_TP14DR 228 -#define R_PARISC_LTOFF_TP16F 229 -#define R_PARISC_LTOFF_TP16WF 230 -#define R_PARISC_LTOFF_TP16DF 231 -#define R_PARISC_GNU_VTENTRY 232 -#define R_PARISC_GNU_VTINHERIT 233 -#define R_PARISC_TLS_GD21L 234 -#define R_PARISC_TLS_GD14R 235 -#define R_PARISC_TLS_GDCALL 236 -#define R_PARISC_TLS_LDM21L 237 -#define R_PARISC_TLS_LDM14R 238 -#define R_PARISC_TLS_LDMCALL 239 -#define R_PARISC_TLS_LDO21L 240 -#define R_PARISC_TLS_LDO14R 241 -#define R_PARISC_TLS_DTPMOD32 242 -#define R_PARISC_TLS_DTPMOD64 243 -#define R_PARISC_TLS_DTPOFF32 244 -#define R_PARISC_TLS_DTPOFF64 245 -#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -#define R_PARISC_HIRESERVE 255 - - - -#define PT_HP_TLS (PT_LOOS + 0x0) -#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -#define PT_HP_PARALLEL (PT_LOOS + 0x10) -#define PT_HP_FASTBIND (PT_LOOS + 0x11) -#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -#define PT_HP_STACK (PT_LOOS + 0x14) - -#define PT_PARISC_ARCHEXT 0x70000000 -#define PT_PARISC_UNWIND 0x70000001 - - - -#define PF_PARISC_SBP 0x08000000 - -#define PF_HP_PAGE_SIZE 0x00100000 -#define PF_HP_FAR_SHARED 0x00200000 -#define PF_HP_NEAR_SHARED 0x00400000 -#define PF_HP_CODE 0x01000000 -#define PF_HP_MODIFY 0x02000000 -#define PF_HP_LAZYSWAP 0x04000000 -#define PF_HP_SBP 0x08000000 - - - - - - -#define EF_ALPHA_32BIT 1 -#define EF_ALPHA_CANRELAX 2 - - - - -#define SHT_ALPHA_DEBUG 0x70000001 -#define SHT_ALPHA_REGINFO 0x70000002 - - - -#define SHF_ALPHA_GPREL 0x10000000 - - -#define STO_ALPHA_NOPV 0x80 -#define STO_ALPHA_STD_GPLOAD 0x88 - - - -#define R_ALPHA_NONE 0 -#define R_ALPHA_REFLONG 1 -#define R_ALPHA_REFQUAD 2 -#define R_ALPHA_GPREL32 3 -#define R_ALPHA_LITERAL 4 -#define R_ALPHA_LITUSE 5 -#define R_ALPHA_GPDISP 6 -#define R_ALPHA_BRADDR 7 -#define R_ALPHA_HINT 8 -#define R_ALPHA_SREL16 9 -#define R_ALPHA_SREL32 10 -#define R_ALPHA_SREL64 11 -#define R_ALPHA_GPRELHIGH 17 -#define R_ALPHA_GPRELLOW 18 -#define R_ALPHA_GPREL16 19 -#define R_ALPHA_COPY 24 -#define R_ALPHA_GLOB_DAT 25 -#define R_ALPHA_JMP_SLOT 26 -#define R_ALPHA_RELATIVE 27 -#define R_ALPHA_TLS_GD_HI 28 -#define R_ALPHA_TLSGD 29 -#define R_ALPHA_TLS_LDM 30 -#define R_ALPHA_DTPMOD64 31 -#define R_ALPHA_GOTDTPREL 32 -#define R_ALPHA_DTPREL64 33 -#define R_ALPHA_DTPRELHI 34 -#define R_ALPHA_DTPRELLO 35 -#define R_ALPHA_DTPREL16 36 -#define R_ALPHA_GOTTPREL 37 -#define R_ALPHA_TPREL64 38 -#define R_ALPHA_TPRELHI 39 -#define R_ALPHA_TPRELLO 40 -#define R_ALPHA_TPREL16 41 - -#define R_ALPHA_NUM 46 - - -#define LITUSE_ALPHA_ADDR 0 -#define LITUSE_ALPHA_BASE 1 -#define LITUSE_ALPHA_BYTOFF 2 -#define LITUSE_ALPHA_JSR 3 -#define LITUSE_ALPHA_TLS_GD 4 -#define LITUSE_ALPHA_TLS_LDM 5 - - -#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -#define DT_ALPHA_NUM 1 - - - - -#define EF_PPC_EMB 0x80000000 - - -#define EF_PPC_RELOCATABLE 0x00010000 -#define EF_PPC_RELOCATABLE_LIB 0x00008000 - - - -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 -#define R_PPC_ADDR24 2 -#define R_PPC_ADDR16 3 -#define R_PPC_ADDR16_LO 4 -#define R_PPC_ADDR16_HI 5 -#define R_PPC_ADDR16_HA 6 -#define R_PPC_ADDR14 7 -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 -#define R_PPC_REL14 11 -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - - -#define R_PPC_TLS 67 -#define R_PPC_DTPMOD32 68 -#define R_PPC_TPREL16 69 -#define R_PPC_TPREL16_LO 70 -#define R_PPC_TPREL16_HI 71 -#define R_PPC_TPREL16_HA 72 -#define R_PPC_TPREL32 73 -#define R_PPC_DTPREL16 74 -#define R_PPC_DTPREL16_LO 75 -#define R_PPC_DTPREL16_HI 76 -#define R_PPC_DTPREL16_HA 77 -#define R_PPC_DTPREL32 78 -#define R_PPC_GOT_TLSGD16 79 -#define R_PPC_GOT_TLSGD16_LO 80 -#define R_PPC_GOT_TLSGD16_HI 81 -#define R_PPC_GOT_TLSGD16_HA 82 -#define R_PPC_GOT_TLSLD16 83 -#define R_PPC_GOT_TLSLD16_LO 84 -#define R_PPC_GOT_TLSLD16_HI 85 -#define R_PPC_GOT_TLSLD16_HA 86 -#define R_PPC_GOT_TPREL16 87 -#define R_PPC_GOT_TPREL16_LO 88 -#define R_PPC_GOT_TPREL16_HI 89 -#define R_PPC_GOT_TPREL16_HA 90 -#define R_PPC_GOT_DTPREL16 91 -#define R_PPC_GOT_DTPREL16_LO 92 -#define R_PPC_GOT_DTPREL16_HI 93 -#define R_PPC_GOT_DTPREL16_HA 94 - - - -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 - - -#define R_PPC_DIAB_SDA21_LO 180 -#define R_PPC_DIAB_SDA21_HI 181 -#define R_PPC_DIAB_SDA21_HA 182 -#define R_PPC_DIAB_RELSDA_LO 183 -#define R_PPC_DIAB_RELSDA_HI 184 -#define R_PPC_DIAB_RELSDA_HA 185 - - -#define R_PPC_IRELATIVE 248 - - -#define R_PPC_REL16 249 -#define R_PPC_REL16_LO 250 -#define R_PPC_REL16_HI 251 -#define R_PPC_REL16_HA 252 - - - -#define R_PPC_TOC16 255 - - -#define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_NUM 1 - - -#define R_PPC64_NONE R_PPC_NONE -#define R_PPC64_ADDR32 R_PPC_ADDR32 -#define R_PPC64_ADDR24 R_PPC_ADDR24 -#define R_PPC64_ADDR16 R_PPC_ADDR16 -#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO -#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI -#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA -#define R_PPC64_ADDR14 R_PPC_ADDR14 -#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -#define R_PPC64_REL24 R_PPC_REL24 -#define R_PPC64_REL14 R_PPC_REL14 -#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -#define R_PPC64_GOT16 R_PPC_GOT16 -#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -#define R_PPC64_GOT16_HA R_PPC_GOT16_HA - -#define R_PPC64_COPY R_PPC_COPY -#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -#define R_PPC64_RELATIVE R_PPC_RELATIVE - -#define R_PPC64_UADDR32 R_PPC_UADDR32 -#define R_PPC64_UADDR16 R_PPC_UADDR16 -#define R_PPC64_REL32 R_PPC_REL32 -#define R_PPC64_PLT32 R_PPC_PLT32 -#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -#define R_PPC64_PLT16_HA R_PPC_PLT16_HA - -#define R_PPC64_SECTOFF R_PPC_SECTOFF -#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -#define R_PPC64_ADDR30 37 -#define R_PPC64_ADDR64 38 -#define R_PPC64_ADDR16_HIGHER 39 -#define R_PPC64_ADDR16_HIGHERA 40 -#define R_PPC64_ADDR16_HIGHEST 41 -#define R_PPC64_ADDR16_HIGHESTA 42 -#define R_PPC64_UADDR64 43 -#define R_PPC64_REL64 44 -#define R_PPC64_PLT64 45 -#define R_PPC64_PLTREL64 46 -#define R_PPC64_TOC16 47 -#define R_PPC64_TOC16_LO 48 -#define R_PPC64_TOC16_HI 49 -#define R_PPC64_TOC16_HA 50 -#define R_PPC64_TOC 51 -#define R_PPC64_PLTGOT16 52 -#define R_PPC64_PLTGOT16_LO 53 -#define R_PPC64_PLTGOT16_HI 54 -#define R_PPC64_PLTGOT16_HA 55 - -#define R_PPC64_ADDR16_DS 56 -#define R_PPC64_ADDR16_LO_DS 57 -#define R_PPC64_GOT16_DS 58 -#define R_PPC64_GOT16_LO_DS 59 -#define R_PPC64_PLT16_LO_DS 60 -#define R_PPC64_SECTOFF_DS 61 -#define R_PPC64_SECTOFF_LO_DS 62 -#define R_PPC64_TOC16_DS 63 -#define R_PPC64_TOC16_LO_DS 64 -#define R_PPC64_PLTGOT16_DS 65 -#define R_PPC64_PLTGOT16_LO_DS 66 - - -#define R_PPC64_TLS 67 -#define R_PPC64_DTPMOD64 68 -#define R_PPC64_TPREL16 69 -#define R_PPC64_TPREL16_LO 70 -#define R_PPC64_TPREL16_HI 71 -#define R_PPC64_TPREL16_HA 72 -#define R_PPC64_TPREL64 73 -#define R_PPC64_DTPREL16 74 -#define R_PPC64_DTPREL16_LO 75 -#define R_PPC64_DTPREL16_HI 76 -#define R_PPC64_DTPREL16_HA 77 -#define R_PPC64_DTPREL64 78 -#define R_PPC64_GOT_TLSGD16 79 -#define R_PPC64_GOT_TLSGD16_LO 80 -#define R_PPC64_GOT_TLSGD16_HI 81 -#define R_PPC64_GOT_TLSGD16_HA 82 -#define R_PPC64_GOT_TLSLD16 83 -#define R_PPC64_GOT_TLSLD16_LO 84 -#define R_PPC64_GOT_TLSLD16_HI 85 -#define R_PPC64_GOT_TLSLD16_HA 86 -#define R_PPC64_GOT_TPREL16_DS 87 -#define R_PPC64_GOT_TPREL16_LO_DS 88 -#define R_PPC64_GOT_TPREL16_HI 89 -#define R_PPC64_GOT_TPREL16_HA 90 -#define R_PPC64_GOT_DTPREL16_DS 91 -#define R_PPC64_GOT_DTPREL16_LO_DS 92 -#define R_PPC64_GOT_DTPREL16_HI 93 -#define R_PPC64_GOT_DTPREL16_HA 94 -#define R_PPC64_TPREL16_DS 95 -#define R_PPC64_TPREL16_LO_DS 96 -#define R_PPC64_TPREL16_HIGHER 97 -#define R_PPC64_TPREL16_HIGHERA 98 -#define R_PPC64_TPREL16_HIGHEST 99 -#define R_PPC64_TPREL16_HIGHESTA 100 -#define R_PPC64_DTPREL16_DS 101 -#define R_PPC64_DTPREL16_LO_DS 102 -#define R_PPC64_DTPREL16_HIGHER 103 -#define R_PPC64_DTPREL16_HIGHERA 104 -#define R_PPC64_DTPREL16_HIGHEST 105 -#define R_PPC64_DTPREL16_HIGHESTA 106 - - -#define R_PPC64_JMP_IREL 247 -#define R_PPC64_IRELATIVE 248 -#define R_PPC64_REL16 249 -#define R_PPC64_REL16_LO 250 -#define R_PPC64_REL16_HI 251 -#define R_PPC64_REL16_HA 252 - - -#define DT_PPC64_GLINK (DT_LOPROC + 0) -#define DT_PPC64_OPD (DT_LOPROC + 1) -#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -#define DT_PPC64_NUM 3 - - - - - -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ARM_ALIGN8 0x40 -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 -#define EF_ARM_MAVERICK_FLOAT 0x800 - -#define EF_ARM_ABI_FLOAT_SOFT 0x200 -#define EF_ARM_ABI_FLOAT_HARD 0x400 - - -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0XFF000000 - - -#define EF_ARM_BE8 0x00800000 -#define EF_ARM_LE8 0x00400000 - -#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -#define EF_ARM_EABI_UNKNOWN 0x00000000 -#define EF_ARM_EABI_VER1 0x01000000 -#define EF_ARM_EABI_VER2 0x02000000 -#define EF_ARM_EABI_VER3 0x03000000 -#define EF_ARM_EABI_VER4 0x04000000 -#define EF_ARM_EABI_VER5 0x05000000 - - -#define STT_ARM_TFUNC STT_LOPROC -#define STT_ARM_16BIT STT_HIPROC - - -#define SHF_ARM_ENTRYSECT 0x10000000 -#define SHF_ARM_COMDEF 0x80000000 - - - -#define PF_ARM_SB 0x10000000 - -#define PF_ARM_PI 0x20000000 -#define PF_ARM_ABS 0x40000000 - - -#define PT_ARM_EXIDX (PT_LOPROC + 1) - - -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) - - -#define R_AARCH64_NONE 0 -#define R_AARCH64_ABS64 257 -#define R_AARCH64_ABS32 258 -#define R_AARCH64_ABS16 259 -#define R_AARCH64_PREL64 260 -#define R_AARCH64_PREL32 261 -#define R_AARCH64_PREL16 262 -#define R_AARCH64_MOVW_UABS_G0 263 -#define R_AARCH64_MOVW_UABS_G0_NC 264 -#define R_AARCH64_MOVW_UABS_G1 265 -#define R_AARCH64_MOVW_UABS_G1_NC 266 -#define R_AARCH64_MOVW_UABS_G2 267 -#define R_AARCH64_MOVW_UABS_G2_NC 268 -#define R_AARCH64_MOVW_UABS_G3 269 -#define R_AARCH64_MOVW_SABS_G0 270 -#define R_AARCH64_MOVW_SABS_G1 271 -#define R_AARCH64_MOVW_SABS_G2 272 -#define R_AARCH64_LD_PREL_LO19 273 -#define R_AARCH64_ADR_PREL_LO21 274 -#define R_AARCH64_ADR_PREL_PG_HI21 275 -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 -#define R_AARCH64_ADD_ABS_LO12_NC 277 -#define R_AARCH64_LDST8_ABS_LO12_NC 278 -#define R_AARCH64_TSTBR14 279 -#define R_AARCH64_CONDBR19 280 -#define R_AARCH64_JUMP26 282 -#define R_AARCH64_CALL26 283 -#define R_AARCH64_LDST16_ABS_LO12_NC 284 -#define R_AARCH64_LDST32_ABS_LO12_NC 285 -#define R_AARCH64_LDST64_ABS_LO12_NC 286 -#define R_AARCH64_MOVW_PREL_G0 287 -#define R_AARCH64_MOVW_PREL_G0_NC 288 -#define R_AARCH64_MOVW_PREL_G1 289 -#define R_AARCH64_MOVW_PREL_G1_NC 290 -#define R_AARCH64_MOVW_PREL_G2 291 -#define R_AARCH64_MOVW_PREL_G2_NC 292 -#define R_AARCH64_MOVW_PREL_G3 293 -#define R_AARCH64_LDST128_ABS_LO12_NC 299 -#define R_AARCH64_MOVW_GOTOFF_G0 300 -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 -#define R_AARCH64_MOVW_GOTOFF_G1 302 -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 -#define R_AARCH64_MOVW_GOTOFF_G2 304 -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 -#define R_AARCH64_MOVW_GOTOFF_G3 306 -#define R_AARCH64_GOTREL64 307 -#define R_AARCH64_GOTREL32 308 -#define R_AARCH64_GOT_LD_PREL19 309 -#define R_AARCH64_LD64_GOTOFF_LO15 310 -#define R_AARCH64_ADR_GOT_PAGE 311 -#define R_AARCH64_LD64_GOT_LO12_NC 312 -#define R_AARCH64_LD64_GOTPAGE_LO15 313 -#define R_AARCH64_TLSGD_ADR_PREL21 512 -#define R_AARCH64_TLSGD_ADR_PAGE21 513 -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 -#define R_AARCH64_TLSGD_MOVW_G1 515 -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 -#define R_AARCH64_TLSLD_ADR_PREL21 517 -#define R_AARCH64_TLSLD_ADR_PAGE21 518 -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 -#define R_AARCH64_TLSLD_MOVW_G1 520 -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 -#define R_AARCH64_TLSLD_LD_PREL19 522 -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 -#define R_AARCH64_TLSDESC_LD_PREL19 560 -#define R_AARCH64_TLSDESC_ADR_PREL21 561 -#define R_AARCH64_TLSDESC_ADR_PAGE21 562 -#define R_AARCH64_TLSDESC_LD64_LO12 563 -#define R_AARCH64_TLSDESC_ADD_LO12 564 -#define R_AARCH64_TLSDESC_OFF_G1 565 -#define R_AARCH64_TLSDESC_OFF_G0_NC 566 -#define R_AARCH64_TLSDESC_LDR 567 -#define R_AARCH64_TLSDESC_ADD 568 -#define R_AARCH64_TLSDESC_CALL 569 -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 -#define R_AARCH64_COPY 1024 -#define R_AARCH64_GLOB_DAT 1025 -#define R_AARCH64_JUMP_SLOT 1026 -#define R_AARCH64_RELATIVE 1027 -#define R_AARCH64_TLS_DTPMOD64 1028 -#define R_AARCH64_TLS_DTPREL64 1029 -#define R_AARCH64_TLS_TPREL64 1030 -#define R_AARCH64_TLSDESC 1031 - - -#define R_ARM_NONE 0 -#define R_ARM_PC24 1 -#define R_ARM_ABS32 2 -#define R_ARM_REL32 3 -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 -#define R_ARM_ABS12 6 -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_TLS_DESC 13 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#define R_ARM_TLS_DTPMOD32 17 -#define R_ARM_TLS_DTPOFF32 18 -#define R_ARM_TLS_TPOFF32 19 -#define R_ARM_COPY 20 -#define R_ARM_GLOB_DAT 21 -#define R_ARM_JUMP_SLOT 22 -#define R_ARM_RELATIVE 23 -#define R_ARM_GOTOFF 24 -#define R_ARM_GOTPC 25 -#define R_ARM_GOT32 26 -#define R_ARM_PLT32 27 -#define R_ARM_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_THM_JUMP24 30 -#define R_ARM_BASE_ABS 31 -#define R_ARM_ALU_PCREL_7_0 32 -#define R_ARM_ALU_PCREL_15_8 33 -#define R_ARM_ALU_PCREL_23_15 34 -#define R_ARM_LDR_SBREL_11_0 35 -#define R_ARM_ALU_SBREL_19_12 36 -#define R_ARM_ALU_SBREL_27_20 37 -#define R_ARM_TARGET1 38 -#define R_ARM_SBREL31 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_ABS_NC 43 -#define R_ARM_MOVT_ABS 44 -#define R_ARM_MOVW_PREL_NC 45 -#define R_ARM_MOVT_PREL 46 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 -#define R_ARM_THM_MOVW_PREL_NC 49 -#define R_ARM_THM_MOVT_PREL 50 -#define R_ARM_THM_JUMP19 51 -#define R_ARM_THM_JUMP6 52 -#define R_ARM_THM_ALU_PREL_11_0 53 -#define R_ARM_THM_PC12 54 -#define R_ARM_ABS32_NOI 55 -#define R_ARM_REL32_NOI 56 -#define R_ARM_ALU_PC_G0_NC 57 -#define R_ARM_ALU_PC_G0 58 -#define R_ARM_ALU_PC_G1_NC 59 -#define R_ARM_ALU_PC_G1 60 -#define R_ARM_ALU_PC_G2 61 -#define R_ARM_LDR_PC_G1 62 -#define R_ARM_LDR_PC_G2 63 -#define R_ARM_LDRS_PC_G0 64 -#define R_ARM_LDRS_PC_G1 65 -#define R_ARM_LDRS_PC_G2 66 -#define R_ARM_LDC_PC_G0 67 -#define R_ARM_LDC_PC_G1 68 -#define R_ARM_LDC_PC_G2 69 -#define R_ARM_ALU_SB_G0_NC 70 -#define R_ARM_ALU_SB_G0 71 -#define R_ARM_ALU_SB_G1_NC 72 -#define R_ARM_ALU_SB_G1 73 -#define R_ARM_ALU_SB_G2 74 -#define R_ARM_LDR_SB_G0 75 -#define R_ARM_LDR_SB_G1 76 -#define R_ARM_LDR_SB_G2 77 -#define R_ARM_LDRS_SB_G0 78 -#define R_ARM_LDRS_SB_G1 79 -#define R_ARM_LDRS_SB_G2 80 -#define R_ARM_LDC_SB_G0 81 -#define R_ARM_LDC_SB_G1 82 -#define R_ARM_LDC_SB_G2 83 -#define R_ARM_MOVW_BREL_NC 84 -#define R_ARM_MOVT_BREL 85 -#define R_ARM_MOVW_BREL 86 -#define R_ARM_THM_MOVW_BREL_NC 87 -#define R_ARM_THM_MOVT_BREL 88 -#define R_ARM_THM_MOVW_BREL 89 -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_PLT32_ABS 94 -#define R_ARM_GOT_ABS 95 -#define R_ARM_GOT_PREL 96 -#define R_ARM_GOT_BREL12 97 -#define R_ARM_GOTOFF12 98 -#define R_ARM_GOTRELAX 99 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 -#define R_ARM_THM_PC9 103 -#define R_ARM_TLS_GD32 104 - -#define R_ARM_TLS_LDM32 105 - -#define R_ARM_TLS_LDO32 106 - -#define R_ARM_TLS_IE32 107 - -#define R_ARM_TLS_LE32 108 -#define R_ARM_TLS_LDO12 109 -#define R_ARM_TLS_LE12 110 -#define R_ARM_TLS_IE12GP 111 -#define R_ARM_ME_TOO 128 -#define R_ARM_THM_TLS_DESCSEQ 129 -#define R_ARM_THM_TLS_DESCSEQ16 129 -#define R_ARM_THM_TLS_DESCSEQ32 130 -#define R_ARM_THM_GOT_BREL12 131 -#define R_ARM_IRELATIVE 160 -#define R_ARM_RXPC25 249 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS22 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 - -#define R_ARM_NUM 256 - - - - -#define EF_IA_64_MASKOS 0x0000000f -#define EF_IA_64_ABI64 0x00000010 -#define EF_IA_64_ARCH 0xff000000 - - -#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) -#define PT_IA_64_UNWIND (PT_LOPROC + 1) -#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) - - -#define PF_IA_64_NORECOV 0x80000000 - - -#define SHT_IA_64_EXT (SHT_LOPROC + 0) -#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) - - -#define SHF_IA_64_SHORT 0x10000000 -#define SHF_IA_64_NORECOV 0x20000000 - - -#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -#define DT_IA_64_NUM 1 - - -#define R_IA64_NONE 0x00 -#define R_IA64_IMM14 0x21 -#define R_IA64_IMM22 0x22 -#define R_IA64_IMM64 0x23 -#define R_IA64_DIR32MSB 0x24 -#define R_IA64_DIR32LSB 0x25 -#define R_IA64_DIR64MSB 0x26 -#define R_IA64_DIR64LSB 0x27 -#define R_IA64_GPREL22 0x2a -#define R_IA64_GPREL64I 0x2b -#define R_IA64_GPREL32MSB 0x2c -#define R_IA64_GPREL32LSB 0x2d -#define R_IA64_GPREL64MSB 0x2e -#define R_IA64_GPREL64LSB 0x2f -#define R_IA64_LTOFF22 0x32 -#define R_IA64_LTOFF64I 0x33 -#define R_IA64_PLTOFF22 0x3a -#define R_IA64_PLTOFF64I 0x3b -#define R_IA64_PLTOFF64MSB 0x3e -#define R_IA64_PLTOFF64LSB 0x3f -#define R_IA64_FPTR64I 0x43 -#define R_IA64_FPTR32MSB 0x44 -#define R_IA64_FPTR32LSB 0x45 -#define R_IA64_FPTR64MSB 0x46 -#define R_IA64_FPTR64LSB 0x47 -#define R_IA64_PCREL60B 0x48 -#define R_IA64_PCREL21B 0x49 -#define R_IA64_PCREL21M 0x4a -#define R_IA64_PCREL21F 0x4b -#define R_IA64_PCREL32MSB 0x4c -#define R_IA64_PCREL32LSB 0x4d -#define R_IA64_PCREL64MSB 0x4e -#define R_IA64_PCREL64LSB 0x4f -#define R_IA64_LTOFF_FPTR22 0x52 -#define R_IA64_LTOFF_FPTR64I 0x53 -#define R_IA64_LTOFF_FPTR32MSB 0x54 -#define R_IA64_LTOFF_FPTR32LSB 0x55 -#define R_IA64_LTOFF_FPTR64MSB 0x56 -#define R_IA64_LTOFF_FPTR64LSB 0x57 -#define R_IA64_SEGREL32MSB 0x5c -#define R_IA64_SEGREL32LSB 0x5d -#define R_IA64_SEGREL64MSB 0x5e -#define R_IA64_SEGREL64LSB 0x5f -#define R_IA64_SECREL32MSB 0x64 -#define R_IA64_SECREL32LSB 0x65 -#define R_IA64_SECREL64MSB 0x66 -#define R_IA64_SECREL64LSB 0x67 -#define R_IA64_REL32MSB 0x6c -#define R_IA64_REL32LSB 0x6d -#define R_IA64_REL64MSB 0x6e -#define R_IA64_REL64LSB 0x6f -#define R_IA64_LTV32MSB 0x74 -#define R_IA64_LTV32LSB 0x75 -#define R_IA64_LTV64MSB 0x76 -#define R_IA64_LTV64LSB 0x77 -#define R_IA64_PCREL21BI 0x79 -#define R_IA64_PCREL22 0x7a -#define R_IA64_PCREL64I 0x7b -#define R_IA64_IPLTMSB 0x80 -#define R_IA64_IPLTLSB 0x81 -#define R_IA64_COPY 0x84 -#define R_IA64_SUB 0x85 -#define R_IA64_LTOFF22X 0x86 -#define R_IA64_LDXMOV 0x87 -#define R_IA64_TPREL14 0x91 -#define R_IA64_TPREL22 0x92 -#define R_IA64_TPREL64I 0x93 -#define R_IA64_TPREL64MSB 0x96 -#define R_IA64_TPREL64LSB 0x97 -#define R_IA64_LTOFF_TPREL22 0x9a -#define R_IA64_DTPMOD64MSB 0xa6 -#define R_IA64_DTPMOD64LSB 0xa7 -#define R_IA64_LTOFF_DTPMOD22 0xaa -#define R_IA64_DTPREL14 0xb1 -#define R_IA64_DTPREL22 0xb2 -#define R_IA64_DTPREL64I 0xb3 -#define R_IA64_DTPREL32MSB 0xb4 -#define R_IA64_DTPREL32LSB 0xb5 -#define R_IA64_DTPREL64MSB 0xb6 -#define R_IA64_DTPREL64LSB 0xb7 -#define R_IA64_LTOFF_DTPREL22 0xba - - - - -#define R_SH_NONE 0 -#define R_SH_DIR32 1 -#define R_SH_REL32 2 -#define R_SH_DIR8WPN 3 -#define R_SH_IND12W 4 -#define R_SH_DIR8WPL 5 -#define R_SH_DIR8WPZ 6 -#define R_SH_DIR8BP 7 -#define R_SH_DIR8W 8 -#define R_SH_DIR8L 9 -#define R_SH_SWITCH16 25 -#define R_SH_SWITCH32 26 -#define R_SH_USES 27 -#define R_SH_COUNT 28 -#define R_SH_ALIGN 29 -#define R_SH_CODE 30 -#define R_SH_DATA 31 -#define R_SH_LABEL 32 -#define R_SH_SWITCH8 33 -#define R_SH_GNU_VTINHERIT 34 -#define R_SH_GNU_VTENTRY 35 -#define R_SH_TLS_GD_32 144 -#define R_SH_TLS_LD_32 145 -#define R_SH_TLS_LDO_32 146 -#define R_SH_TLS_IE_32 147 -#define R_SH_TLS_LE_32 148 -#define R_SH_TLS_DTPMOD32 149 -#define R_SH_TLS_DTPOFF32 150 -#define R_SH_TLS_TPOFF32 151 -#define R_SH_GOT32 160 -#define R_SH_PLT32 161 -#define R_SH_COPY 162 -#define R_SH_GLOB_DAT 163 -#define R_SH_JMP_SLOT 164 -#define R_SH_RELATIVE 165 -#define R_SH_GOTOFF 166 -#define R_SH_GOTPC 167 -#define R_SH_GOT20 201 -#define R_SH_GOTOFF20 202 -#define R_SH_GOTFUNCDESC 203 -#define R_SH_GOTFUNCDEST20 204 -#define R_SH_GOTOFFFUNCDESC 205 -#define R_SH_GOTOFFFUNCDEST20 206 -#define R_SH_FUNCDESC 207 -#define R_SH_FUNCDESC_VALUE 208 - -#define R_SH_NUM 256 - - - -#define R_390_NONE 0 -#define R_390_8 1 -#define R_390_12 2 -#define R_390_16 3 -#define R_390_32 4 -#define R_390_PC32 5 -#define R_390_GOT12 6 -#define R_390_GOT32 7 -#define R_390_PLT32 8 -#define R_390_COPY 9 -#define R_390_GLOB_DAT 10 -#define R_390_JMP_SLOT 11 -#define R_390_RELATIVE 12 -#define R_390_GOTOFF32 13 -#define R_390_GOTPC 14 -#define R_390_GOT16 15 -#define R_390_PC16 16 -#define R_390_PC16DBL 17 -#define R_390_PLT16DBL 18 -#define R_390_PC32DBL 19 -#define R_390_PLT32DBL 20 -#define R_390_GOTPCDBL 21 -#define R_390_64 22 -#define R_390_PC64 23 -#define R_390_GOT64 24 -#define R_390_PLT64 25 -#define R_390_GOTENT 26 -#define R_390_GOTOFF16 27 -#define R_390_GOTOFF64 28 -#define R_390_GOTPLT12 29 -#define R_390_GOTPLT16 30 -#define R_390_GOTPLT32 31 -#define R_390_GOTPLT64 32 -#define R_390_GOTPLTENT 33 -#define R_390_PLTOFF16 34 -#define R_390_PLTOFF32 35 -#define R_390_PLTOFF64 36 -#define R_390_TLS_LOAD 37 -#define R_390_TLS_GDCALL 38 - -#define R_390_TLS_LDCALL 39 - -#define R_390_TLS_GD32 40 - -#define R_390_TLS_GD64 41 - -#define R_390_TLS_GOTIE12 42 - -#define R_390_TLS_GOTIE32 43 - -#define R_390_TLS_GOTIE64 44 - -#define R_390_TLS_LDM32 45 - -#define R_390_TLS_LDM64 46 - -#define R_390_TLS_IE32 47 - -#define R_390_TLS_IE64 48 - -#define R_390_TLS_IEENT 49 - -#define R_390_TLS_LE32 50 - -#define R_390_TLS_LE64 51 - -#define R_390_TLS_LDO32 52 - -#define R_390_TLS_LDO64 53 - -#define R_390_TLS_DTPMOD 54 -#define R_390_TLS_DTPOFF 55 -#define R_390_TLS_TPOFF 56 - -#define R_390_20 57 -#define R_390_GOT20 58 -#define R_390_GOTPLT20 59 -#define R_390_TLS_GOTIE20 60 - - -#define R_390_NUM 61 - - - -#define R_CRIS_NONE 0 -#define R_CRIS_8 1 -#define R_CRIS_16 2 -#define R_CRIS_32 3 -#define R_CRIS_8_PCREL 4 -#define R_CRIS_16_PCREL 5 -#define R_CRIS_32_PCREL 6 -#define R_CRIS_GNU_VTINHERIT 7 -#define R_CRIS_GNU_VTENTRY 8 -#define R_CRIS_COPY 9 -#define R_CRIS_GLOB_DAT 10 -#define R_CRIS_JUMP_SLOT 11 -#define R_CRIS_RELATIVE 12 -#define R_CRIS_16_GOT 13 -#define R_CRIS_32_GOT 14 -#define R_CRIS_16_GOTPLT 15 -#define R_CRIS_32_GOTPLT 16 -#define R_CRIS_32_GOTREL 17 -#define R_CRIS_32_PLT_GOTREL 18 -#define R_CRIS_32_PLT_PCREL 19 - -#define R_CRIS_NUM 20 - - - -#define R_X86_64_NONE 0 -#define R_X86_64_64 1 -#define R_X86_64_PC32 2 -#define R_X86_64_GOT32 3 -#define R_X86_64_PLT32 4 -#define R_X86_64_COPY 5 -#define R_X86_64_GLOB_DAT 6 -#define R_X86_64_JUMP_SLOT 7 -#define R_X86_64_RELATIVE 8 -#define R_X86_64_GOTPCREL 9 - -#define R_X86_64_32 10 -#define R_X86_64_32S 11 -#define R_X86_64_16 12 -#define R_X86_64_PC16 13 -#define R_X86_64_8 14 -#define R_X86_64_PC8 15 -#define R_X86_64_DTPMOD64 16 -#define R_X86_64_DTPOFF64 17 -#define R_X86_64_TPOFF64 18 -#define R_X86_64_TLSGD 19 - -#define R_X86_64_TLSLD 20 - -#define R_X86_64_DTPOFF32 21 -#define R_X86_64_GOTTPOFF 22 - -#define R_X86_64_TPOFF32 23 -#define R_X86_64_PC64 24 -#define R_X86_64_GOTOFF64 25 -#define R_X86_64_GOTPC32 26 -#define R_X86_64_GOT64 27 -#define R_X86_64_GOTPCREL64 28 -#define R_X86_64_GOTPC64 29 -#define R_X86_64_GOTPLT64 30 -#define R_X86_64_PLTOFF64 31 -#define R_X86_64_SIZE32 32 -#define R_X86_64_SIZE64 33 - -#define R_X86_64_GOTPC32_TLSDESC 34 -#define R_X86_64_TLSDESC_CALL 35 - -#define R_X86_64_TLSDESC 36 -#define R_X86_64_IRELATIVE 37 -#define R_X86_64_RELATIVE64 38 -#define R_X86_64_NUM 39 - - - -#define R_MN10300_NONE 0 -#define R_MN10300_32 1 -#define R_MN10300_16 2 -#define R_MN10300_8 3 -#define R_MN10300_PCREL32 4 -#define R_MN10300_PCREL16 5 -#define R_MN10300_PCREL8 6 -#define R_MN10300_GNU_VTINHERIT 7 -#define R_MN10300_GNU_VTENTRY 8 -#define R_MN10300_24 9 -#define R_MN10300_GOTPC32 10 -#define R_MN10300_GOTPC16 11 -#define R_MN10300_GOTOFF32 12 -#define R_MN10300_GOTOFF24 13 -#define R_MN10300_GOTOFF16 14 -#define R_MN10300_PLT32 15 -#define R_MN10300_PLT16 16 -#define R_MN10300_GOT32 17 -#define R_MN10300_GOT24 18 -#define R_MN10300_GOT16 19 -#define R_MN10300_COPY 20 -#define R_MN10300_GLOB_DAT 21 -#define R_MN10300_JMP_SLOT 22 -#define R_MN10300_RELATIVE 23 - -#define R_MN10300_NUM 24 - - - -#define R_M32R_NONE 0 -#define R_M32R_16 1 -#define R_M32R_32 2 -#define R_M32R_24 3 -#define R_M32R_10_PCREL 4 -#define R_M32R_18_PCREL 5 -#define R_M32R_26_PCREL 6 -#define R_M32R_HI16_ULO 7 -#define R_M32R_HI16_SLO 8 -#define R_M32R_LO16 9 -#define R_M32R_SDA16 10 -#define R_M32R_GNU_VTINHERIT 11 -#define R_M32R_GNU_VTENTRY 12 - -#define R_M32R_16_RELA 33 -#define R_M32R_32_RELA 34 -#define R_M32R_24_RELA 35 -#define R_M32R_10_PCREL_RELA 36 -#define R_M32R_18_PCREL_RELA 37 -#define R_M32R_26_PCREL_RELA 38 -#define R_M32R_HI16_ULO_RELA 39 -#define R_M32R_HI16_SLO_RELA 40 -#define R_M32R_LO16_RELA 41 -#define R_M32R_SDA16_RELA 42 -#define R_M32R_RELA_GNU_VTINHERIT 43 -#define R_M32R_RELA_GNU_VTENTRY 44 -#define R_M32R_REL32 45 - -#define R_M32R_GOT24 48 -#define R_M32R_26_PLTREL 49 -#define R_M32R_COPY 50 -#define R_M32R_GLOB_DAT 51 -#define R_M32R_JMP_SLOT 52 -#define R_M32R_RELATIVE 53 -#define R_M32R_GOTOFF 54 -#define R_M32R_GOTPC24 55 -#define R_M32R_GOT16_HI_ULO 56 - -#define R_M32R_GOT16_HI_SLO 57 - -#define R_M32R_GOT16_LO 58 -#define R_M32R_GOTPC_HI_ULO 59 - -#define R_M32R_GOTPC_HI_SLO 60 - -#define R_M32R_GOTPC_LO 61 - -#define R_M32R_GOTOFF_HI_ULO 62 - -#define R_M32R_GOTOFF_HI_SLO 63 - -#define R_M32R_GOTOFF_LO 64 -#define R_M32R_NUM 256 - -#define R_MICROBLAZE_NONE 0 -#define R_MICROBLAZE_32 1 -#define R_MICROBLAZE_32_PCREL 2 -#define R_MICROBLAZE_64_PCREL 3 -#define R_MICROBLAZE_32_PCREL_LO 4 -#define R_MICROBLAZE_64 5 -#define R_MICROBLAZE_32_LO 6 -#define R_MICROBLAZE_SRO32 7 -#define R_MICROBLAZE_SRW32 8 -#define R_MICROBLAZE_64_NONE 9 -#define R_MICROBLAZE_32_SYM_OP_SYM 10 -#define R_MICROBLAZE_GNU_VTINHERIT 11 -#define R_MICROBLAZE_GNU_VTENTRY 12 -#define R_MICROBLAZE_GOTPC_64 13 -#define R_MICROBLAZE_GOT_64 14 -#define R_MICROBLAZE_PLT_64 15 -#define R_MICROBLAZE_REL 16 -#define R_MICROBLAZE_JUMP_SLOT 17 -#define R_MICROBLAZE_GLOB_DAT 18 -#define R_MICROBLAZE_GOTOFF_64 19 -#define R_MICROBLAZE_GOTOFF_32 20 -#define R_MICROBLAZE_COPY 21 -#define R_MICROBLAZE_TLS 22 -#define R_MICROBLAZE_TLSGD 23 -#define R_MICROBLAZE_TLSLD 24 -#define R_MICROBLAZE_TLSDTPMOD32 25 -#define R_MICROBLAZE_TLSDTPREL32 26 -#define R_MICROBLAZE_TLSDTPREL64 27 -#define R_MICROBLAZE_TLSGOTTPREL32 28 -#define R_MICROBLAZE_TLSTPREL32 29 - -#define R_OR1K_NONE 0 -#define R_OR1K_32 1 -#define R_OR1K_16 2 -#define R_OR1K_8 3 -#define R_OR1K_LO_16_IN_INSN 4 -#define R_OR1K_HI_16_IN_INSN 5 -#define R_OR1K_INSN_REL_26 6 -#define R_OR1K_GNU_VTENTRY 7 -#define R_OR1K_GNU_VTINHERIT 8 -#define R_OR1K_32_PCREL 9 -#define R_OR1K_16_PCREL 10 -#define R_OR1K_8_PCREL 11 -#define R_OR1K_GOTPC_HI16 12 -#define R_OR1K_GOTPC_LO16 13 -#define R_OR1K_GOT16 14 -#define R_OR1K_PLT26 15 -#define R_OR1K_GOTOFF_HI16 16 -#define R_OR1K_GOTOFF_LO16 17 -#define R_OR1K_COPY 18 -#define R_OR1K_GLOB_DAT 19 -#define R_OR1K_JMP_SLOT 20 -#define R_OR1K_RELATIVE 21 -#define R_OR1K_TLS_GD_HI16 22 -#define R_OR1K_TLS_GD_LO16 23 -#define R_OR1K_TLS_LDM_HI16 24 -#define R_OR1K_TLS_LDM_LO16 25 -#define R_OR1K_TLS_LDO_HI16 26 -#define R_OR1K_TLS_LDO_LO16 27 -#define R_OR1K_TLS_IE_HI16 28 -#define R_OR1K_TLS_IE_LO16 29 -#define R_OR1K_TLS_LE_HI16 30 -#define R_OR1K_TLS_LE_LO16 31 -#define R_OR1K_TLS_TPOFF 32 -#define R_OR1K_TLS_DTPOFF 33 -#define R_OR1K_TLS_DTPMOD 34 - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc deleted file mode 100644 index a0e8f8ba2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// core2md.cc: A utility to convert an ELF core file to a minidump file. - -#include - -#include "client/linux/minidump_writer/minidump_writer.h" -#include "client/linux/minidump_writer/linux_core_dumper.h" - -using google_breakpad::AppMemoryList; -using google_breakpad::MappingList; -using google_breakpad::LinuxCoreDumper; - -static int ShowUsage(const char* argv0) { - fprintf(stderr, "Usage: %s \n", argv0); - return 1; -} - -bool WriteMinidumpFromCore(const char* filename, - const char* core_path, - const char* procfs_override) { - MappingList mappings; - AppMemoryList memory_list; - LinuxCoreDumper dumper(0, core_path, procfs_override); - return google_breakpad::WriteMinidump(filename, mappings, memory_list, - &dumper); -} - -int main(int argc, char *argv[]) { - if (argc != 4) { - return ShowUsage(argv[0]); - } - - const char* core_file = argv[1]; - const char* procfs_dir = argv[2]; - const char* minidump_file = argv[3]; - if (!WriteMinidumpFromCore(minidump_file, - core_file, - procfs_dir)) { - fprintf(stderr, "Unable to generate minidump.\n"); - return 1; - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc deleted file mode 100644 index 84953172e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include - -#include -#include -#include -#include - -#include "common/linux/dump_symbols.h" - -using google_breakpad::WriteSymbolFile; -using google_breakpad::WriteSymbolFileHeader; - -int usage(const char* self) { - fprintf(stderr, "Usage: %s [OPTION] " - "[directories-for-debug-file]\n\n", self); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -i: Output module header information only.\n"); - fprintf(stderr, " -c Do not generate CFI section\n"); - fprintf(stderr, " -r Do not handle inter-compilation unit references\n"); - fprintf(stderr, " -v Print all warnings to stderr\n"); - return 1; -} - -int main(int argc, char **argv) { - if (argc < 2) - return usage(argv[0]); - bool header_only = false; - bool cfi = true; - bool handle_inter_cu_refs = true; - bool log_to_stderr = false; - int arg_index = 1; - while (arg_index < argc && strlen(argv[arg_index]) > 0 && - argv[arg_index][0] == '-') { - if (strcmp("-i", argv[arg_index]) == 0) { - header_only = true; - } else if (strcmp("-c", argv[arg_index]) == 0) { - cfi = false; - } else if (strcmp("-r", argv[arg_index]) == 0) { - handle_inter_cu_refs = false; - } else if (strcmp("-v", argv[arg_index]) == 0) { - log_to_stderr = true; - } else { - printf("2.4 %s\n", argv[arg_index]); - return usage(argv[0]); - } - ++arg_index; - } - if (arg_index == argc) - return usage(argv[0]); - // Save stderr so it can be used below. - FILE* saved_stderr = fdopen(dup(fileno(stderr)), "w"); - if (!log_to_stderr) { - if (freopen(_PATH_DEVNULL, "w", stderr)) { - // If it fails, not a lot we can (or should) do. - // Add this brace section to silence gcc warnings. - } - } - const char* binary; - std::vector debug_dirs; - binary = argv[arg_index]; - for (int debug_dir_index = arg_index + 1; - debug_dir_index < argc; - ++debug_dir_index) { - debug_dirs.push_back(argv[debug_dir_index]); - } - - if (header_only) { - if (!WriteSymbolFileHeader(binary, std::cout)) { - fprintf(saved_stderr, "Failed to process file.\n"); - return 1; - } - } else { - SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI; - google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs); - if (!WriteSymbolFile(binary, debug_dirs, options, std::cout)) { - fprintf(saved_stderr, "Failed to write symbol file.\n"); - return 1; - } - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build deleted file mode 100644 index 643020e84..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build +++ /dev/null @@ -1,33 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_SOURCES += [ - 'dump_syms.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -# host_breakpad_linux_common_s needs to come first -HOST_USE_LIBS += [ - 'host_breakpad_linux_common_s', -] -HOST_USE_LIBS += [ - 'host_breakpad_common_s', - 'host_breakpad_dwarf_s', -] - -# The HostProgram template may append 'host_stdc++compat' to -# HOST_USE_LIBS, which needs to appear after the entries above. -HostProgram('dump_syms') - -LOCAL_INCLUDES += [ - '../../../common/linux', -] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc deleted file mode 100644 index 6f637845e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc +++ /dev/null @@ -1,1276 +0,0 @@ -// Copyright (c) 2009, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Converts a minidump file to a core file which gdb can read. -// Large parts lifted from the userspace core dumper: -// http://code.google.com/p/google-coredumper/ -// -// Usage: minidump-2-core [-v] 1234.dmp > core - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/linux/memory_mapped_file.h" -#include "common/minidump_type_helper.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "third_party/lss/linux_syscall_support.h" -#include "tools/linux/md2core/minidump_memory_range.h" - -#if __WORDSIZE == 64 - #define ELF_CLASS ELFCLASS64 -#else - #define ELF_CLASS ELFCLASS32 -#endif -#define Ehdr ElfW(Ehdr) -#define Phdr ElfW(Phdr) -#define Shdr ElfW(Shdr) -#define Nhdr ElfW(Nhdr) -#define auxv_t ElfW(auxv_t) - - -#if defined(__x86_64__) - #define ELF_ARCH EM_X86_64 -#elif defined(__i386__) - #define ELF_ARCH EM_386 -#elif defined(__arm__) - #define ELF_ARCH EM_ARM -#elif defined(__mips__) - #define ELF_ARCH EM_MIPS -#elif defined(__aarch64__) - #define ELF_ARCH EM_AARCH64 -#endif - -#if defined(__arm__) -// GLibc/ARM and Android/ARM both use 'user_regs' for the structure type -// containing core registers, while they use 'user_regs_struct' on other -// architectures. This file-local typedef simplifies the source code. -typedef user_regs user_regs_struct; -#elif defined (__mips__) -// This file-local typedef simplifies the source code. -typedef gregset_t user_regs_struct; -#endif - -using google_breakpad::MDTypeHelper; -using google_breakpad::MemoryMappedFile; -using google_breakpad::MinidumpMemoryRange; - -typedef MDTypeHelper::MDRawDebug MDRawDebug; -typedef MDTypeHelper::MDRawLinkMap MDRawLinkMap; - -static const MDRVA kInvalidMDRVA = static_cast(-1); -static bool verbose; -static string g_custom_so_basedir; - -static int usage(const char* argv0) { - fprintf(stderr, "Usage: %s [-v] \n", argv0); - return 1; -} - -// Write all of the given buffer, handling short writes and EINTR. Return true -// iff successful. -static bool -writea(int fd, const void* idata, size_t length) { - const uint8_t* data = (const uint8_t*) idata; - - size_t done = 0; - while (done < length) { - ssize_t r; - do { - r = write(fd, data + done, length - done); - } while (r == -1 && errno == EINTR); - - if (r < 1) - return false; - done += r; - } - - return true; -} - -/* Dynamically determines the byte sex of the system. Returns non-zero - * for big-endian machines. - */ -static inline int sex() { - int probe = 1; - return !*(char *)&probe; -} - -typedef struct elf_timeval { /* Time value with microsecond resolution */ - long tv_sec; /* Seconds */ - long tv_usec; /* Microseconds */ -} elf_timeval; - -typedef struct _elf_siginfo { /* Information about signal (unused) */ - int32_t si_signo; /* Signal number */ - int32_t si_code; /* Extra code */ - int32_t si_errno; /* Errno */ -} _elf_siginfo; - -typedef struct prstatus { /* Information about thread; includes CPU reg*/ - _elf_siginfo pr_info; /* Info associated with signal */ - uint16_t pr_cursig; /* Current signal */ - unsigned long pr_sigpend; /* Set of pending signals */ - unsigned long pr_sighold; /* Set of held signals */ - pid_t pr_pid; /* Process ID */ - pid_t pr_ppid; /* Parent's process ID */ - pid_t pr_pgrp; /* Group ID */ - pid_t pr_sid; /* Session ID */ - elf_timeval pr_utime; /* User time */ - elf_timeval pr_stime; /* System time */ - elf_timeval pr_cutime; /* Cumulative user time */ - elf_timeval pr_cstime; /* Cumulative system time */ - user_regs_struct pr_reg; /* CPU registers */ - uint32_t pr_fpvalid; /* True if math co-processor being used */ -} prstatus; - -typedef struct prpsinfo { /* Information about process */ - unsigned char pr_state; /* Numeric process state */ - char pr_sname; /* Char for pr_state */ - unsigned char pr_zomb; /* Zombie */ - signed char pr_nice; /* Nice val */ - unsigned long pr_flag; /* Flags */ -#if defined(__x86_64__) || defined(__mips__) - uint32_t pr_uid; /* User ID */ - uint32_t pr_gid; /* Group ID */ -#else - uint16_t pr_uid; /* User ID */ - uint16_t pr_gid; /* Group ID */ -#endif - pid_t pr_pid; /* Process ID */ - pid_t pr_ppid; /* Parent's process ID */ - pid_t pr_pgrp; /* Group ID */ - pid_t pr_sid; /* Session ID */ - char pr_fname[16]; /* Filename of executable */ - char pr_psargs[80]; /* Initial part of arg list */ -} prpsinfo; - -// We parse the minidump file and keep the parsed information in this structure -struct CrashedProcess { - CrashedProcess() - : crashing_tid(-1), - auxv(NULL), - auxv_length(0) { - memset(&prps, 0, sizeof(prps)); - prps.pr_sname = 'R'; - memset(&debug, 0, sizeof(debug)); - } - - struct Mapping { - Mapping() - : permissions(0xFFFFFFFF), - start_address(0), - end_address(0), - offset(0) { - } - - uint32_t permissions; - uint64_t start_address, end_address, offset; - string filename; - string data; - }; - std::map mappings; - - pid_t crashing_tid; - int fatal_signal; - - struct Thread { - pid_t tid; -#if defined(__mips__) - mcontext_t mcontext; -#else - user_regs_struct regs; -#endif -#if defined(__i386__) || defined(__x86_64__) - user_fpregs_struct fpregs; -#endif -#if defined(__i386__) - user_fpxregs_struct fpxregs; -#endif -#if defined(__aarch64__) - user_fpsimd_struct fpregs; -#endif - uintptr_t stack_addr; - const uint8_t* stack; - size_t stack_length; - }; - std::vector threads; - - const uint8_t* auxv; - size_t auxv_length; - - prpsinfo prps; - - std::map signatures; - - string dynamic_data; - MDRawDebug debug; - std::vector link_map; -}; - -#if defined(__i386__) -static uint32_t -U32(const uint8_t* data) { - uint32_t v; - memcpy(&v, data, sizeof(v)); - return v; -} - -static uint16_t -U16(const uint8_t* data) { - uint16_t v; - memcpy(&v, data, sizeof(v)); - return v; -} - -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextX86* rawregs = range.GetData(0); - - thread->regs.ebx = rawregs->ebx; - thread->regs.ecx = rawregs->ecx; - thread->regs.edx = rawregs->edx; - thread->regs.esi = rawregs->esi; - thread->regs.edi = rawregs->edi; - thread->regs.ebp = rawregs->ebp; - thread->regs.eax = rawregs->eax; - thread->regs.xds = rawregs->ds; - thread->regs.xes = rawregs->es; - thread->regs.xfs = rawregs->fs; - thread->regs.xgs = rawregs->gs; - thread->regs.orig_eax = rawregs->eax; - thread->regs.eip = rawregs->eip; - thread->regs.xcs = rawregs->cs; - thread->regs.eflags = rawregs->eflags; - thread->regs.esp = rawregs->esp; - thread->regs.xss = rawregs->ss; - - thread->fpregs.cwd = rawregs->float_save.control_word; - thread->fpregs.swd = rawregs->float_save.status_word; - thread->fpregs.twd = rawregs->float_save.tag_word; - thread->fpregs.fip = rawregs->float_save.error_offset; - thread->fpregs.fcs = rawregs->float_save.error_selector; - thread->fpregs.foo = rawregs->float_save.data_offset; - thread->fpregs.fos = rawregs->float_save.data_selector; - memcpy(thread->fpregs.st_space, rawregs->float_save.register_area, - 10 * 8); - - thread->fpxregs.cwd = rawregs->float_save.control_word; - thread->fpxregs.swd = rawregs->float_save.status_word; - thread->fpxregs.twd = rawregs->float_save.tag_word; - thread->fpxregs.fop = U16(rawregs->extended_registers + 6); - thread->fpxregs.fip = U16(rawregs->extended_registers + 8); - thread->fpxregs.fcs = U16(rawregs->extended_registers + 12); - thread->fpxregs.foo = U16(rawregs->extended_registers + 16); - thread->fpxregs.fos = U16(rawregs->extended_registers + 20); - thread->fpxregs.mxcsr = U32(rawregs->extended_registers + 24); - memcpy(thread->fpxregs.st_space, rawregs->extended_registers + 32, 128); - memcpy(thread->fpxregs.xmm_space, rawregs->extended_registers + 160, 128); -} -#elif defined(__x86_64__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextAMD64* rawregs = range.GetData(0); - - thread->regs.r15 = rawregs->r15; - thread->regs.r14 = rawregs->r14; - thread->regs.r13 = rawregs->r13; - thread->regs.r12 = rawregs->r12; - thread->regs.rbp = rawregs->rbp; - thread->regs.rbx = rawregs->rbx; - thread->regs.r11 = rawregs->r11; - thread->regs.r10 = rawregs->r10; - thread->regs.r9 = rawregs->r9; - thread->regs.r8 = rawregs->r8; - thread->regs.rax = rawregs->rax; - thread->regs.rcx = rawregs->rcx; - thread->regs.rdx = rawregs->rdx; - thread->regs.rsi = rawregs->rsi; - thread->regs.rdi = rawregs->rdi; - thread->regs.orig_rax = rawregs->rax; - thread->regs.rip = rawregs->rip; - thread->regs.cs = rawregs->cs; - thread->regs.eflags = rawregs->eflags; - thread->regs.rsp = rawregs->rsp; - thread->regs.ss = rawregs->ss; - thread->regs.fs_base = 0; - thread->regs.gs_base = 0; - thread->regs.ds = rawregs->ds; - thread->regs.es = rawregs->es; - thread->regs.fs = rawregs->fs; - thread->regs.gs = rawregs->gs; - - thread->fpregs.cwd = rawregs->flt_save.control_word; - thread->fpregs.swd = rawregs->flt_save.status_word; - thread->fpregs.ftw = rawregs->flt_save.tag_word; - thread->fpregs.fop = rawregs->flt_save.error_opcode; - thread->fpregs.rip = rawregs->flt_save.error_offset; - thread->fpregs.rdp = rawregs->flt_save.data_offset; - thread->fpregs.mxcsr = rawregs->flt_save.mx_csr; - thread->fpregs.mxcr_mask = rawregs->flt_save.mx_csr_mask; - memcpy(thread->fpregs.st_space, rawregs->flt_save.float_registers, 8 * 16); - memcpy(thread->fpregs.xmm_space, rawregs->flt_save.xmm_registers, 16 * 16); -} -#elif defined(__arm__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextARM* rawregs = range.GetData(0); - - thread->regs.uregs[0] = rawregs->iregs[0]; - thread->regs.uregs[1] = rawregs->iregs[1]; - thread->regs.uregs[2] = rawregs->iregs[2]; - thread->regs.uregs[3] = rawregs->iregs[3]; - thread->regs.uregs[4] = rawregs->iregs[4]; - thread->regs.uregs[5] = rawregs->iregs[5]; - thread->regs.uregs[6] = rawregs->iregs[6]; - thread->regs.uregs[7] = rawregs->iregs[7]; - thread->regs.uregs[8] = rawregs->iregs[8]; - thread->regs.uregs[9] = rawregs->iregs[9]; - thread->regs.uregs[10] = rawregs->iregs[10]; - thread->regs.uregs[11] = rawregs->iregs[11]; - thread->regs.uregs[12] = rawregs->iregs[12]; - thread->regs.uregs[13] = rawregs->iregs[13]; - thread->regs.uregs[14] = rawregs->iregs[14]; - thread->regs.uregs[15] = rawregs->iregs[15]; - - thread->regs.uregs[16] = rawregs->cpsr; - thread->regs.uregs[17] = 0; // what is ORIG_r0 exactly? -} -#elif defined(__aarch64__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextARM64* rawregs = range.GetData(0); - - for (int i = 0; i < 31; ++i) - thread->regs.regs[i] = rawregs->iregs[i]; - thread->regs.sp = rawregs->iregs[MD_CONTEXT_ARM64_REG_SP]; - thread->regs.pc = rawregs->iregs[MD_CONTEXT_ARM64_REG_PC]; - thread->regs.pstate = rawregs->cpsr; - - memcpy(thread->fpregs.vregs, rawregs->float_save.regs, 8 * 32); - thread->fpregs.fpsr = rawregs->float_save.fpsr; - thread->fpregs.fpcr = rawregs->float_save.fpcr; -} -#elif defined(__mips__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextMIPS* rawregs = range.GetData(0); - - for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i) - thread->mcontext.gregs[i] = rawregs->iregs[i]; - - thread->mcontext.pc = rawregs->epc; - - thread->mcontext.mdlo = rawregs->mdlo; - thread->mcontext.mdhi = rawregs->mdhi; - - thread->mcontext.hi1 = rawregs->hi[0]; - thread->mcontext.lo1 = rawregs->lo[0]; - thread->mcontext.hi2 = rawregs->hi[1]; - thread->mcontext.lo2 = rawregs->lo[1]; - thread->mcontext.hi3 = rawregs->hi[2]; - thread->mcontext.lo3 = rawregs->lo[2]; - - for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) { - thread->mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs = - rawregs->float_save.regs[i]; - } - - thread->mcontext.fpc_csr = rawregs->float_save.fpcsr; -#if _MIPS_SIM == _ABIO32 - thread->mcontext.fpc_eir = rawregs->float_save.fir; -#endif -} -#else -#error "This code has not been ported to your platform yet" -#endif - -static void -ParseThreadList(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const uint32_t num_threads = *range.GetData(0); - if (verbose) { - fprintf(stderr, - "MD_THREAD_LIST_STREAM:\n" - "Found %d threads\n" - "\n\n", - num_threads); - } - for (unsigned i = 0; i < num_threads; ++i) { - CrashedProcess::Thread thread; - memset(&thread, 0, sizeof(thread)); - const MDRawThread* rawthread = - range.GetArrayElement(sizeof(uint32_t), i); - thread.tid = rawthread->thread_id; - thread.stack_addr = rawthread->stack.start_of_memory_range; - MinidumpMemoryRange stack_range = - full_file.Subrange(rawthread->stack.memory); - thread.stack = stack_range.data(); - thread.stack_length = rawthread->stack.memory.data_size; - - ParseThreadRegisters(&thread, - full_file.Subrange(rawthread->thread_context)); - - crashinfo->threads.push_back(thread); - } -} - -static void -ParseSystemInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const MDRawSystemInfo* sysinfo = range.GetData(0); - if (!sysinfo) { - fprintf(stderr, "Failed to access MD_SYSTEM_INFO_STREAM\n"); - _exit(1); - } -#if defined(__i386__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_X86) { - fprintf(stderr, - "This version of minidump-2-core only supports x86 (32bit)%s.\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64 ? - ",\nbut the minidump file is from a 64bit machine" : ""); - _exit(1); - } -#elif defined(__x86_64__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_AMD64) { - fprintf(stderr, - "This version of minidump-2-core only supports x86 (64bit)%s.\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 ? - ",\nbut the minidump file is from a 32bit machine" : ""); - _exit(1); - } -#elif defined(__arm__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM) { - fprintf(stderr, - "This version of minidump-2-core only supports ARM (32bit).\n"); - _exit(1); - } -#elif defined(__aarch64__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM64) { - fprintf(stderr, - "This version of minidump-2-core only supports ARM (64bit).\n"); - _exit(1); - } -#elif defined(__mips__) -# if _MIPS_SIM == _ABIO32 - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS) { - fprintf(stderr, - "This version of minidump-2-core only supports mips o32 (32bit).\n"); - _exit(1); - } -# elif _MIPS_SIM == _ABI64 - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS64) { - fprintf(stderr, - "This version of minidump-2-core only supports mips n64 (64bit).\n"); - _exit(1); - } -# else -# error "This mips ABI is currently not supported (n32)" -# endif -#else -#error "This code has not been ported to your platform yet" -#endif - if (!strstr(full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str(), - "Linux") && - sysinfo->platform_id != MD_OS_NACL) { - fprintf(stderr, "This minidump was not generated by Linux or NaCl.\n"); - _exit(1); - } - - if (verbose) { - fprintf(stderr, - "MD_SYSTEM_INFO_STREAM:\n" - "Architecture: %s\n" - "Number of processors: %d\n" - "Processor level: %d\n" - "Processor model: %d\n" - "Processor stepping: %d\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 - ? "i386" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64 - ? "x86-64" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_ARM - ? "ARM" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS - ? "MIPS" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS64 - ? "MIPS64" - : "???", - sysinfo->number_of_processors, - sysinfo->processor_level, - sysinfo->processor_revision >> 8, - sysinfo->processor_revision & 0xFF); - if (sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 || - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64) { - fputs("Vendor id: ", stderr); - const char *nul = - (const char *)memchr(sysinfo->cpu.x86_cpu_info.vendor_id, 0, - sizeof(sysinfo->cpu.x86_cpu_info.vendor_id)); - fwrite(sysinfo->cpu.x86_cpu_info.vendor_id, - nul ? nul - (const char *)&sysinfo->cpu.x86_cpu_info.vendor_id[0] - : sizeof(sysinfo->cpu.x86_cpu_info.vendor_id), 1, stderr); - fputs("\n", stderr); - } - fprintf(stderr, "OS: %s\n", - full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str()); - fputs("\n\n", stderr); - } -} - -static void -ParseCPUInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_CPU_INFO:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n\n", stderr); - } -} - -static void -ParseProcessStatus(CrashedProcess* crashinfo, - const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_PROC_STATUS:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n", stderr); - } -} - -static void -ParseLSBRelease(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_LSB_RELEASE:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n", stderr); - } -} - -static void -ParseMaps(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_MAPS:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - } - for (const uint8_t* ptr = range.data(); - ptr < range.data() + range.length();) { - const uint8_t* eol = (uint8_t*)memchr(ptr, '\n', - range.data() + range.length() - ptr); - string line((const char*)ptr, - eol ? eol - ptr : range.data() + range.length() - ptr); - ptr = eol ? eol + 1 : range.data() + range.length(); - unsigned long long start, stop, offset; - char* permissions = NULL; - char* filename = NULL; - sscanf(line.c_str(), "%llx-%llx %m[-rwxp] %llx %*[:0-9a-f] %*d %ms", - &start, &stop, &permissions, &offset, &filename); - if (filename && *filename == '/') { - CrashedProcess::Mapping mapping; - mapping.permissions = 0; - if (strchr(permissions, 'r')) { - mapping.permissions |= PF_R; - } - if (strchr(permissions, 'w')) { - mapping.permissions |= PF_W; - } - if (strchr(permissions, 'x')) { - mapping.permissions |= PF_X; - } - mapping.start_address = start; - mapping.end_address = stop; - mapping.offset = offset; - if (filename) { - mapping.filename = filename; - } - crashinfo->mappings[mapping.start_address] = mapping; - } - free(permissions); - free(filename); - } - if (verbose) { - fputs("\n\n\n", stderr); - } -} - -static void -ParseEnvironment(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_ENVIRON:\n", stderr); - char* env = new char[range.length()]; - memcpy(env, range.data(), range.length()); - int nul_count = 0; - for (char *ptr = env;;) { - ptr = (char *)memchr(ptr, '\000', range.length() - (ptr - env)); - if (!ptr) { - break; - } - if (ptr > env && ptr[-1] == '\n') { - if (++nul_count > 5) { - // Some versions of Chrome try to rewrite the process' command line - // in a way that causes the environment to be corrupted. Afterwards, - // part of the environment will contain the trailing bit of the - // command line. The rest of the environment will be filled with - // NUL bytes. - // We detect this corruption by counting the number of consecutive - // NUL bytes. Normally, we would not expect any consecutive NUL - // bytes. But we are conservative and only suppress printing of - // the environment if we see at least five consecutive NULs. - fputs("Environment has been corrupted; no data available", stderr); - goto env_corrupted; - } - } else { - nul_count = 0; - } - *ptr = '\n'; - } - fwrite(env, range.length(), 1, stderr); - env_corrupted: - delete[] env; - fputs("\n\n\n", stderr); - } -} - -static void -ParseAuxVector(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - // Some versions of Chrome erroneously used the MD_LINUX_AUXV stream value - // when dumping /proc/$x/maps - if (range.length() > 17) { - // The AUXV vector contains binary data, whereas the maps always begin - // with an 8+ digit hex address followed by a hyphen and another 8+ digit - // address. - char addresses[18]; - memcpy(addresses, range.data(), 17); - addresses[17] = '\000'; - if (strspn(addresses, "0123456789abcdef-") == 17) { - ParseMaps(crashinfo, range); - return; - } - } - - crashinfo->auxv = range.data(); - crashinfo->auxv_length = range.length(); -} - -static void -ParseCmdLine(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - // The command line is supposed to use NUL bytes to separate arguments. - // As Chrome rewrites its own command line and (incorrectly) substitutes - // spaces, this is often not the case in our minidump files. - const char* cmdline = (const char*) range.data(); - if (verbose) { - fputs("MD_LINUX_CMD_LINE:\n", stderr); - unsigned i = 0; - for (; i < range.length() && cmdline[i] && cmdline[i] != ' '; ++i) { } - fputs("argv[0] = \"", stderr); - fwrite(cmdline, i, 1, stderr); - fputs("\"\n", stderr); - for (unsigned j = ++i, argc = 1; j < range.length(); ++j) { - if (!cmdline[j] || cmdline[j] == ' ') { - fprintf(stderr, "argv[%d] = \"", argc++); - fwrite(cmdline + i, j - i, 1, stderr); - fputs("\"\n", stderr); - i = j + 1; - } - } - fputs("\n\n", stderr); - } - - const char *binary_name = cmdline; - for (size_t i = 0; i < range.length(); ++i) { - if (cmdline[i] == '/') { - binary_name = cmdline + i + 1; - } else if (cmdline[i] == 0 || cmdline[i] == ' ') { - static const size_t fname_len = sizeof(crashinfo->prps.pr_fname) - 1; - static const size_t args_len = sizeof(crashinfo->prps.pr_psargs) - 1; - memset(crashinfo->prps.pr_fname, 0, fname_len + 1); - memset(crashinfo->prps.pr_psargs, 0, args_len + 1); - unsigned len = cmdline + i - binary_name; - memcpy(crashinfo->prps.pr_fname, binary_name, - len > fname_len ? fname_len : len); - - len = range.length() > args_len ? args_len : range.length(); - memcpy(crashinfo->prps.pr_psargs, cmdline, len); - for (unsigned j = 0; j < len; ++j) { - if (crashinfo->prps.pr_psargs[j] == 0) - crashinfo->prps.pr_psargs[j] = ' '; - } - break; - } - } -} - -static void -ParseDSODebugInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const MDRawDebug* debug = range.GetData(0); - if (!debug) { - return; - } - if (verbose) { - fprintf(stderr, - "MD_LINUX_DSO_DEBUG:\n" - "Version: %d\n" - "Number of DSOs: %d\n" - "Brk handler: 0x%" PRIx64 "\n" - "Dynamic loader at: 0x%" PRIx64 "\n" - "_DYNAMIC: 0x%" PRIx64 "\n", - debug->version, - debug->dso_count, - static_cast(debug->brk), - static_cast(debug->ldbase), - static_cast(debug->dynamic)); - } - crashinfo->debug = *debug; - if (range.length() > sizeof(MDRawDebug)) { - char* dynamic_data = (char*)range.data() + sizeof(MDRawDebug); - crashinfo->dynamic_data.assign(dynamic_data, - range.length() - sizeof(MDRawDebug)); - } - if (debug->map != kInvalidMDRVA) { - for (unsigned int i = 0; i < debug->dso_count; ++i) { - const MDRawLinkMap* link_map = - full_file.GetArrayElement(debug->map, i); - if (link_map) { - if (verbose) { - fprintf(stderr, - "#%03d: %" PRIx64 ", %" PRIx64 ", \"%s\"\n", - i, static_cast(link_map->addr), - static_cast(link_map->ld), - full_file.GetAsciiMDString(link_map->name).c_str()); - } - crashinfo->link_map.push_back(*link_map); - } - } - } - if (verbose) { - fputs("\n\n", stderr); - } -} - -static void -ParseExceptionStream(CrashedProcess* crashinfo, - const MinidumpMemoryRange& range) { - const MDRawExceptionStream* exp = range.GetData(0); - crashinfo->crashing_tid = exp->thread_id; - crashinfo->fatal_signal = (int) exp->exception_record.exception_code; -} - -static bool -WriteThread(const CrashedProcess::Thread& thread, int fatal_signal) { - struct prstatus pr; - memset(&pr, 0, sizeof(pr)); - - pr.pr_info.si_signo = fatal_signal; - pr.pr_cursig = fatal_signal; - pr.pr_pid = thread.tid; -#if defined(__mips__) - memcpy(&pr.pr_reg, &thread.mcontext.gregs, sizeof(user_regs_struct)); -#else - memcpy(&pr.pr_reg, &thread.regs, sizeof(user_regs_struct)); -#endif - - Nhdr nhdr; - memset(&nhdr, 0, sizeof(nhdr)); - nhdr.n_namesz = 5; - nhdr.n_descsz = sizeof(struct prstatus); - nhdr.n_type = NT_PRSTATUS; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &pr, sizeof(struct prstatus))) { - return false; - } - -#if defined(__i386__) || defined(__x86_64__) - nhdr.n_descsz = sizeof(user_fpregs_struct); - nhdr.n_type = NT_FPREGSET; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &thread.fpregs, sizeof(user_fpregs_struct))) { - return false; - } -#endif - -#if defined(__i386__) - nhdr.n_descsz = sizeof(user_fpxregs_struct); - nhdr.n_type = NT_PRXFPREG; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "LINUX\0\0\0", 8) || - !writea(1, &thread.fpxregs, sizeof(user_fpxregs_struct))) { - return false; - } -#endif - - return true; -} - -static void -ParseModuleStream(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - if (verbose) { - fputs("MD_MODULE_LIST_STREAM:\n", stderr); - } - const uint32_t num_mappings = *range.GetData(0); - for (unsigned i = 0; i < num_mappings; ++i) { - CrashedProcess::Mapping mapping; - const MDRawModule* rawmodule = reinterpret_cast( - range.GetArrayElement(sizeof(uint32_t), MD_MODULE_SIZE, i)); - mapping.start_address = rawmodule->base_of_image; - mapping.end_address = rawmodule->size_of_image + rawmodule->base_of_image; - - if (crashinfo->mappings.find(mapping.start_address) == - crashinfo->mappings.end()) { - // We prefer data from MD_LINUX_MAPS over MD_MODULE_LIST_STREAM, as - // the former is a strict superset of the latter. - crashinfo->mappings[mapping.start_address] = mapping; - } - - const MDCVInfoPDB70* record = reinterpret_cast( - full_file.GetData(rawmodule->cv_record.rva, MDCVInfoPDB70_minsize)); - char guid[40]; - sprintf(guid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - record->signature.data1, record->signature.data2, - record->signature.data3, - record->signature.data4[0], record->signature.data4[1], - record->signature.data4[2], record->signature.data4[3], - record->signature.data4[4], record->signature.data4[5], - record->signature.data4[6], record->signature.data4[7]); - string filename = - full_file.GetAsciiMDString(rawmodule->module_name_rva); - size_t slash = filename.find_last_of('/'); - string basename = slash == string::npos ? - filename : filename.substr(slash + 1); - if (strcmp(guid, "00000000-0000-0000-0000-000000000000")) { - string prefix; - if (!g_custom_so_basedir.empty()) - prefix = g_custom_so_basedir; - else - prefix = string("/var/lib/breakpad/") + guid + "-" + basename; - - crashinfo->signatures[rawmodule->base_of_image] = prefix + basename; - } - - if (verbose) { - fprintf(stderr, "0x%08llX-0x%08llX, ChkSum: 0x%08X, GUID: %s, \"%s\"\n", - (unsigned long long)rawmodule->base_of_image, - (unsigned long long)rawmodule->base_of_image + - rawmodule->size_of_image, - rawmodule->checksum, guid, filename.c_str()); - } - } - if (verbose) { - fputs("\n\n", stderr); - } -} - -static void -AddDataToMapping(CrashedProcess* crashinfo, const string& data, - uintptr_t addr) { - for (std::map::iterator - iter = crashinfo->mappings.begin(); - iter != crashinfo->mappings.end(); - ++iter) { - if (addr >= iter->second.start_address && - addr < iter->second.end_address) { - CrashedProcess::Mapping mapping = iter->second; - if ((addr & ~4095) != iter->second.start_address) { - // If there are memory pages in the mapping prior to where the - // data starts, truncate the existing mapping so that it ends with - // the page immediately preceding the data region. - iter->second.end_address = addr & ~4095; - if (!mapping.filename.empty()) { - // "mapping" is a copy of "iter->second". We are splitting the - // existing mapping into two separate ones when we write the data - // to the core file. The first one does not have any associated - // data in the core file, the second one is backed by data that is - // included with the core file. - // If this mapping wasn't supposed to be anonymous, then we also - // have to update the file offset upon splitting the mapping. - mapping.offset += iter->second.end_address - - iter->second.start_address; - } - } - // Create a new mapping that contains the data contents. We often - // limit the amount of data that is actually written to the core - // file. But it is OK if the mapping itself extends past the end of - // the data. - mapping.start_address = addr & ~4095; - mapping.data.assign(addr & 4095, 0).append(data); - mapping.data.append(-mapping.data.size() & 4095, 0); - crashinfo->mappings[mapping.start_address] = mapping; - return; - } - } - // Didn't find a suitable existing mapping for the data. Create a new one. - CrashedProcess::Mapping mapping; - mapping.permissions = PF_R | PF_W; - mapping.start_address = addr & ~4095; - mapping.end_address = - (addr + data.size() + 4095) & ~4095; - mapping.data.assign(addr & 4095, 0).append(data); - mapping.data.append(-mapping.data.size() & 4095, 0); - crashinfo->mappings[mapping.start_address] = mapping; -} - -static void -AugmentMappings(CrashedProcess* crashinfo, - const MinidumpMemoryRange& full_file) { - // For each thread, find the memory mapping that matches the thread's stack. - // Then adjust the mapping to include the stack dump. - for (unsigned i = 0; i < crashinfo->threads.size(); ++i) { - const CrashedProcess::Thread& thread = crashinfo->threads[i]; - AddDataToMapping(crashinfo, - string((char *)thread.stack, thread.stack_length), - thread.stack_addr); - } - - // Create a new link map with information about DSOs. We move this map to - // the beginning of the address space, as this area should always be - // available. - static const uintptr_t start_addr = 4096; - string data; - struct r_debug debug = { 0 }; - debug.r_version = crashinfo->debug.version; - debug.r_brk = (ElfW(Addr))crashinfo->debug.brk; - debug.r_state = r_debug::RT_CONSISTENT; - debug.r_ldbase = (ElfW(Addr))crashinfo->debug.ldbase; - debug.r_map = crashinfo->debug.dso_count > 0 ? - (struct link_map*)(start_addr + sizeof(debug)) : 0; - data.append((char*)&debug, sizeof(debug)); - - struct link_map* prev = 0; - for (std::vector::iterator iter = crashinfo->link_map.begin(); - iter != crashinfo->link_map.end(); - ++iter) { - struct link_map link_map = { 0 }; - link_map.l_addr = (ElfW(Addr))iter->addr; - link_map.l_name = (char*)(start_addr + data.size() + sizeof(link_map)); - link_map.l_ld = (ElfW(Dyn)*)iter->ld; - link_map.l_prev = prev; - prev = (struct link_map*)(start_addr + data.size()); - string filename = full_file.GetAsciiMDString(iter->name); - - // Look up signature for this filename. If available, change filename - // to point to GUID, instead. - std::map::const_iterator guid = - crashinfo->signatures.find((uintptr_t)iter->addr); - if (guid != crashinfo->signatures.end()) { - filename = guid->second; - } - - if (std::distance(iter, crashinfo->link_map.end()) == 1) { - link_map.l_next = 0; - } else { - link_map.l_next = (struct link_map*)(start_addr + data.size() + - sizeof(link_map) + - ((filename.size() + 8) & ~7)); - } - data.append((char*)&link_map, sizeof(link_map)); - data.append(filename); - data.append(8 - (filename.size() & 7), 0); - } - AddDataToMapping(crashinfo, data, start_addr); - - // Map the page containing the _DYNAMIC array - if (!crashinfo->dynamic_data.empty()) { - // Make _DYNAMIC DT_DEBUG entry point to our link map - for (int i = 0;; ++i) { - ElfW(Dyn) dyn; - if ((i+1)*sizeof(dyn) > crashinfo->dynamic_data.length()) { - no_dt_debug: - if (verbose) { - fprintf(stderr, "No DT_DEBUG entry found\n"); - } - return; - } - memcpy(&dyn, crashinfo->dynamic_data.c_str() + i*sizeof(dyn), - sizeof(dyn)); - if (dyn.d_tag == DT_DEBUG) { - crashinfo->dynamic_data.replace(i*sizeof(dyn) + - offsetof(ElfW(Dyn), d_un.d_ptr), - sizeof(start_addr), - (char*)&start_addr, sizeof(start_addr)); - break; - } else if (dyn.d_tag == DT_NULL) { - goto no_dt_debug; - } - } - AddDataToMapping(crashinfo, crashinfo->dynamic_data, - (uintptr_t)crashinfo->debug.dynamic); - } -} - -int -main(int argc, char** argv) { - int argi = 1; - while (argi < argc && argv[argi][0] == '-') { - if (!strcmp(argv[argi], "-v")) { - verbose = true; - } else if (!strcmp(argv[argi], "--sobasedir")) { - argi++; - if (argi >= argc) { - fprintf(stderr, "--sobasedir expects an argument."); - return usage(argv[0]); - } - - g_custom_so_basedir = argv[argi]; - } else { - return usage(argv[0]); - } - argi++; - } - - if (argc != argi + 1) - return usage(argv[0]); - - MemoryMappedFile mapped_file(argv[argi], 0); - if (!mapped_file.data()) { - fprintf(stderr, "Failed to mmap dump file\n"); - return 1; - } - - MinidumpMemoryRange dump(mapped_file.data(), mapped_file.size()); - - const MDRawHeader* header = dump.GetData(0); - - CrashedProcess crashinfo; - - // Always check the system info first, as that allows us to tell whether - // this is a minidump file that is compatible with our converter. - bool ok = false; - for (unsigned i = 0; i < header->stream_count; ++i) { - const MDRawDirectory* dirent = - dump.GetArrayElement(header->stream_directory_rva, i); - switch (dirent->stream_type) { - case MD_SYSTEM_INFO_STREAM: - ParseSystemInfo(&crashinfo, dump.Subrange(dirent->location), dump); - ok = true; - break; - default: - break; - } - } - if (!ok) { - fprintf(stderr, "Cannot determine input file format.\n"); - _exit(1); - } - - for (unsigned i = 0; i < header->stream_count; ++i) { - const MDRawDirectory* dirent = - dump.GetArrayElement(header->stream_directory_rva, i); - switch (dirent->stream_type) { - case MD_THREAD_LIST_STREAM: - ParseThreadList(&crashinfo, dump.Subrange(dirent->location), dump); - break; - case MD_LINUX_CPU_INFO: - ParseCPUInfo(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_PROC_STATUS: - ParseProcessStatus(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_LSB_RELEASE: - ParseLSBRelease(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_ENVIRON: - ParseEnvironment(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_MAPS: - ParseMaps(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_AUXV: - ParseAuxVector(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_CMD_LINE: - ParseCmdLine(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_DSO_DEBUG: - ParseDSODebugInfo(&crashinfo, dump.Subrange(dirent->location), dump); - break; - case MD_EXCEPTION_STREAM: - ParseExceptionStream(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_MODULE_LIST_STREAM: - ParseModuleStream(&crashinfo, dump.Subrange(dirent->location), dump); - break; - default: - if (verbose) - fprintf(stderr, "Skipping %x\n", dirent->stream_type); - } - } - - AugmentMappings(&crashinfo, dump); - - // Write the ELF header. The file will look like: - // ELF header - // Phdr for the PT_NOTE - // Phdr for each of the thread stacks - // PT_NOTE - // each of the thread stacks - Ehdr ehdr; - memset(&ehdr, 0, sizeof(Ehdr)); - ehdr.e_ident[0] = ELFMAG0; - ehdr.e_ident[1] = ELFMAG1; - ehdr.e_ident[2] = ELFMAG2; - ehdr.e_ident[3] = ELFMAG3; - ehdr.e_ident[4] = ELF_CLASS; - ehdr.e_ident[5] = sex() ? ELFDATA2MSB : ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; - ehdr.e_type = ET_CORE; - ehdr.e_machine = ELF_ARCH; - ehdr.e_version = EV_CURRENT; - ehdr.e_phoff = sizeof(Ehdr); - ehdr.e_ehsize = sizeof(Ehdr); - ehdr.e_phentsize= sizeof(Phdr); - ehdr.e_phnum = 1 + // PT_NOTE - crashinfo.mappings.size(); // memory mappings - ehdr.e_shentsize= sizeof(Shdr); - if (!writea(1, &ehdr, sizeof(Ehdr))) - return 1; - - size_t offset = sizeof(Ehdr) + ehdr.e_phnum * sizeof(Phdr); - size_t filesz = sizeof(Nhdr) + 8 + sizeof(prpsinfo) + - // sizeof(Nhdr) + 8 + sizeof(user) + - sizeof(Nhdr) + 8 + crashinfo.auxv_length + - crashinfo.threads.size() * ( - (sizeof(Nhdr) + 8 + sizeof(prstatus)) -#if defined(__i386__) || defined(__x86_64__) - + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) -#endif -#if defined(__i386__) - + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct) -#endif - ); - - Phdr phdr; - memset(&phdr, 0, sizeof(Phdr)); - phdr.p_type = PT_NOTE; - phdr.p_offset = offset; - phdr.p_filesz = filesz; - if (!writea(1, &phdr, sizeof(phdr))) - return 1; - - phdr.p_type = PT_LOAD; - phdr.p_align = 4096; - size_t note_align = phdr.p_align - ((offset+filesz) % phdr.p_align); - if (note_align == phdr.p_align) - note_align = 0; - offset += note_align; - - for (std::map::const_iterator iter = - crashinfo.mappings.begin(); - iter != crashinfo.mappings.end(); ++iter) { - const CrashedProcess::Mapping& mapping = iter->second; - if (mapping.permissions == 0xFFFFFFFF) { - // This is a map that we found in MD_MODULE_LIST_STREAM (as opposed to - // MD_LINUX_MAPS). It lacks some of the information that we would like - // to include. - phdr.p_flags = PF_R; - } else { - phdr.p_flags = mapping.permissions; - } - phdr.p_vaddr = mapping.start_address; - phdr.p_memsz = mapping.end_address - mapping.start_address; - if (mapping.data.size()) { - offset += filesz; - filesz = mapping.data.size(); - phdr.p_filesz = mapping.data.size(); - phdr.p_offset = offset; - } else { - phdr.p_filesz = 0; - phdr.p_offset = 0; - } - if (!writea(1, &phdr, sizeof(phdr))) - return 1; - } - - Nhdr nhdr; - memset(&nhdr, 0, sizeof(nhdr)); - nhdr.n_namesz = 5; - nhdr.n_descsz = sizeof(prpsinfo); - nhdr.n_type = NT_PRPSINFO; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &crashinfo.prps, sizeof(prpsinfo))) { - return 1; - } - - nhdr.n_descsz = crashinfo.auxv_length; - nhdr.n_type = NT_AUXV; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, crashinfo.auxv, crashinfo.auxv_length)) { - return 1; - } - - for (unsigned i = 0; i < crashinfo.threads.size(); ++i) { - if (crashinfo.threads[i].tid == crashinfo.crashing_tid) { - WriteThread(crashinfo.threads[i], crashinfo.fatal_signal); - break; - } - } - - for (unsigned i = 0; i < crashinfo.threads.size(); ++i) { - if (crashinfo.threads[i].tid != crashinfo.crashing_tid) - WriteThread(crashinfo.threads[i], 0); - } - - if (note_align) { - google_breakpad::scoped_array scratch(new char[note_align]); - memset(scratch.get(), 0, note_align); - if (!writea(1, scratch.get(), note_align)) - return 1; - } - - for (std::map::const_iterator iter = - crashinfo.mappings.begin(); - iter != crashinfo.mappings.end(); ++iter) { - const CrashedProcess::Mapping& mapping = iter->second; - if (mapping.data.size()) { - if (!writea(1, mapping.data.c_str(), mapping.data.size())) - return 1; - } - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h deleted file mode 100644 index a793e2cfb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_memory_range.h: Define the google_breakpad::MinidumpMemoryRange -// class, which adds methods for handling minidump specific data structures -// on top of google_breakpad::MemoryRange. See common/memory_range.h for -// more details on MemoryRange. - -#ifndef TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ -#define TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ - -#include - -#include "common/memory_range.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// A derived class of MemoryRange with added methods for handling minidump -// specific data structures. To avoid virtual functions, it is not designed -// to be used polymorphically. -class MinidumpMemoryRange : public MemoryRange { - public: - MinidumpMemoryRange() {} - - MinidumpMemoryRange(const void* data, size_t length) - : MemoryRange(data, length) {} - - // Returns a subrange of |length| bytes at |offset| bytes of this memory - // range, or an empty range if the subrange is out of bounds. - // This methods overrides the base implemementation in order to return - // an instance of MinidumpMemoryRange instead of MemoryRange. - MinidumpMemoryRange Subrange(size_t sub_offset, size_t sub_length) const { - if (Covers(sub_offset, sub_length)) - return MinidumpMemoryRange(data() + sub_offset, sub_length); - return MinidumpMemoryRange(); - } - - // Returns a subrange that covers the offset and length specified by - // |location|, or an empty range if the subrange is out of bounds. - MinidumpMemoryRange Subrange(const MDLocationDescriptor& location) const { - return MinidumpMemoryRange::Subrange(location.rva, location.data_size); - } - - // Gets a STL string from a MDString at |sub_offset| bytes of this memory - // range. This method only works correctly for ASCII characters and does - // not convert between UTF-16 and UTF-8. - const std::string GetAsciiMDString(size_t sub_offset) const { - std::string str; - const MDString* md_str = GetData(sub_offset); - if (md_str) { - const uint16_t* buffer = &md_str->buffer[0]; - for (uint32_t i = 0; i < md_str->length && buffer[i]; ++i) { - str.push_back(buffer[i]); - } - } - return str; - } -}; - -} // namespace google_breakpad - -#endif // TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc deleted file mode 100644 index fe4ded83d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_memory_range_unittest.cc: -// Unit tests for google_breakpad::MinidumpMemoryRange. - -#include "breakpad_googletest_includes.h" -#include "tools/linux/md2core/minidump_memory_range.h" - -using google_breakpad::MinidumpMemoryRange; -using testing::Message; - -namespace { - -const uint32_t kBuffer[10] = { 0 }; -const size_t kBufferSize = sizeof(kBuffer); -const uint8_t* kBufferPointer = reinterpret_cast(kBuffer); - -// Test vectors for verifying Covers, GetData, and Subrange. -const struct { - bool valid; - size_t offset; - size_t length; -} kSubranges[] = { - { true, 0, 0 }, - { true, 0, 2 }, - { true, 0, kBufferSize }, - { true, 2, 0 }, - { true, 2, 4 }, - { true, 2, kBufferSize - 2 }, - { true, kBufferSize - 1, 1 }, - { false, kBufferSize, 0 }, - { false, kBufferSize, static_cast(-1) }, - { false, kBufferSize + 1, 0 }, - { false, static_cast(-1), 2 }, - { false, 1, kBufferSize }, - { false, kBufferSize - 1, 2 }, - { false, 0, static_cast(-1) }, - { false, 1, static_cast(-1) }, -}; -const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]); - -// Test vectors for verifying GetArrayElement. -const struct { - size_t offset; - size_t size; - size_t index; - const void* const pointer; -} kElements[] = { - // Valid array elemenets - { 0, 1, 0, kBufferPointer }, - { 0, 1, 1, kBufferPointer + 1 }, - { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 }, - { 0, 2, 1, kBufferPointer + 2 }, - { 0, 4, 2, kBufferPointer + 8 }, - { 0, 4, 9, kBufferPointer + 36 }, - { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, - // Invalid array elemenets - { 0, 1, kBufferSize, NULL }, - { 0, 4, 10, NULL }, - { kBufferSize - 1, 1, 1, NULL }, - { kBufferSize - 1, 2, 0, NULL }, - { kBufferSize, 1, 0, NULL }, -}; -const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); - -} // namespace - -TEST(MinidumpMemoryRangeTest, DefaultConstructor) { - MinidumpMemoryRange range; - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, ConstructorWithDataAndLength) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); -} - -TEST(MinidumpMemoryRangeTest, Reset) { - MinidumpMemoryRange range; - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); - - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, Set) { - MinidumpMemoryRange range; - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Set(NULL, 0); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, SubrangeOfEmptyMemoryRange) { - MinidumpMemoryRange range; - MinidumpMemoryRange subrange = range.Subrange(0, 10); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); -} - -TEST(MinidumpMemoryRangeTest, SubrangeAndGetData) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumSubranges; ++i) { - bool valid = kSubranges[i].valid; - size_t sub_offset = kSubranges[i].offset; - size_t sub_length = kSubranges[i].length; - SCOPED_TRACE(Message() << "offset=" << sub_offset - << ", length=" << sub_length); - - MinidumpMemoryRange subrange = range.Subrange(sub_offset, sub_length); - if (valid) { - EXPECT_TRUE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, - range.GetData(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); - EXPECT_EQ(sub_length, subrange.length()); - } else { - EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); - } - } -} - -TEST(MinidumpMemoryRangeTest, SubrangeWithMDLocationDescriptor) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumSubranges; ++i) { - bool valid = kSubranges[i].valid; - size_t sub_offset = kSubranges[i].offset; - size_t sub_length = kSubranges[i].length; - SCOPED_TRACE(Message() << "offset=" << sub_offset - << ", length=" << sub_length); - - MDLocationDescriptor location; - location.rva = sub_offset; - location.data_size = sub_length; - MinidumpMemoryRange subrange = range.Subrange(location); - if (valid) { - EXPECT_TRUE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, - range.GetData(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); - EXPECT_EQ(sub_length, subrange.length()); - } else { - EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); - } - } -} - -TEST(MinidumpMemoryRangeTest, GetDataWithTemplateType) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetData(0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); - const int* int_pointer = range.GetData(0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); -} - -TEST(MinidumpMemoryRangeTest, GetArrayElement) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumElements; ++i) { - size_t element_offset = kElements[i].offset; - size_t element_size = kElements[i].size; - unsigned element_index = kElements[i].index; - const void* const element_pointer = kElements[i].pointer; - SCOPED_TRACE(Message() << "offset=" << element_offset - << ", size=" << element_size - << ", index=" << element_index); - EXPECT_EQ(element_pointer, range.GetArrayElement( - element_offset, element_size, element_index)); - } -} - -TEST(MinidumpMemoryRangeTest, GetArrayElmentWithTemplateType) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetArrayElement(0, 0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); - const int* int_pointer = range.GetArrayElement(0, 0); - EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); -} - -TEST(MinidumpMemoryRangeTest, GetAsciiMDString) { - uint8_t buffer[100] = { 0 }; - - MDString* md_str = reinterpret_cast(buffer); - md_str->length = 4; - md_str->buffer[0] = 'T'; - md_str->buffer[1] = 'e'; - md_str->buffer[2] = 's'; - md_str->buffer[3] = 't'; - md_str->buffer[4] = '\0'; - - size_t str2_offset = - sizeof(MDString) + (md_str->length + 1) * sizeof(uint16_t); - - md_str = reinterpret_cast(buffer + str2_offset); - md_str->length = 9; // Test length larger than actual string - md_str->buffer[0] = 'S'; - md_str->buffer[1] = 't'; - md_str->buffer[2] = 'r'; - md_str->buffer[3] = 'i'; - md_str->buffer[4] = 'n'; - md_str->buffer[5] = 'g'; - md_str->buffer[6] = '\0'; - md_str->buffer[7] = '1'; - md_str->buffer[8] = '2'; - - MinidumpMemoryRange range(buffer, sizeof(buffer)); - EXPECT_EQ("Test", range.GetAsciiMDString(0)); - EXPECT_EQ("String", range.GetAsciiMDString(str2_offset)); - - // Test out-of-bounds cases. - EXPECT_EQ("", range.GetAsciiMDString( - sizeof(buffer) - sizeof(MDString) + 1)); - EXPECT_EQ("", range.GetAsciiMDString(sizeof(buffer))); -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc deleted file mode 100644 index 19f17450a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_upload.cc: Upload a minidump to a HTTP server. -// The upload is sent as a multipart/form-data POST request with -// the following parameters: -// prod: the product name -// ver: the product version -// symbol_file: the breakpad format symbol file - -#include -#include -#include - -#include - -#include "common/linux/http_upload.h" -#include "common/using_std_string.h" - -using google_breakpad::HTTPUpload; - -struct Options { - string minidumpPath; - string uploadURLStr; - string product; - string version; - string proxy; - string proxy_user_pwd; - bool success; -}; - -//============================================================================= -static void Start(Options *options) { - std::map parameters; - // Add parameters - parameters["prod"] = options->product; - parameters["ver"] = options->version; - - std::map files; - files["upload_file_minidump"] = options->minidumpPath; - - // Send it - string response, error; - bool success = HTTPUpload::SendRequest(options->uploadURLStr, - parameters, - files, - options->proxy, - options->proxy_user_pwd, - "", - &response, - NULL, - &error); - - if (success) { - printf("Successfully sent the minidump file.\n"); - } else { - printf("Failed to send minidump: %s\n", error.c_str()); - } - printf("Response:\n"); - printf("%s\n", response.c_str()); - options->success = success; -} - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit minidump information.\n"); - fprintf(stderr, "Usage: %s [options...] -p -v " - "\n", argv[0]); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " should be a minidump.\n"); - fprintf(stderr, " is the destination for the upload\n"); - - fprintf(stderr, "-p:\t Product name\n"); - fprintf(stderr, "-v:\t Product version\n"); - fprintf(stderr, "-x:\t Use HTTP proxy on given port\n"); - fprintf(stderr, "-u:\t Set proxy user and password\n"); - fprintf(stderr, "-h:\t Usage\n"); - fprintf(stderr, "-?:\t Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - int ch; - - while ((ch = getopt(argc, (char * const *)argv, "p:u:v:x:h?")) != -1) { - switch (ch) { - case 'p': - options->product = optarg; - break; - case 'u': - options->proxy_user_pwd = optarg; - break; - case 'v': - options->version = optarg; - break; - case 'x': - options->proxy = optarg; - break; - - default: - fprintf(stderr, "Invalid option '%c'\n", ch); - Usage(argc, argv); - exit(1); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->minidumpPath = argv[optind]; - options->uploadURLStr = argv[optind + 1]; -} - -//============================================================================= -int main(int argc, const char* argv[]) { - Options options; - SetupOptions(argc, argv, &options); - Start(&options); - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc deleted file mode 100644 index 9eeb2d447..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// symupload.cc: Upload a symbol file to a HTTP server. The upload is sent as -// a multipart/form-data POST request with the following parameters: -// code_file: the basename of the module, e.g. "app" -// debug_file: the basename of the debugging file, e.g. "app" -// debug_identifier: the debug file's identifier, usually consisting of -// the guid and age embedded in the pdb, e.g. -// "11111111BBBB3333DDDD555555555555F" -// version: the file version of the module, e.g. "1.2.3.4" -// os: the operating system that the module was built for -// cpu: the CPU that the module was built for -// symbol_file: the contents of the breakpad-format symbol file - -#include -#include -#include - -#include "common/linux/symbol_upload.h" - -using google_breakpad::sym_upload::Options; - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit symbol information.\n"); - fprintf(stderr, "Usage: %s [options...] \n", argv[0]); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " should be created by using the dump_syms tool.\n"); - fprintf(stderr, " is the destination for the upload\n"); - fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n"); - fprintf(stderr, "-x:\t Use HTTP proxy on given port\n"); - fprintf(stderr, "-u:\t Set proxy user and password\n"); - fprintf(stderr, "-h:\t Usage\n"); - fprintf(stderr, "-?:\t Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - int ch; - - while ((ch = getopt(argc, (char * const *)argv, "u:v:x:h?")) != -1) { - switch (ch) { - case 'h': - case '?': - Usage(argc, argv); - exit(0); - break; - case 'u': - options->proxy_user_pwd = optarg; - break; - case 'v': - options->version = optarg; - break; - case 'x': - options->proxy = optarg; - break; - - default: - fprintf(stderr, "Invalid option '%c'\n", ch); - Usage(argc, argv); - exit(1); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->symbolsPath = argv[optind]; - options->uploadURLStr = argv[optind + 1]; -} - -//============================================================================= -int main(int argc, const char* argv[]) { - Options options; - SetupOptions(argc, argv, &options); - google_breakpad::sym_upload::Start(&options); - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi b/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi deleted file mode 100644 index 1c15992e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'target_defaults': { - 'include_dirs': [ - '../..', - ], - }, - 'targets': [ - { - 'target_name': 'dump_syms', - 'type': 'executable', - 'sources': [ - 'dump_syms/dump_syms.cc', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'md2core', - 'type': 'executable', - 'sources': [ - 'md2core/minidump-2-core.cc', - 'md2core/minidump_memory_range.h', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'minidump_upload', - 'type': 'executable', - 'sources': [ - 'symupload/minidump_upload.m', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'symupload', - 'type': 'executable', - 'sources': [ - 'symupload/sym_upload.cc', - ], - 'link_settings': { - 'libraries': [ - '-ldl', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm deleted file mode 100644 index f68200c7c..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.mm +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// crash_report.mm: Convert the contents of a minidump into a format that -// looks more like Apple's CrashReporter format - -#include - -#include -#include - -#include - -#include - -#include "common/scoped_ptr.h" -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/call_stack.h" -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/minidump_processor.h" -#include "google_breakpad/processor/process_state.h" -#include "google_breakpad/processor/stack_frame_cpu.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/pathname_stripper.h" -#include "processor/simple_symbol_supplier.h" - -#include "on_demand_symbol_supplier.h" - -using std::string; - -using google_breakpad::BasicSourceLineResolver; -using google_breakpad::CallStack; -using google_breakpad::CodeModule; -using google_breakpad::CodeModules; -using google_breakpad::Minidump; -using google_breakpad::MinidumpProcessor; -using google_breakpad::OnDemandSymbolSupplier; -using google_breakpad::PathnameStripper; -using google_breakpad::ProcessState; -using google_breakpad::scoped_ptr; -using google_breakpad::StackFrame; -using google_breakpad::StackFramePPC; -using google_breakpad::StackFrameX86; -using google_breakpad::SystemInfo; - -typedef struct { - NSString *minidumpPath; - NSString *searchDir; - NSString *symbolSearchDir; - BOOL printThreadMemory; -} Options; - -//============================================================================= -static int PrintRegister(const char *name, u_int32_t value, int sequence) { - if (sequence % 4 == 0) { - printf("\n"); - } - printf("%6s = 0x%08x ", name, value); - return ++sequence; -} - -//============================================================================= -static void PrintStack(const CallStack *stack, const string &cpu) { - size_t frame_count = stack->frames()->size(); - char buffer[1024]; - for (size_t frame_index = 0; frame_index < frame_count; ++frame_index) { - const StackFrame *frame = stack->frames()->at(frame_index); - const CodeModule *module = frame->module; - printf("%2zu ", frame_index); - - if (module) { - // Module name (20 chars max) - strcpy(buffer, PathnameStripper::File(module->code_file()).c_str()); - int maxStr = 20; - buffer[maxStr] = 0; - printf("%-*s", maxStr, buffer); - - strcpy(buffer, module->version().c_str()); - buffer[maxStr] = 0; - - printf("%-*s",maxStr, buffer); - - u_int64_t instruction = frame->instruction; - - // PPC only: Adjust the instruction to match that of Crash reporter. The - // instruction listed is actually the return address. See the detailed - // comments in stackwalker_ppc.cc for more information. - if (cpu == "ppc" && frame_index) - instruction += 4; - - printf(" 0x%08llx ", instruction); - - // Function name - if (!frame->function_name.empty()) { - printf("%s", frame->function_name.c_str()); - if (!frame->source_file_name.empty()) { - string source_file = PathnameStripper::File(frame->source_file_name); - printf(" + 0x%llx (%s:%d)", - instruction - frame->source_line_base, - source_file.c_str(), frame->source_line); - } else { - printf(" + 0x%llx", instruction - frame->function_base); - } - } - } - printf("\n"); - } -} - -//============================================================================= -static void PrintRegisters(const CallStack *stack, const string &cpu) { - int sequence = 0; - const StackFrame *frame = stack->frames()->at(0); - if (cpu == "x86") { - const StackFrameX86 *frame_x86 = - reinterpret_cast(frame); - - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EIP) - sequence = PrintRegister("eip", frame_x86->context.eip, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP) - sequence = PrintRegister("esp", frame_x86->context.esp, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBP) - sequence = PrintRegister("ebp", frame_x86->context.ebp, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBX) - sequence = PrintRegister("ebx", frame_x86->context.ebx, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESI) - sequence = PrintRegister("esi", frame_x86->context.esi, sequence); - if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EDI) - sequence = PrintRegister("edi", frame_x86->context.edi, sequence); - if (frame_x86->context_validity == StackFrameX86::CONTEXT_VALID_ALL) { - sequence = PrintRegister("eax", frame_x86->context.eax, sequence); - sequence = PrintRegister("ecx", frame_x86->context.ecx, sequence); - sequence = PrintRegister("edx", frame_x86->context.edx, sequence); - sequence = PrintRegister("efl", frame_x86->context.eflags, sequence); - } - } else if (cpu == "ppc") { - const StackFramePPC *frame_ppc = - reinterpret_cast(frame); - - if ((frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_ALL) == - StackFramePPC::CONTEXT_VALID_ALL) { - sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence); - sequence = PrintRegister("srr1", frame_ppc->context.srr1, sequence); - sequence = PrintRegister("cr", frame_ppc->context.cr, sequence); - sequence = PrintRegister("xer", frame_ppc->context.xer, sequence); - sequence = PrintRegister("lr", frame_ppc->context.lr, sequence); - sequence = PrintRegister("ctr", frame_ppc->context.ctr, sequence); - sequence = PrintRegister("mq", frame_ppc->context.mq, sequence); - sequence = PrintRegister("vrsave", frame_ppc->context.vrsave, sequence); - - sequence = 0; - char buffer[5]; - for (int i = 0; i < MD_CONTEXT_PPC_GPR_COUNT; ++i) { - sprintf(buffer, "r%d", i); - sequence = PrintRegister(buffer, frame_ppc->context.gpr[i], sequence); - } - } else { - if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_SRR0) - sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence); - if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_GPR1) - sequence = PrintRegister("r1", frame_ppc->context.gpr[1], sequence); - } - } - - printf("\n"); -} - -static void PrintModules(const CodeModules *modules) { - if (!modules) - return; - - printf("\n"); - printf("Loaded modules:\n"); - - u_int64_t main_address = 0; - const CodeModule *main_module = modules->GetMainModule(); - if (main_module) { - main_address = main_module->base_address(); - } - - unsigned int module_count = modules->module_count(); - for (unsigned int module_sequence = 0; - module_sequence < module_count; - ++module_sequence) { - const CodeModule *module = modules->GetModuleAtSequence(module_sequence); - assert(module); - u_int64_t base_address = module->base_address(); - printf("0x%08llx - 0x%08llx %s %s%s %s\n", - base_address, base_address + module->size() - 1, - PathnameStripper::File(module->code_file()).c_str(), - module->version().empty() ? "???" : module->version().c_str(), - main_module != NULL && base_address == main_address ? - " (main)" : "", - module->code_file().c_str()); - } -} - -static void ProcessSingleReport(Options *options, NSString *file_path) { - string minidump_file([file_path fileSystemRepresentation]); - BasicSourceLineResolver resolver; - string search_dir = options->searchDir ? - [options->searchDir fileSystemRepresentation] : ""; - string symbol_search_dir = options->symbolSearchDir ? - [options->symbolSearchDir fileSystemRepresentation] : ""; - scoped_ptr symbol_supplier( - new OnDemandSymbolSupplier(search_dir, symbol_search_dir)); - scoped_ptr - minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver)); - ProcessState process_state; - scoped_ptr dump(new google_breakpad::Minidump(minidump_file)); - - if (!dump->Read()) { - fprintf(stderr, "Minidump %s could not be read\n", dump->path().c_str()); - return; - } - if (minidump_processor->Process(dump.get(), &process_state) != - google_breakpad::PROCESS_OK) { - fprintf(stderr, "MinidumpProcessor::Process failed\n"); - return; - } - - const SystemInfo *system_info = process_state.system_info(); - string cpu = system_info->cpu; - - // Convert the time to a string - u_int32_t time_date_stamp = process_state.time_date_stamp(); - struct tm timestruct; - gmtime_r(reinterpret_cast(&time_date_stamp), ×truct); - char timestr[20]; - strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); - printf("Date: %s GMT\n", timestr); - - printf("Operating system: %s (%s)\n", system_info->os.c_str(), - system_info->os_version.c_str()); - printf("Architecture: %s\n", cpu.c_str()); - - if (process_state.crashed()) { - printf("Crash reason: %s\n", process_state.crash_reason().c_str()); - printf("Crash address: 0x%llx\n", process_state.crash_address()); - } else { - printf("No crash\n"); - } - - int requesting_thread = process_state.requesting_thread(); - if (requesting_thread != -1) { - printf("\n"); - printf("Thread %d (%s)\n", - requesting_thread, - process_state.crashed() ? "crashed" : - "requested dump, did not crash"); - PrintStack(process_state.threads()->at(requesting_thread), cpu); - } - - // Print all of the threads in the dump. - int thread_count = static_cast(process_state.threads()->size()); - const std::vector - *thread_memory_regions = process_state.thread_memory_regions(); - - for (int thread_index = 0; thread_index < thread_count; ++thread_index) { - if (thread_index != requesting_thread) { - // Don't print the crash thread again, it was already printed. - printf("\n"); - printf("Thread %d\n", thread_index); - PrintStack(process_state.threads()->at(thread_index), cpu); - google_breakpad::MemoryRegion *thread_stack_bytes = - thread_memory_regions->at(thread_index); - if (options->printThreadMemory) { - thread_stack_bytes->Print(); - } - } - } - - // Print the crashed registers - if (requesting_thread != -1) { - printf("\nThread %d:", requesting_thread); - PrintRegisters(process_state.threads()->at(requesting_thread), cpu); - } - - // Print information about modules - PrintModules(process_state.modules()); -} - -//============================================================================= -static void Start(Options *options) { - NSFileManager *manager = [NSFileManager defaultManager]; - NSString *minidump_path = options->minidumpPath; - BOOL is_dir = NO; - BOOL file_exists = [manager fileExistsAtPath:minidump_path - isDirectory:&is_dir]; - if (file_exists && is_dir) { - NSDirectoryEnumerator *enumerator = - [manager enumeratorAtPath:minidump_path]; - NSString *current_file = nil; - while ((current_file = [enumerator nextObject])) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if ([[current_file pathExtension] isEqualTo:@"dmp"]) { - printf("Attempting to process report: %s\n", - [current_file cStringUsingEncoding:NSASCIIStringEncoding]); - NSString *full_path = - [minidump_path stringByAppendingPathComponent:current_file]; - ProcessSingleReport(options, full_path); - } - [pool release]; - } - } else if (file_exists) { - ProcessSingleReport(options, minidump_path); - } -} - -//============================================================================= -static void Usage(int argc, const char *argv[]) { - fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol " - "files will be used (or created if missing) in /tmp.\n" - "If a symbol-file-search-dir is specified, any symbol " - "files in it will be used instead of being loaded from " - "modules on disk.\n" - "If modules cannot be found at the paths stored in the " - "minidump file, they will be searched for at " - "/.\n"); - fprintf(stderr, "Usage: %s [-s module-search-dir] [-S symbol-file-search-dir] " - "minidump-file\n", argv[0]); - fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n" - "\t-S: Specify a search directory to use for symbol files\n" - "\t-t: Print thread stack memory in hex\n" - "\t-h: Usage\n" - "\t-?: Usage\n"); -} - -//============================================================================= -static void SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - char ch; - - while ((ch = getopt(argc, (char * const *)argv, "S:s:ht?")) != -1) { - switch (ch) { - case 's': - options->searchDir = [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:optarg - length:strlen(optarg)]; - break; - - case 'S': - options->symbolSearchDir = [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:optarg - length:strlen(optarg)]; - break; - - case 't': - options->printThreadMemory = YES; - break; - case 'h': - case '?': - Usage(argc, argv); - exit(1); - break; - } - } - - if ((argc - optind) != 1) { - fprintf(stderr, "%s: Missing minidump file\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->minidumpPath = [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:argv[optind] - length:strlen(argv[optind])]; -} - -//============================================================================= -int main (int argc, const char * argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Options options; - - bzero(&options, sizeof(Options)); - SetupOptions(argc, argv, &options); - Start(&options); - [pool release]; - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj deleted file mode 100644 index d32837cbd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj +++ /dev/null @@ -1,587 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXBuildFile section */ - 162F64FE161C5ECB00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */; }; - 4D2C721B126F9ACC00B43EAF /* source_line_resolver_base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */; }; - 4D2C721F126F9ADE00B43EAF /* exploitability.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C721E126F9ADE00B43EAF /* exploitability.cc */; }; - 4D2C7223126F9AF900B43EAF /* exploitability_win.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */; }; - 4D2C7227126F9B0F00B43EAF /* disassembler_x86.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */; }; - 4D2C722B126F9B5A00B43EAF /* x86_disasm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */; }; - 4D2C722D126F9B6E00B43EAF /* x86_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722C126F9B6E00B43EAF /* x86_misc.c */; }; - 4D2C722F126F9B8300B43EAF /* x86_operand_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */; }; - 4D2C7233126F9BB000B43EAF /* ia32_invariant.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; }; - 4D2C7235126F9BC200B43EAF /* ia32_settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7234126F9BC200B43EAF /* ia32_settings.c */; }; - 4D2C7246126F9C0B00B43EAF /* ia32_insn.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */; }; - 4D2C724A126F9C2300B43EAF /* ia32_opcode_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; }; - 4D2C724C126F9C3800B43EAF /* ia32_implicit.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; }; - 4D2C724E126F9C4D00B43EAF /* ia32_reg.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */; settings = {COMPILER_FLAGS = "-Wno-error"; }; }; - 4D2C725B126F9C8000B43EAF /* ia32_operand.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C725A126F9C8000B43EAF /* ia32_operand.c */; }; - 4D2C725D126F9C9200B43EAF /* x86_insn.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C725C126F9C9200B43EAF /* x86_insn.c */; }; - 4D2C7264126F9CBB00B43EAF /* ia32_modrm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */; }; - 4D2C726D126F9CDC00B43EAF /* x86_imm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D2C7263126F9CBB00B43EAF /* x86_imm.c */; }; - 4D72CA5713DFBA84006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CA5613DFBA84006CABE3 /* md5.cc */; }; - 557800400BE1F28500EC23E0 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */; }; - 8B31FF2A11F0C62700FCF3E4 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */; }; - 8B31FF2B11F0C62700FCF3E4 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */; }; - 8B31FF2C11F0C62700FCF3E4 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */; }; - 8B31FF4111F0C64400FCF3E4 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */; }; - 8B31FF4211F0C64400FCF3E4 /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */; }; - 8B31FF7411F0C6E000FCF3E4 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */; }; - 8B31FF8811F0C6FB00FCF3E4 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF8411F0C6FB00FCF3E4 /* language.cc */; }; - 8B31FF8911F0C6FB00FCF3E4 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FF8611F0C6FB00FCF3E4 /* module.cc */; }; - 8B31FFC511F0C8AB00FCF3E4 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */; }; - 8B40BDC00C0638E4009535AF /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8B40BDBF0C0638E4009535AF /* logging.cc */; }; - 8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* crash_report.mm */; settings = {ATTRIBUTES = (); }; }; - 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; - 9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */; }; - 9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */; }; - 9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172A0B1B8B2400F8391B /* call_stack.cc */; }; - 9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */; }; - 9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF173F0B1B8B9A00F8391B /* minidump.cc */; }; - 9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */; }; - 9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */; }; - 9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF17530B1B8BF900F8391B /* stackwalker.cc */; }; - 9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF175B0B1B8C1B00F8391B /* process_state.cc */; }; - 9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */; }; - 9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */; }; - 9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */; }; - 9BE650B20B52FE3000611104 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AC0B52FE3000611104 /* file_id.cc */; }; - 9BE650B40B52FE3000611104 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650AE0B52FE3000611104 /* macho_id.cc */; }; - 9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650B00B52FE3000611104 /* macho_walker.cc */; }; - D2A5DD4D1188651100081F03 /* cfi_frame_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */; }; - D2A5DD631188658B00081F03 /* tokenize.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2A5DD621188658B00081F03 /* tokenize.cc */; }; - F407DC48185773C10064622B /* exploitability_linux.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC40185773C10064622B /* exploitability_linux.cc */; }; - F407DC49185773C10064622B /* stack_frame_symbolizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC41185773C10064622B /* stack_frame_symbolizer.cc */; }; - F407DC4A185773C10064622B /* stackwalker_arm64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC42185773C10064622B /* stackwalker_arm64.cc */; }; - F407DC4B185773C10064622B /* stackwalker_mips.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC44185773C10064622B /* stackwalker_mips.cc */; }; - F407DC4C185773C10064622B /* stackwalker_ppc64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F407DC46185773C10064622B /* stackwalker_ppc64.cc */; }; - F44DDD8719C85CD50047280E /* dump_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8419C85CD50047280E /* dump_context.cc */; }; - F44DDD8819C85CD50047280E /* dump_object.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8519C85CD50047280E /* dump_object.cc */; }; - F44DDD8919C85CD50047280E /* microdump_processor.cc in Sources */ = {isa = PBXBuildFile; fileRef = F44DDD8619C85CD50047280E /* microdump_processor.cc */; }; - F4D43B2F1A38490700C290B2 /* microdump.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4D43B2E1A38490700C290B2 /* microdump.cc */; }; - F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE20E8ABCA600E953AD /* bytereader.cc */; }; - F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */; }; - F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */; }; - F9F0706710FBC02D0037B88B /* stackwalker_arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */; }; - FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */; }; - FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 08FB7796FE84155DC02AAC07 /* crash_report.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = crash_report.mm; sourceTree = ""; }; - 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = ""; }; - 162F64FD161C5ECB00CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = ""; }; - 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = source_line_resolver_base.cc; path = ../../../processor/source_line_resolver_base.cc; sourceTree = SOURCE_ROOT; }; - 4D2C721E126F9ADE00B43EAF /* exploitability.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability.cc; path = ../../../processor/exploitability.cc; sourceTree = SOURCE_ROOT; }; - 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability_win.cc; path = ../../../processor/exploitability_win.cc; sourceTree = SOURCE_ROOT; }; - 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = disassembler_x86.cc; path = ../../../processor/disassembler_x86.cc; sourceTree = SOURCE_ROOT; }; - 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_disasm.c; path = ../../../third_party/libdisasm/x86_disasm.c; sourceTree = SOURCE_ROOT; }; - 4D2C722C126F9B6E00B43EAF /* x86_misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_misc.c; path = ../../../third_party/libdisasm/x86_misc.c; sourceTree = SOURCE_ROOT; }; - 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_operand_list.c; path = ../../../third_party/libdisasm/x86_operand_list.c; sourceTree = SOURCE_ROOT; }; - 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_invariant.c; path = ../../../third_party/libdisasm/ia32_invariant.c; sourceTree = SOURCE_ROOT; }; - 4D2C7234126F9BC200B43EAF /* ia32_settings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_settings.c; path = ../../../third_party/libdisasm/ia32_settings.c; sourceTree = SOURCE_ROOT; }; - 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_insn.c; path = ../../../third_party/libdisasm/ia32_insn.c; sourceTree = SOURCE_ROOT; }; - 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_opcode_tables.c; path = ../../../third_party/libdisasm/ia32_opcode_tables.c; sourceTree = SOURCE_ROOT; }; - 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_implicit.c; path = ../../../third_party/libdisasm/ia32_implicit.c; sourceTree = SOURCE_ROOT; }; - 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_reg.c; path = ../../../third_party/libdisasm/ia32_reg.c; sourceTree = SOURCE_ROOT; }; - 4D2C725A126F9C8000B43EAF /* ia32_operand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_operand.c; path = ../../../third_party/libdisasm/ia32_operand.c; sourceTree = SOURCE_ROOT; }; - 4D2C725C126F9C9200B43EAF /* x86_insn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_insn.c; path = ../../../third_party/libdisasm/x86_insn.c; sourceTree = SOURCE_ROOT; }; - 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ia32_modrm.c; path = ../../../third_party/libdisasm/ia32_modrm.c; sourceTree = SOURCE_ROOT; }; - 4D2C7263126F9CBB00B43EAF /* x86_imm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = x86_imm.c; path = ../../../third_party/libdisasm/x86_imm.c; sourceTree = SOURCE_ROOT; }; - 4D72CA5613DFBA84006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; }; - 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; }; - 5578003F0BE1F28500EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; }; - 8B31025311F0D2D400FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module.cc; path = ../../../common/dwarf_cfi_to_module.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF2511F0C62700FCF3E4 /* dwarf_cfi_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cfi_to_module.h; path = ../../../common/dwarf_cfi_to_module.h; sourceTree = SOURCE_ROOT; }; - 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module.cc; path = ../../../common/dwarf_cu_to_module.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF2711F0C62700FCF3E4 /* dwarf_cu_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cu_to_module.h; path = ../../../common/dwarf_cu_to_module.h; sourceTree = SOURCE_ROOT; }; - 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module.cc; path = ../../../common/dwarf_line_to_module.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF2911F0C62700FCF3E4 /* dwarf_line_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_line_to_module.h; path = ../../../common/dwarf_line_to_module.h; sourceTree = SOURCE_ROOT; }; - 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader.cc; path = ../../../common/stabs_reader.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF3E11F0C64400FCF3E4 /* stabs_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_reader.h; path = ../../../common/stabs_reader.h; sourceTree = SOURCE_ROOT; }; - 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module.cc; path = ../../../common/stabs_to_module.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF4011F0C64400FCF3E4 /* stabs_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_to_module.h; path = ../../../common/stabs_to_module.h; sourceTree = SOURCE_ROOT; }; - 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader.cc; path = ../../../common/mac/macho_reader.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF7311F0C6E000FCF3E4 /* macho_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_reader.h; path = ../../../common/mac/macho_reader.h; sourceTree = SOURCE_ROOT; }; - 8B31FF8411F0C6FB00FCF3E4 /* language.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = language.cc; path = ../../../common/language.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF8511F0C6FB00FCF3E4 /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = language.h; path = ../../../common/language.h; sourceTree = SOURCE_ROOT; }; - 8B31FF8611F0C6FB00FCF3E4 /* module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module.cc; path = ../../../common/module.cc; sourceTree = SOURCE_ROOT; }; - 8B31FF8711F0C6FB00FCF3E4 /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = module.h; path = ../../../common/module.h; sourceTree = SOURCE_ROOT; }; - 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler.cc; path = ../../../common/dwarf/dwarf2diehandler.cc; sourceTree = SOURCE_ROOT; }; - 8B31FFC411F0C8AB00FCF3E4 /* dwarf2diehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2diehandler.h; path = ../../../common/dwarf/dwarf2diehandler.h; sourceTree = SOURCE_ROOT; }; - 8B40BDBF0C0638E4009535AF /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = logging.cc; path = ../../../processor/logging.cc; sourceTree = SOURCE_ROOT; }; - 8DD76FA10486AA7600D96B5E /* crash_report */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = crash_report; sourceTree = BUILT_PRODUCTS_DIR; }; - 9B35FEE20B2675F9008DE8C7 /* code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_module.h; path = ../../../google_breakpad/processor/code_module.h; sourceTree = SOURCE_ROOT; }; - 9B35FEE30B2675F9008DE8C7 /* code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = code_modules.h; path = ../../../google_breakpad/processor/code_modules.h; sourceTree = SOURCE_ROOT; }; - 9B35FEE60B26761C008DE8C7 /* basic_code_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_module.h; path = ../../../processor/basic_code_module.h; sourceTree = SOURCE_ROOT; }; - 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_code_modules.cc; path = ../../../processor/basic_code_modules.cc; sourceTree = SOURCE_ROOT; }; - 9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = basic_code_modules.h; path = ../../../processor/basic_code_modules.h; sourceTree = SOURCE_ROOT; }; - 9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = basic_source_line_resolver.h; sourceTree = ""; }; - 9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source_line_resolver_interface.h; sourceTree = ""; }; - 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = basic_source_line_resolver.cc; path = ../../../processor/basic_source_line_resolver.cc; sourceTree = SOURCE_ROOT; }; - 9B44619D0B66C66B00BBB817 /* system_info.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = system_info.h; sourceTree = ""; }; - 9BDF16F90B1B8ACD00F8391B /* breakpad_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = breakpad_types.h; sourceTree = ""; }; - 9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_format.h; sourceTree = ""; }; - 9BDF16FC0B1B8ACD00F8391B /* call_stack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = call_stack.h; sourceTree = ""; }; - 9BDF16FD0B1B8ACD00F8391B /* memory_region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = memory_region.h; sourceTree = ""; }; - 9BDF16FE0B1B8ACD00F8391B /* minidump.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump.h; sourceTree = ""; }; - 9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = minidump_processor.h; sourceTree = ""; }; - 9BDF17000B1B8ACD00F8391B /* process_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process_state.h; sourceTree = ""; }; - 9BDF17010B1B8ACD00F8391B /* stack_frame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame.h; sourceTree = ""; }; - 9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stack_frame_cpu.h; sourceTree = ""; }; - 9BDF17030B1B8ACD00F8391B /* stackwalker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stackwalker.h; sourceTree = ""; }; - 9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = symbol_supplier.h; sourceTree = ""; }; - 9BDF172A0B1B8B2400F8391B /* call_stack.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = call_stack.cc; path = ../../../processor/call_stack.cc; sourceTree = SOURCE_ROOT; }; - 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump_processor.cc; path = ../../../processor/minidump_processor.cc; sourceTree = SOURCE_ROOT; }; - 9BDF173F0B1B8B9A00F8391B /* minidump.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = minidump.cc; path = ../../../processor/minidump.cc; sourceTree = SOURCE_ROOT; }; - 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_ppc.cc; path = ../../../processor/stackwalker_ppc.cc; sourceTree = SOURCE_ROOT; }; - 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_x86.cc; path = ../../../processor/stackwalker_x86.cc; sourceTree = SOURCE_ROOT; }; - 9BDF17530B1B8BF900F8391B /* stackwalker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker.cc; path = ../../../processor/stackwalker.cc; sourceTree = SOURCE_ROOT; }; - 9BDF175B0B1B8C1B00F8391B /* process_state.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = process_state.cc; path = ../../../processor/process_state.cc; sourceTree = SOURCE_ROOT; }; - 9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = on_demand_symbol_supplier.h; sourceTree = ""; }; - 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = on_demand_symbol_supplier.mm; sourceTree = ""; }; - 9BDF192D0B1BC15D00F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; }; - 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = SOURCE_ROOT; }; - 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pathname_stripper.cc; path = ../../../processor/pathname_stripper.cc; sourceTree = SOURCE_ROOT; }; - 9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "range_map-inl.h"; path = "../../../processor/range_map-inl.h"; sourceTree = SOURCE_ROOT; }; - 9BDF1A7B0B1BE30100F8391B /* range_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = range_map.h; path = ../../../processor/range_map.h; sourceTree = SOURCE_ROOT; }; - 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "address_map-inl.h"; path = "../../../processor/address_map-inl.h"; sourceTree = SOURCE_ROOT; }; - 9BDF1AFB0B1BEB6300F8391B /* address_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = address_map.h; path = ../../../processor/address_map.h; sourceTree = SOURCE_ROOT; }; - 9BE650AC0B52FE3000611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; }; - 9BE650AD0B52FE3000611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; }; - 9BE650AE0B52FE3000611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; }; - 9BE650AF0B52FE3000611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; - 9BE650B00B52FE3000611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; - 9BE650B10B52FE3000611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; - D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cfi_frame_info.cc; path = ../../../processor/cfi_frame_info.cc; sourceTree = SOURCE_ROOT; }; - D2A5DD621188658B00081F03 /* tokenize.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tokenize.cc; path = ../../../processor/tokenize.cc; sourceTree = SOURCE_ROOT; }; - F407DC40185773C10064622B /* exploitability_linux.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exploitability_linux.cc; path = ../../../processor/exploitability_linux.cc; sourceTree = ""; }; - F407DC41185773C10064622B /* stack_frame_symbolizer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stack_frame_symbolizer.cc; path = ../../../processor/stack_frame_symbolizer.cc; sourceTree = ""; }; - F407DC42185773C10064622B /* stackwalker_arm64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_arm64.cc; path = ../../../processor/stackwalker_arm64.cc; sourceTree = ""; }; - F407DC43185773C10064622B /* stackwalker_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_arm64.h; path = ../../../processor/stackwalker_arm64.h; sourceTree = ""; }; - F407DC44185773C10064622B /* stackwalker_mips.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_mips.cc; path = ../../../processor/stackwalker_mips.cc; sourceTree = ""; }; - F407DC45185773C10064622B /* stackwalker_mips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_mips.h; path = ../../../processor/stackwalker_mips.h; sourceTree = ""; }; - F407DC46185773C10064622B /* stackwalker_ppc64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_ppc64.cc; path = ../../../processor/stackwalker_ppc64.cc; sourceTree = ""; }; - F407DC47185773C10064622B /* stackwalker_ppc64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_ppc64.h; path = ../../../processor/stackwalker_ppc64.h; sourceTree = ""; }; - F44DDD8419C85CD50047280E /* dump_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dump_context.cc; path = ../../../processor/dump_context.cc; sourceTree = ""; }; - F44DDD8519C85CD50047280E /* dump_object.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dump_object.cc; path = ../../../processor/dump_object.cc; sourceTree = ""; }; - F44DDD8619C85CD50047280E /* microdump_processor.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = microdump_processor.cc; path = ../../../processor/microdump_processor.cc; sourceTree = ""; }; - F44DDD8A19C85CFB0047280E /* dump_context.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dump_context.h; path = ../../../google_breakpad/processor/dump_context.h; sourceTree = ""; }; - F44DDD8B19C85CFB0047280E /* dump_object.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = dump_object.h; path = ../../../google_breakpad/processor/dump_object.h; sourceTree = ""; }; - F44DDD8C19C85CFC0047280E /* microdump_processor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = microdump_processor.h; path = ../../../google_breakpad/processor/microdump_processor.h; sourceTree = ""; }; - F44DDD8D19C85CFC0047280E /* process_result.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = process_result.h; path = ../../../google_breakpad/processor/process_result.h; sourceTree = ""; }; - F4D43B2E1A38490700C290B2 /* microdump.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = microdump.cc; path = ../../../processor/microdump.cc; sourceTree = ""; }; - F4D43B301A38492000C290B2 /* microdump.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = microdump.h; path = ../../../google_breakpad/processor/microdump.h; sourceTree = ""; }; - F9C7ECE20E8ABCA600E953AD /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; - F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; - F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; }; - F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_arm.cc; path = ../../../processor/stackwalker_arm.cc; sourceTree = SOURCE_ROOT; }; - F9F0706610FBC02D0037B88B /* stackwalker_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_arm.h; path = ../../../processor/stackwalker_arm.h; sourceTree = SOURCE_ROOT; }; - FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_amd64.cc; path = ../../../processor/stackwalker_amd64.cc; sourceTree = SOURCE_ROOT; }; - FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_amd64.h; path = ../../../processor/stackwalker_amd64.h; sourceTree = SOURCE_ROOT; }; - FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_sparc.cc; path = ../../../processor/stackwalker_sparc.cc; sourceTree = SOURCE_ROOT; }; - FD8EDEAD0CADDAD400A5EDF1 /* stackwalker_sparc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stackwalker_sparc.h; path = ../../../processor/stackwalker_sparc.h; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* crash_report */ = { - isa = PBXGroup; - children = ( - 8B31025311F0D2D400FCF3E4 /* Breakpad.xcconfig */, - 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */, - 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */, - F9C7ECE10E8ABC7F00E953AD /* DWARF */, - 162F64FC161C5ECB00CD68D5 /* arch_utilities.cc */, - 162F64FD161C5ECB00CD68D5 /* arch_utilities.h */, - 5578003E0BE1F28500EC23E0 /* macho_utilities.cc */, - 5578003F0BE1F28500EC23E0 /* macho_utilities.h */, - 8B31FF7211F0C6E000FCF3E4 /* macho_reader.cc */, - 8B31FF7311F0C6E000FCF3E4 /* macho_reader.h */, - 9BDF192D0B1BC15D00F8391B /* dump_syms.h */, - 9BDF192E0B1BC15D00F8391B /* dump_syms.mm */, - 08FB7796FE84155DC02AAC07 /* crash_report.mm */, - F44DDD8D19C85CFC0047280E /* process_result.h */, - 9BDF176B0B1B8CB100F8391B /* on_demand_symbol_supplier.h */, - F44DDD8419C85CD50047280E /* dump_context.cc */, - F44DDD8A19C85CFB0047280E /* dump_context.h */, - F44DDD8519C85CD50047280E /* dump_object.cc */, - F44DDD8B19C85CFB0047280E /* dump_object.h */, - F4D43B2E1A38490700C290B2 /* microdump.cc */, - F4D43B301A38492000C290B2 /* microdump.h */, - F44DDD8619C85CD50047280E /* microdump_processor.cc */, - F44DDD8C19C85CFC0047280E /* microdump_processor.h */, - 9BDF176C0B1B8CB100F8391B /* on_demand_symbol_supplier.mm */, - 8B31FF2411F0C62700FCF3E4 /* dwarf_cfi_to_module.cc */, - 8B31FF2511F0C62700FCF3E4 /* dwarf_cfi_to_module.h */, - 8B31FF2611F0C62700FCF3E4 /* dwarf_cu_to_module.cc */, - 8B31FF2711F0C62700FCF3E4 /* dwarf_cu_to_module.h */, - 8B31FF2811F0C62700FCF3E4 /* dwarf_line_to_module.cc */, - 8B31FF2911F0C62700FCF3E4 /* dwarf_line_to_module.h */, - 8B31FF3D11F0C64400FCF3E4 /* stabs_reader.cc */, - 8B31FF3E11F0C64400FCF3E4 /* stabs_reader.h */, - 8B31FF3F11F0C64400FCF3E4 /* stabs_to_module.cc */, - 8B31FF4011F0C64400FCF3E4 /* stabs_to_module.h */, - 8B31FF8411F0C6FB00FCF3E4 /* language.cc */, - 8B31FF8511F0C6FB00FCF3E4 /* language.h */, - 4D72CA5613DFBA84006CABE3 /* md5.cc */, - 8B31FF8611F0C6FB00FCF3E4 /* module.cc */, - 8B31FF8711F0C6FB00FCF3E4 /* module.h */, - 08FB7795FE84155DC02AAC07 /* breakpad */, - 4D2C726E126F9CE200B43EAF /* libdisasm */, - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = crash_report; - sourceTree = ""; - }; - 08FB7795FE84155DC02AAC07 /* breakpad */ = { - isa = PBXGroup; - children = ( - 9BE650AB0B52FE1A00611104 /* common */, - 9BDF17280B1B8B0200F8391B /* processor */, - 9BDF16F70B1B8ACD00F8391B /* google_breakpad */, - ); - name = breakpad; - sourceTree = ""; - }; - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 08FB779EFE84155DC02AAC07 /* Foundation.framework */, - ); - name = "External Frameworks and Libraries"; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8DD76FA10486AA7600D96B5E /* crash_report */, - ); - name = Products; - sourceTree = ""; - }; - 4D2C726E126F9CE200B43EAF /* libdisasm */ = { - isa = PBXGroup; - children = ( - 4D2C7226126F9B0F00B43EAF /* disassembler_x86.cc */, - 4D2C724B126F9C3800B43EAF /* ia32_implicit.c */, - 4D2C7245126F9C0B00B43EAF /* ia32_insn.c */, - 4D2C7232126F9BB000B43EAF /* ia32_invariant.c */, - 4D2C7261126F9CBB00B43EAF /* ia32_modrm.c */, - 4D2C7249126F9C2300B43EAF /* ia32_opcode_tables.c */, - 4D2C725A126F9C8000B43EAF /* ia32_operand.c */, - 4D2C724D126F9C4D00B43EAF /* ia32_reg.c */, - 4D2C7234126F9BC200B43EAF /* ia32_settings.c */, - 4D2C722A126F9B5A00B43EAF /* x86_disasm.c */, - 4D2C7263126F9CBB00B43EAF /* x86_imm.c */, - 4D2C725C126F9C9200B43EAF /* x86_insn.c */, - 4D2C722C126F9B6E00B43EAF /* x86_misc.c */, - 4D2C722E126F9B8300B43EAF /* x86_operand_list.c */, - ); - name = libdisasm; - sourceTree = ""; - }; - 9BDF16F70B1B8ACD00F8391B /* google_breakpad */ = { - isa = PBXGroup; - children = ( - 9BDF16F80B1B8ACD00F8391B /* common */, - 9BDF16FB0B1B8ACD00F8391B /* processor */, - ); - name = google_breakpad; - path = ../../../google_breakpad; - sourceTree = SOURCE_ROOT; - }; - 9BDF16F80B1B8ACD00F8391B /* common */ = { - isa = PBXGroup; - children = ( - 9BDF16F90B1B8ACD00F8391B /* breakpad_types.h */, - 9BDF16FA0B1B8ACD00F8391B /* minidump_format.h */, - ); - path = common; - sourceTree = ""; - }; - 9BDF16FB0B1B8ACD00F8391B /* processor */ = { - isa = PBXGroup; - children = ( - 9B3904940B2E52D90059FABE /* basic_source_line_resolver.h */, - 9BDF16FC0B1B8ACD00F8391B /* call_stack.h */, - 9B35FEE20B2675F9008DE8C7 /* code_module.h */, - 9B35FEE30B2675F9008DE8C7 /* code_modules.h */, - 9BDF16FD0B1B8ACD00F8391B /* memory_region.h */, - 9BDF16FE0B1B8ACD00F8391B /* minidump.h */, - 9BDF16FF0B1B8ACD00F8391B /* minidump_processor.h */, - 9BDF17000B1B8ACD00F8391B /* process_state.h */, - 9B3904950B2E52D90059FABE /* source_line_resolver_interface.h */, - 9BDF17010B1B8ACD00F8391B /* stack_frame.h */, - 9BDF17020B1B8ACD00F8391B /* stack_frame_cpu.h */, - 9BDF17030B1B8ACD00F8391B /* stackwalker.h */, - 9BDF17040B1B8ACD00F8391B /* symbol_supplier.h */, - 9B44619D0B66C66B00BBB817 /* system_info.h */, - ); - path = processor; - sourceTree = ""; - }; - 9BDF17280B1B8B0200F8391B /* processor */ = { - isa = PBXGroup; - children = ( - 4D2C7222126F9AF900B43EAF /* exploitability_win.cc */, - F407DC40185773C10064622B /* exploitability_linux.cc */, - F407DC41185773C10064622B /* stack_frame_symbolizer.cc */, - F407DC42185773C10064622B /* stackwalker_arm64.cc */, - F407DC43185773C10064622B /* stackwalker_arm64.h */, - F407DC44185773C10064622B /* stackwalker_mips.cc */, - F407DC45185773C10064622B /* stackwalker_mips.h */, - F407DC46185773C10064622B /* stackwalker_ppc64.cc */, - F407DC47185773C10064622B /* stackwalker_ppc64.h */, - 4D2C721E126F9ADE00B43EAF /* exploitability.cc */, - 4D2C721A126F9ACC00B43EAF /* source_line_resolver_base.cc */, - D2A5DD621188658B00081F03 /* tokenize.cc */, - D2A5DD4C1188651100081F03 /* cfi_frame_info.cc */, - F9F0706510FBC02D0037B88B /* stackwalker_arm.cc */, - F9F0706610FBC02D0037B88B /* stackwalker_arm.h */, - 9B3904980B2E52FD0059FABE /* basic_source_line_resolver.cc */, - 9BDF1AFA0B1BEB6300F8391B /* address_map-inl.h */, - 9BDF1AFB0B1BEB6300F8391B /* address_map.h */, - 9B35FEE60B26761C008DE8C7 /* basic_code_module.h */, - 9B35FEE70B26761C008DE8C7 /* basic_code_modules.cc */, - 9B35FEE80B26761C008DE8C7 /* basic_code_modules.h */, - 9BDF172A0B1B8B2400F8391B /* call_stack.cc */, - 8B40BDBF0C0638E4009535AF /* logging.cc */, - 9BDF173F0B1B8B9A00F8391B /* minidump.cc */, - 9BDF172B0B1B8B2400F8391B /* minidump_processor.cc */, - 9BDF1A270B1BD58200F8391B /* pathname_stripper.cc */, - 9BDF175B0B1B8C1B00F8391B /* process_state.cc */, - 9BDF1A7A0B1BE30100F8391B /* range_map-inl.h */, - 9BDF1A7B0B1BE30100F8391B /* range_map.h */, - 9BDF17530B1B8BF900F8391B /* stackwalker.cc */, - 9BDF17510B1B8BF900F8391B /* stackwalker_ppc.cc */, - 9BDF17520B1B8BF900F8391B /* stackwalker_x86.cc */, - FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */, - FD8EDEAD0CADDAD400A5EDF1 /* stackwalker_sparc.h */, - FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */, - FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */, - ); - name = processor; - sourceTree = ""; - }; - 9BE650AB0B52FE1A00611104 /* common */ = { - isa = PBXGroup; - children = ( - 9BE650AC0B52FE3000611104 /* file_id.cc */, - 9BE650AD0B52FE3000611104 /* file_id.h */, - 9BE650AE0B52FE3000611104 /* macho_id.cc */, - 9BE650AF0B52FE3000611104 /* macho_id.h */, - 9BE650B00B52FE3000611104 /* macho_walker.cc */, - 9BE650B10B52FE3000611104 /* macho_walker.h */, - ); - name = common; - sourceTree = ""; - }; - F9C7ECE10E8ABC7F00E953AD /* DWARF */ = { - isa = PBXGroup; - children = ( - F9C7ECE20E8ABCA600E953AD /* bytereader.cc */, - F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */, - 8B31FFC311F0C8AB00FCF3E4 /* dwarf2diehandler.cc */, - 8B31FFC411F0C8AB00FCF3E4 /* dwarf2diehandler.h */, - F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */, - ); - name = DWARF; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8DD76F960486AA7600D96B5E /* crash_report */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */; - buildPhases = ( - 8DD76F990486AA7600D96B5E /* Sources */, - 8DD76F9B0486AA7600D96B5E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = crash_report; - productInstallPath = "$(HOME)/bin"; - productName = crash_report; - productReference = 8DD76FA10486AA7600D96B5E /* crash_report */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */; - compatibilityVersion = "Xcode 3.1"; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* crash_report */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8DD76F960486AA7600D96B5E /* crash_report */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DD76F990486AA7600D96B5E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 162F64FE161C5ECB00CD68D5 /* arch_utilities.cc in Sources */, - 8DD76F9A0486AA7600D96B5E /* crash_report.mm in Sources */, - 9BDF172C0B1B8B2400F8391B /* call_stack.cc in Sources */, - 9BDF172D0B1B8B2400F8391B /* minidump_processor.cc in Sources */, - 9BDF17410B1B8B9A00F8391B /* minidump.cc in Sources */, - F44DDD8719C85CD50047280E /* dump_context.cc in Sources */, - 9BDF17540B1B8BF900F8391B /* stackwalker_ppc.cc in Sources */, - 9BDF17550B1B8BF900F8391B /* stackwalker_x86.cc in Sources */, - 9BDF17560B1B8BF900F8391B /* stackwalker.cc in Sources */, - 9BDF175D0B1B8C1B00F8391B /* process_state.cc in Sources */, - 9BDF176E0B1B8CB100F8391B /* on_demand_symbol_supplier.mm in Sources */, - 9BDF1A280B1BD58200F8391B /* pathname_stripper.cc in Sources */, - 9BDF21A70B1E825400F8391B /* dump_syms.mm in Sources */, - 9B35FEEA0B26761C008DE8C7 /* basic_code_modules.cc in Sources */, - 9B3904990B2E52FD0059FABE /* basic_source_line_resolver.cc in Sources */, - 9BE650B20B52FE3000611104 /* file_id.cc in Sources */, - 9BE650B40B52FE3000611104 /* macho_id.cc in Sources */, - 9BE650B60B52FE3000611104 /* macho_walker.cc in Sources */, - 557800400BE1F28500EC23E0 /* macho_utilities.cc in Sources */, - 8B40BDC00C0638E4009535AF /* logging.cc in Sources */, - FD8EDEAE0CADDAD400A5EDF1 /* stackwalker_sparc.cc in Sources */, - FD6625CD0CF4D45C004AC844 /* stackwalker_amd64.cc in Sources */, - F9C7ECE50E8ABCA600E953AD /* bytereader.cc in Sources */, - F9C7ECE60E8ABCA600E953AD /* dwarf2reader.cc in Sources */, - F9C7ECE70E8ABCA600E953AD /* functioninfo.cc in Sources */, - F9F0706710FBC02D0037B88B /* stackwalker_arm.cc in Sources */, - D2A5DD4D1188651100081F03 /* cfi_frame_info.cc in Sources */, - D2A5DD631188658B00081F03 /* tokenize.cc in Sources */, - 8B31FF2A11F0C62700FCF3E4 /* dwarf_cfi_to_module.cc in Sources */, - F4D43B2F1A38490700C290B2 /* microdump.cc in Sources */, - 8B31FF2B11F0C62700FCF3E4 /* dwarf_cu_to_module.cc in Sources */, - F44DDD8819C85CD50047280E /* dump_object.cc in Sources */, - 8B31FF2C11F0C62700FCF3E4 /* dwarf_line_to_module.cc in Sources */, - 8B31FF4111F0C64400FCF3E4 /* stabs_reader.cc in Sources */, - 8B31FF4211F0C64400FCF3E4 /* stabs_to_module.cc in Sources */, - 8B31FF7411F0C6E000FCF3E4 /* macho_reader.cc in Sources */, - 8B31FF8811F0C6FB00FCF3E4 /* language.cc in Sources */, - 8B31FF8911F0C6FB00FCF3E4 /* module.cc in Sources */, - 8B31FFC511F0C8AB00FCF3E4 /* dwarf2diehandler.cc in Sources */, - F407DC49185773C10064622B /* stack_frame_symbolizer.cc in Sources */, - 4D2C721B126F9ACC00B43EAF /* source_line_resolver_base.cc in Sources */, - 4D2C721F126F9ADE00B43EAF /* exploitability.cc in Sources */, - 4D2C7223126F9AF900B43EAF /* exploitability_win.cc in Sources */, - 4D2C7227126F9B0F00B43EAF /* disassembler_x86.cc in Sources */, - F407DC48185773C10064622B /* exploitability_linux.cc in Sources */, - 4D2C722B126F9B5A00B43EAF /* x86_disasm.c in Sources */, - 4D2C722D126F9B6E00B43EAF /* x86_misc.c in Sources */, - 4D2C722F126F9B8300B43EAF /* x86_operand_list.c in Sources */, - F407DC4A185773C10064622B /* stackwalker_arm64.cc in Sources */, - 4D2C7233126F9BB000B43EAF /* ia32_invariant.c in Sources */, - 4D2C7235126F9BC200B43EAF /* ia32_settings.c in Sources */, - 4D2C7246126F9C0B00B43EAF /* ia32_insn.c in Sources */, - 4D2C724A126F9C2300B43EAF /* ia32_opcode_tables.c in Sources */, - 4D2C724C126F9C3800B43EAF /* ia32_implicit.c in Sources */, - F44DDD8919C85CD50047280E /* microdump_processor.cc in Sources */, - 4D2C724E126F9C4D00B43EAF /* ia32_reg.c in Sources */, - 4D2C725B126F9C8000B43EAF /* ia32_operand.c in Sources */, - F407DC4C185773C10064622B /* stackwalker_ppc64.cc in Sources */, - 4D2C725D126F9C9200B43EAF /* x86_insn.c in Sources */, - 4D2C7264126F9CBB00B43EAF /* ia32_modrm.c in Sources */, - F407DC4B185773C10064622B /* stackwalker_mips.cc in Sources */, - 4D2C726D126F9CDC00B43EAF /* x86_imm.c in Sources */, - 4D72CA5713DFBA84006CABE3 /* md5.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB927508733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../../../src; - PRODUCT_NAME = crash_report; - }; - name = Debug; - }; - 1DEB927608733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../../../src; - PRODUCT_NAME = crash_report; - }; - name = Release; - }; - 1DEB927908733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102DA11F0D65600FCF3E4 /* BreakpadDebug.xcconfig */; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - }; - name = Debug; - }; - 1DEB927A08733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102DB11F0D65600FCF3E4 /* BreakpadRelease.xcconfig */; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "crash_report" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927508733DD40010E9CD /* Debug */, - 1DEB927608733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "crash_report" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927908733DD40010E9CD /* Debug */, - 1DEB927A08733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h deleted file mode 100644 index 3fbe108eb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// on_demand_symbol_supplier.h: Provides a Symbol Supplier that will create -// a breakpad symbol file on demand. - -#ifndef TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__ -#define TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__ - -#include -#include -#include "google_breakpad/processor/symbol_supplier.h" - -namespace google_breakpad { - -using std::map; -using std::string; -class MinidumpModule; - -class OnDemandSymbolSupplier : public SymbolSupplier { - public: - // |search_dir| is the directory to search for alternative symbols with - // the same name as the module in the minidump - OnDemandSymbolSupplier(const string &search_dir, - const string &symbol_search_dir); - virtual ~OnDemandSymbolSupplier() {} - - // Returns the path to the symbol file for the given module. - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file); - - // Returns the path to the symbol file for the given module. - virtual SymbolResult GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data); - // Allocates data buffer on heap, and takes the ownership of - // the data buffer. - virtual SymbolResult GetCStringSymbolData(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size); - - // Delete the data buffer allocated for module in GetCStringSymbolData(). - virtual void FreeSymbolData(const CodeModule *module); - - protected: - // Search directory - string search_dir_; - string symbol_search_dir_; - - // When we create a symbol file for a module, save the name of the module - // and the path to that module's symbol file. - map module_file_map_; - - // Map of allocated data buffers, keyed by module->code_file(). - map memory_buffers_; - - // Return the name for |module| This will be the value used as the key - // to the |module_file_map_|. - string GetNameForModule(const CodeModule *module); - - // Find the module on local system. If the module resides in a different - // location than the full path in the minidump, this will be the location - // used. - string GetLocalModulePath(const CodeModule *module); - - // Return the full path for |module|. - string GetModulePath(const CodeModule *module); - - // Return the path to the symbol file for |module|. If an empty string is - // returned, then |module| doesn't have a symbol file. - string GetModuleSymbolFile(const CodeModule *module); - - // Generate the breakpad symbol file for |module|. Return true if successful. - // File is generated in /tmp. - bool GenerateSymbolFile(const CodeModule *module, - const SystemInfo *system_info); -}; - -} // namespace google_breakpad - -#endif // TOOLS_MAC_CRASH_REPORT_ON_DEMAND_SYMBOL_SUPPLIER_H__ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm deleted file mode 100644 index ebbca87a0..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.mm +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include - -#include "google_breakpad/processor/basic_source_line_resolver.h" -#include "google_breakpad/processor/minidump.h" -#include "google_breakpad/processor/system_info.h" -#include "processor/pathname_stripper.h" - -#include "on_demand_symbol_supplier.h" -#include "common/mac/dump_syms.h" - -using std::map; -using std::string; - -using google_breakpad::OnDemandSymbolSupplier; -using google_breakpad::PathnameStripper; -using google_breakpad::SymbolSupplier; -using google_breakpad::SystemInfo; - -OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string &search_dir, - const string &symbol_search_dir) - : search_dir_(search_dir) { - NSFileManager *mgr = [NSFileManager defaultManager]; - size_t length = symbol_search_dir.length(); - if (length) { - // Load all sym files in symbol_search_dir into our module_file_map - // A symbol file always starts with a line like this: - // MODULE mac x86 BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon - // or - // MODULE mac ppc BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon - const char *symbolSearchStr = symbol_search_dir.c_str(); - NSString *symbolSearchPath = - [mgr stringWithFileSystemRepresentation:symbolSearchStr - length:strlen(symbolSearchStr)]; - NSDirectoryEnumerator *dirEnum = [mgr enumeratorAtPath:symbolSearchPath]; - NSString *fileName; - NSCharacterSet *hexSet = - [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"]; - NSCharacterSet *newlineSet = - [NSCharacterSet characterSetWithCharactersInString:@"\r\n"]; - while ((fileName = [dirEnum nextObject])) { - // Check to see what type of file we have - NSDictionary *attrib = [dirEnum fileAttributes]; - NSString *fileType = [attrib objectForKey:NSFileType]; - if ([fileType isEqualToString:NSFileTypeDirectory]) { - // Skip subdirectories - [dirEnum skipDescendents]; - } else { - NSString *filePath = [symbolSearchPath stringByAppendingPathComponent:fileName]; - NSString *dataStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL]; - if (dataStr) { - // Check file to see if it is of appropriate type, and grab module - // name. - NSScanner *scanner = [NSScanner scannerWithString:dataStr]; - BOOL goodScan = [scanner scanString:@"MODULE mac " intoString:nil]; - if (goodScan) { - goodScan = ([scanner scanString:@"x86 " intoString:nil] || - [scanner scanString:@"x86_64 " intoString:nil] || - [scanner scanString:@"ppc " intoString:nil]); - if (goodScan) { - NSString *moduleID; - goodScan = [scanner scanCharactersFromSet:hexSet - intoString:&moduleID]; - if (goodScan) { - // Module IDs are always 33 chars long - goodScan = [moduleID length] == 33; - if (goodScan) { - NSString *moduleName; - goodScan = [scanner scanUpToCharactersFromSet:newlineSet - intoString:&moduleName]; - if (goodScan) { - goodScan = [moduleName length] > 0; - if (goodScan) { - const char *moduleNameStr = [moduleName UTF8String]; - const char *filePathStr = [filePath fileSystemRepresentation]; - // Map our file - module_file_map_[moduleNameStr] = filePathStr; - } - } - } - } - } - } - } - } - } - } -} - -SymbolSupplier::SymbolResult -OnDemandSymbolSupplier::GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file) { - string path(GetModuleSymbolFile(module)); - - if (path.empty()) { - if (!GenerateSymbolFile(module, system_info)) - return NOT_FOUND; - - path = GetModuleSymbolFile(module); - } - - if (path.empty()) - return NOT_FOUND; - - *symbol_file = path; - return FOUND; -} - -SymbolSupplier::SymbolResult -OnDemandSymbolSupplier::GetSymbolFile(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - string *symbol_data) { - SymbolSupplier::SymbolResult s = GetSymbolFile(module, - system_info, - symbol_file); - - - if (s == FOUND) { - std::ifstream in(symbol_file->c_str()); - getline(in, *symbol_data, std::string::traits_type::to_char_type( - std::string::traits_type::eof())); - in.close(); - } - - return s; -} - -SymbolSupplier::SymbolResult -OnDemandSymbolSupplier::GetCStringSymbolData(const CodeModule *module, - const SystemInfo *system_info, - string *symbol_file, - char **symbol_data, - size_t *symbol_data_size) { - std::string symbol_data_string; - SymbolSupplier::SymbolResult result = GetSymbolFile(module, - system_info, - symbol_file, - &symbol_data_string); - if (result == FOUND) { - *symbol_data_size = symbol_data_string.size() + 1; - *symbol_data = new char[*symbol_data_size]; - if (*symbol_data == NULL) { - // Should return INTERRUPT on memory allocation failure. - return INTERRUPT; - } - memcpy(*symbol_data, symbol_data_string.c_str(), symbol_data_string.size()); - (*symbol_data)[symbol_data_string.size()] = '\0'; - memory_buffers_.insert(make_pair(module->code_file(), *symbol_data)); - } - return result; -} - -void OnDemandSymbolSupplier::FreeSymbolData(const CodeModule *module) { - map::iterator it = memory_buffers_.find(module->code_file()); - if (it != memory_buffers_.end()) { - delete [] it->second; - memory_buffers_.erase(it); - } -} - -string OnDemandSymbolSupplier::GetLocalModulePath(const CodeModule *module) { - NSFileManager *mgr = [NSFileManager defaultManager]; - const char *moduleStr = module->code_file().c_str(); - NSString *modulePath = - [mgr stringWithFileSystemRepresentation:moduleStr length:strlen(moduleStr)]; - const char *searchStr = search_dir_.c_str(); - NSString *searchDir = - [mgr stringWithFileSystemRepresentation:searchStr length:strlen(searchStr)]; - - if ([mgr fileExistsAtPath:modulePath]) - return module->code_file(); - - // If the module is not found, try to start appending the components to the - // search string and stop if a file (not dir) is found or all components - // have been appended - NSArray *pathComponents = [modulePath componentsSeparatedByString:@"/"]; - size_t count = [pathComponents count]; - NSMutableString *path = [NSMutableString string]; - - for (size_t i = 0; i < count; ++i) { - [path setString:searchDir]; - - for (size_t j = 0; j < i + 1; ++j) { - size_t idx = count - 1 - i + j; - [path appendFormat:@"/%@", [pathComponents objectAtIndex:idx]]; - } - - BOOL isDir; - if ([mgr fileExistsAtPath:path isDirectory:&isDir] && (!isDir)) { - return [path fileSystemRepresentation]; - } - } - - return ""; -} - -string OnDemandSymbolSupplier::GetModulePath(const CodeModule *module) { - return module->code_file(); -} - -string OnDemandSymbolSupplier::GetNameForModule(const CodeModule *module) { - return PathnameStripper::File(module->code_file()); -} - -string OnDemandSymbolSupplier::GetModuleSymbolFile(const CodeModule *module) { - string name(GetNameForModule(module)); - map::iterator result = module_file_map_.find(name); - - return (result == module_file_map_.end()) ? "" : (*result).second; -} - -static float GetFileModificationTime(const char *path) { - float result = 0; - struct stat file_stat; - if (stat(path, &file_stat) == 0) - result = (float)file_stat.st_mtimespec.tv_sec + - (float)file_stat.st_mtimespec.tv_nsec / 1.0e9f; - - return result; -} - -bool OnDemandSymbolSupplier::GenerateSymbolFile(const CodeModule *module, - const SystemInfo *system_info) { - bool result = true; - string name = GetNameForModule(module); - string module_path = GetLocalModulePath(module); - NSString *symbol_path = [NSString stringWithFormat:@"/tmp/%s.%s.sym", - name.c_str(), system_info->cpu.c_str()]; - - if (module_path.empty()) - return false; - - // Check if there's already a symbol file cached. Ensure that the file is - // newer than the module. Otherwise, generate a new one. - BOOL generate_file = YES; - if ([[NSFileManager defaultManager] fileExistsAtPath:symbol_path]) { - // Check if the module file is newer than the saved symbols - float cache_time = - GetFileModificationTime([symbol_path fileSystemRepresentation]); - float module_time = - GetFileModificationTime(module_path.c_str()); - - if (cache_time > module_time) - generate_file = NO; - } - - if (generate_file) { - NSString *module_str = [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:module_path.c_str() - length:module_path.length()]; - DumpSymbols dump(ALL_SYMBOL_DATA, false); - if (dump.Read(module_str)) { - // What Breakpad calls "x86" should be given to the system as "i386". - std::string architecture; - if (system_info->cpu.compare("x86") == 0) { - architecture = "i386"; - } else { - architecture = system_info->cpu; - } - - if (dump.SetArchitecture(architecture)) { - std::fstream file([symbol_path fileSystemRepresentation], - std::ios_base::out | std::ios_base::trunc); - dump.WriteSymbolFile(file); - } else { - printf("Architecture %s not available for %s\n", - system_info->cpu.c_str(), name.c_str()); - result = false; - } - } else { - printf("Unable to open %s\n", [module_str UTF8String]); - result = false; - } - } - - // Add the mapping - if (result) - module_file_map_[name] = [symbol_path fileSystemRepresentation]; - - return result; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj deleted file mode 100644 index 2e6bd9e10..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1839 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXAggregateTarget section */ - B88FAFC9116BDCAD00407530 /* all_unittests */ = { - isa = PBXAggregateTarget; - buildConfigurationList = B88FAFCC116BDCCC00407530 /* Build configuration list for PBXAggregateTarget "all_unittests" */; - buildPhases = ( - B88FB094116CE73E00407530 /* ShellScript */, - ); - dependencies = ( - B88FB15B116CF53E00407530 /* PBXTargetDependency */, - B88FAFCF116BDD7000407530 /* PBXTargetDependency */, - B88FB01D116BDF9800407530 /* PBXTargetDependency */, - B88FB167116CF54B00407530 /* PBXTargetDependency */, - B88FAFD1116BDD7000407530 /* PBXTargetDependency */, - B88FB165116CF54B00407530 /* PBXTargetDependency */, - B88FB161116CF54B00407530 /* PBXTargetDependency */, - B88FB15F116CF54B00407530 /* PBXTargetDependency */, - B88FB15D116CF54B00407530 /* PBXTargetDependency */, - B84A9201116CF7D2006C210E /* PBXTargetDependency */, - B88FB0C8116CEB4A00407530 /* PBXTargetDependency */, - 8B31051511F100CF00FCF3E4 /* PBXTargetDependency */, - ); - name = all_unittests; - productName = all_unittests; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; }; - 162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; }; - 4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CAF413DFBAC2006CABE3 /* md5.cc */; }; - 8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; }; - 8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; }; - B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B84A91FB116CF7AF006C210E /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; }; - B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */; }; - B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1711665FE400407530 /* dwarf2diehandler.cc */; }; - B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */; }; - B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE201166603300407530 /* dwarf_line_to_module.cc */; }; - B88FAE281166603300407530 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE221166603300407530 /* language.cc */; }; - B88FAE291166603300407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B88FAE2C1166606200407530 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; }; - B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */; }; - B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3911666C6F00407530 /* stabs_reader.cc */; }; - B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; }; - B88FAF37116A595400407530 /* cfi_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF34116A595400407530 /* cfi_assembler.cc */; }; - B88FAF38116A595400407530 /* dwarf2reader_cfi_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */; }; - B88FAF3F116A5A2E00407530 /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */; }; - B88FAF40116A5A2E00407530 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; }; - B88FB00F116BDEA700407530 /* stabs_reader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */; }; - B88FB010116BDEA700407530 /* stabs_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3911666C6F00407530 /* stabs_reader.cc */; }; - B88FB028116BE03100407530 /* test_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE0911665B5700407530 /* test_assembler.cc */; }; - B88FB029116BE03100407530 /* gmock-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0EA311665AEA00DD08C9 /* gmock-all.cc */; }; - B88FB02A116BE03100407530 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E9F11665AC300DD08C9 /* gtest_main.cc */; }; - B88FB02B116BE03100407530 /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0EA011665AC300DD08C9 /* gtest-all.cc */; }; - B88FB03F116BE24200407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB042116BE3C400407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB057116C0CDE00407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB0BD116CEAE000407530 /* module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0B5116CEA8A00407530 /* module_unittest.cc */; }; - B88FB0C1116CEB0600407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB0C4116CEB4100407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B88FB0E3116CEEB000407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB0E5116CEED300407530 /* dwarf2diehandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1711665FE400407530 /* dwarf2diehandler.cc */; }; - B88FB0E6116CEED300407530 /* dwarf2diehandler_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */; }; - B88FB0F6116CEF2000407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB0FA116CF00E00407530 /* dwarf_line_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE201166603300407530 /* dwarf_line_to_module.cc */; }; - B88FB0FB116CF00E00407530 /* dwarf_line_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */; }; - B88FB0FE116CF02400407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B88FB10E116CF08100407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB112116CF1F000407530 /* dwarf_cu_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */; }; - B88FB113116CF1F000407530 /* dwarf_cu_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */; }; - B88FB114116CF1F000407530 /* language.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE221166603300407530 /* language.cc */; }; - B88FB115116CF1F000407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B88FB123116CF28500407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB129116CF2DD00407530 /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; }; - B88FB12A116CF2DD00407530 /* dwarf_cfi_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */; }; - B88FB12B116CF2DD00407530 /* dwarf_cfi_to_module_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */; }; - B88FB139116CF31600407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB13D116CF38300407530 /* cfi_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAF34116A595400407530 /* cfi_assembler.cc */; }; - B88FB13E116CF38300407530 /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; }; - B88FB13F116CF38300407530 /* bytereader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */; }; - B88FB14F116CF4AE00407530 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - B88FB152116CF4D300407530 /* byte_cursor_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */; }; - B89E0E781166576C00DD08C9 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; }; - B89E0E7A1166576C00DD08C9 /* macho_dump.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E701166573700DD08C9 /* macho_dump.cc */; }; - B89E0E9911665A7200DD08C9 /* macho_reader_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */; }; - B89E0E9A11665A7200DD08C9 /* macho_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = B89E0E6E1166571D00DD08C9 /* macho_reader.cc */; }; - B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */; }; - B8C5B5181166534700D34F4E /* bytereader.cc in Sources */ = {isa = PBXBuildFile; fileRef = F95B422C0E0E22D100DBDE83 /* bytereader.cc */; }; - B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */; }; - B8C5B51A1166534700D34F4E /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650410B52F6D800611104 /* file_id.cc */; }; - B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650430B52F6D800611104 /* macho_id.cc */; }; - B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650450B52F6D800611104 /* macho_walker.cc */; }; - B8C5B51D1166534700D34F4E /* dump_syms.cc in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* dump_syms.cc */; }; - B8C5B51E1166534700D34F4E /* dump_syms_tool.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */; }; - B8C5B523116653BA00D34F4E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; - D21F97D711CBA12300239E38 /* test_assembler_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */; }; - D21F97D811CBA13D00239E38 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; - D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE0911665B5700407530 /* test_assembler.cc */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 8B31051411F100CF00FCF3E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D21F97D111CBA0F200239E38; - remoteInfo = test_assembler_unittest; - }; - B84A91F9116CF796006C210E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B84A9200116CF7D2006C210E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B84A91F3116CF784006C210E; - remoteInfo = stabs_to_module_unittest; - }; - B88FAFCE116BDD7000407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B89E0E9411665A6400DD08C9; - remoteInfo = macho_reader_unittest; - }; - B88FAFD0116BDD7000407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FAF2E116A591D00407530; - remoteInfo = dwarf2reader_cfi_unittest; - }; - B88FB01C116BDF9800407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB006116BDE8300407530; - remoteInfo = stabs_reader_unittest; - }; - B88FB039116BE17E00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB087116CE6D800407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB08F116CE71000407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB0BF116CEAFE00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB0C7116CEB4A00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB0B8116CEABF00407530; - remoteInfo = module_unittest; - }; - B88FB0E7116CEEDA00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB0F7116CEF2E00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB10F116CF08A00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB124116CF29E00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB13B116CF35C00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB150116CF4C100407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB023116BDFFF00407530; - remoteInfo = gtestmockall; - }; - B88FB15A116CF53E00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB14A116CF4A700407530; - remoteInfo = byte_cursor_unittest; - }; - B88FB15C116CF54B00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB11E116CF27F00407530; - remoteInfo = dwarf_cfi_to_module_unittest; - }; - B88FB15E116CF54B00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB0F1116CEF1900407530; - remoteInfo = dwarf_line_to_module_unittest; - }; - B88FB160116CF54B00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB109116CF07900407530; - remoteInfo = dwarf_cu_to_module_unittest; - }; - B88FB164116CF54B00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB0DE116CEEA800407530; - remoteInfo = dwarf2diehandler_unittest; - }; - B88FB166116CF54B00407530 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B88FB134116CF30F00407530; - remoteInfo = bytereader_unittest; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 08FB7796FE84155DC02AAC07 /* dump_syms.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.cc; path = ../../../common/mac/dump_syms.cc; sourceTree = ""; }; - 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 162F64F8161C591500CD68D5 /* arch_utilities.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = arch_utilities.cc; path = ../../../common/mac/arch_utilities.cc; sourceTree = ""; }; - 162F64F9161C591500CD68D5 /* arch_utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arch_utilities.h; path = ../../../common/mac/arch_utilities.h; sourceTree = ""; }; - 4D72CAF413DFBAC2006CABE3 /* md5.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = md5.cc; path = ../../../common/md5.cc; sourceTree = SOURCE_ROOT; }; - 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_utilities.cc; path = ../../../common/mac/macho_utilities.cc; sourceTree = SOURCE_ROOT; }; - 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_utilities.h; path = ../../../common/mac/macho_utilities.h; sourceTree = SOURCE_ROOT; }; - 8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; - 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elf_reader.cc; path = ../../../common/dwarf/elf_reader.cc; sourceTree = ""; }; - 8BCAAA4B1CE3A7980046090B /* elf_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elf_reader.h; path = ../../../common/dwarf/elf_reader.h; sourceTree = ""; }; - 9BDF186D0B1BB43700F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = ""; }; - 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dump_syms_tool.cc; sourceTree = ""; }; - 9BE650410B52F6D800611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; }; - 9BE650420B52F6D800611104 /* file_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = file_id.h; path = ../../../common/mac/file_id.h; sourceTree = SOURCE_ROOT; }; - 9BE650430B52F6D800611104 /* macho_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_id.cc; path = ../../../common/mac/macho_id.cc; sourceTree = SOURCE_ROOT; }; - 9BE650440B52F6D800611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; }; - 9BE650450B52F6D800611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; }; - 9BE650460B52F6D800611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; }; - B84A91F4116CF784006C210E /* stabs_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stabs_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FAE0911665B5700407530 /* test_assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_assembler.cc; path = ../../../common/test_assembler.cc; sourceTree = SOURCE_ROOT; }; - B88FAE0A11665B5700407530 /* test_assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = test_assembler.h; path = ../../../common/test_assembler.h; sourceTree = SOURCE_ROOT; }; - B88FAE1711665FE400407530 /* dwarf2diehandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler.cc; path = ../../../common/dwarf/dwarf2diehandler.cc; sourceTree = SOURCE_ROOT; }; - B88FAE1811665FE400407530 /* dwarf2diehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2diehandler.h; path = ../../../common/dwarf/dwarf2diehandler.h; sourceTree = SOURCE_ROOT; }; - B88FAE1D1166603300407530 /* byte_cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byte_cursor.h; path = ../../../common/byte_cursor.h; sourceTree = SOURCE_ROOT; }; - B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module.cc; path = ../../../common/dwarf_cu_to_module.cc; sourceTree = SOURCE_ROOT; }; - B88FAE1F1166603300407530 /* dwarf_cu_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cu_to_module.h; path = ../../../common/dwarf_cu_to_module.h; sourceTree = SOURCE_ROOT; }; - B88FAE201166603300407530 /* dwarf_line_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module.cc; path = ../../../common/dwarf_line_to_module.cc; sourceTree = SOURCE_ROOT; }; - B88FAE211166603300407530 /* dwarf_line_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_line_to_module.h; path = ../../../common/dwarf_line_to_module.h; sourceTree = SOURCE_ROOT; }; - B88FAE221166603300407530 /* language.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = language.cc; path = ../../../common/language.cc; sourceTree = SOURCE_ROOT; }; - B88FAE231166603300407530 /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = language.h; path = ../../../common/language.h; sourceTree = SOURCE_ROOT; }; - B88FAE241166603300407530 /* module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module.cc; path = ../../../common/module.cc; sourceTree = SOURCE_ROOT; }; - B88FAE251166603300407530 /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = module.h; path = ../../../common/module.h; sourceTree = SOURCE_ROOT; }; - B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module.cc; path = ../../../common/dwarf_cfi_to_module.cc; sourceTree = SOURCE_ROOT; }; - B88FAE341166673E00407530 /* dwarf_cfi_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf_cfi_to_module.h; path = ../../../common/dwarf_cfi_to_module.h; sourceTree = SOURCE_ROOT; }; - B88FAE3911666C6F00407530 /* stabs_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader.cc; path = ../../../common/stabs_reader.cc; sourceTree = SOURCE_ROOT; }; - B88FAE3A11666C6F00407530 /* stabs_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_reader.h; path = ../../../common/stabs_reader.h; sourceTree = SOURCE_ROOT; }; - B88FAE3C11666C8900407530 /* stabs_to_module.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module.cc; path = ../../../common/stabs_to_module.cc; sourceTree = SOURCE_ROOT; }; - B88FAE3D11666C8900407530 /* stabs_to_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stabs_to_module.h; path = ../../../common/stabs_to_module.h; sourceTree = SOURCE_ROOT; }; - B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf2reader_cfi_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FAF34116A595400407530 /* cfi_assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cfi_assembler.cc; path = ../../../common/dwarf/cfi_assembler.cc; sourceTree = SOURCE_ROOT; }; - B88FAF35116A595400407530 /* cfi_assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cfi_assembler.h; path = ../../../common/dwarf/cfi_assembler.h; sourceTree = SOURCE_ROOT; }; - B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader_cfi_unittest.cc; path = ../../../common/dwarf/dwarf2reader_cfi_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_reader_unittest.cc; path = ../../../common/stabs_reader_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB007116BDE8300407530 /* stabs_reader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stabs_reader_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB024116BDFFF00407530 /* libgtestmockall.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtestmockall.a; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB0B5116CEA8A00407530 /* module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module_unittest.cc; path = ../../../common/module_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0B9116CEABF00407530 /* module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = module_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = byte_cursor_unittest.cc; path = ../../../common/byte_cursor_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cfi_to_module_unittest.cc; path = ../../../common/dwarf_cfi_to_module_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_cu_to_module_unittest.cc; path = ../../../common/dwarf_cu_to_module_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf_line_to_module_unittest.cc; path = ../../../common/dwarf_line_to_module_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stabs_to_module_unittest.cc; path = ../../../common/stabs_to_module_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_assembler_unittest.cc; path = ../../../common/test_assembler_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader_unittest.cc; path = ../../../common/dwarf/bytereader_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2diehandler_unittest.cc; path = ../../../common/dwarf/dwarf2diehandler_unittest.cc; sourceTree = SOURCE_ROOT; }; - B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf2diehandler_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_line_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_cu_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dwarf_cfi_to_module_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB135116CF30F00407530 /* bytereader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = bytereader_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B88FB14B116CF4A700407530 /* byte_cursor_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = byte_cursor_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader_unittest.cc; path = ../../../common/mac/macho_reader_unittest.cc; sourceTree = SOURCE_ROOT; }; - B89E0E6E1166571D00DD08C9 /* macho_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macho_reader.cc; path = ../../../common/mac/macho_reader.cc; sourceTree = SOURCE_ROOT; }; - B89E0E6F1166571D00DD08C9 /* macho_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macho_reader.h; path = ../../../common/mac/macho_reader.h; sourceTree = SOURCE_ROOT; }; - B89E0E701166573700DD08C9 /* macho_dump.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho_dump.cc; sourceTree = ""; }; - B89E0E741166575200DD08C9 /* macho_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_dump; sourceTree = BUILT_PRODUCTS_DIR; }; - B89E0E9511665A6400DD08C9 /* macho_reader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_reader_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 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; }; - 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; }; - 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; }; - B8C5B5111166531A00D34F4E /* dump_syms */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dump_syms; sourceTree = BUILT_PRODUCTS_DIR; }; - B8E8CA0C1156C854009E61B2 /* byteswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byteswap.h; path = ../../../common/mac/byteswap.h; sourceTree = SOURCE_ROOT; }; - D21F97D211CBA0F200239E38 /* test_assembler_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_assembler_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 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; }; - F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; - F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; }; - F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; }; - F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; - F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; }; - 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; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - B84A91F2116CF784006C210E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FAF2D116A591D00407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB042116BE3C400407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB005116BDE8300407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB03F116BE24200407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB022116BDFFF00407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0B7116CEABF00407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0C1116CEB0600407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0DD116CEEA800407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0E3116CEEB000407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0F0116CEF1900407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0F6116CEF2000407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB108116CF07900407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB10E116CF08100407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB11D116CF27F00407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB123116CF28500407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB133116CF30F00407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB139116CF31600407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB149116CF4A700407530 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB14F116CF4AE00407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B89E0E721166575200DD08C9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B89E0E9311665A6400DD08C9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB057116C0CDE00407530 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B8C5B50F1166531A00D34F4E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B8C5B523116653BA00D34F4E /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D21F97D011CBA0F200239E38 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D21F97D811CBA13D00239E38 /* libgtestmockall.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* dump_syms */ = { - isa = PBXGroup; - children = ( - 8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */, - 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */, - 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */, - B89E0E9D11665A9500DD08C9 /* TESTING */, - F9F5344B0E7C8FFC0012363F /* DWARF */, - B89E0E6C1166569700DD08C9 /* MACHO */, - B88FAE3811666A1700407530 /* STABS */, - B88FAE1C11665FFD00407530 /* MODULE */, - 162F64F8161C591500CD68D5 /* arch_utilities.cc */, - 162F64F9161C591500CD68D5 /* arch_utilities.h */, - B88FAE1D1166603300407530 /* byte_cursor.h */, - B88FB0D4116CEC0600407530 /* byte_cursor_unittest.cc */, - B8E8CA0C1156C854009E61B2 /* byteswap.h */, - 9BE650410B52F6D800611104 /* file_id.cc */, - 9BE650420B52F6D800611104 /* file_id.h */, - 9BDF186D0B1BB43700F8391B /* dump_syms.h */, - 08FB7796FE84155DC02AAC07 /* dump_syms.cc */, - 9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */, - B89E0E701166573700DD08C9 /* macho_dump.cc */, - 4D72CAF413DFBAC2006CABE3 /* md5.cc */, - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = dump_syms; - sourceTree = ""; - }; - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 08FB779EFE84155DC02AAC07 /* Foundation.framework */, - ); - name = "External Frameworks and Libraries"; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - B8C5B5111166531A00D34F4E /* dump_syms */, - B89E0E741166575200DD08C9 /* macho_dump */, - B89E0E9511665A6400DD08C9 /* macho_reader_unittest */, - B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */, - B88FB007116BDE8300407530 /* stabs_reader_unittest */, - B88FB024116BDFFF00407530 /* libgtestmockall.a */, - B88FB0B9116CEABF00407530 /* module_unittest */, - B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */, - B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */, - B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */, - B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */, - B88FB135116CF30F00407530 /* bytereader_unittest */, - B88FB14B116CF4A700407530 /* byte_cursor_unittest */, - B84A91F4116CF784006C210E /* stabs_to_module_unittest */, - D21F97D211CBA0F200239E38 /* test_assembler_unittest */, - ); - name = Products; - sourceTree = ""; - }; - B88FAE1C11665FFD00407530 /* MODULE */ = { - isa = PBXGroup; - children = ( - B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */, - B88FAE1F1166603300407530 /* dwarf_cu_to_module.h */, - B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */, - B88FAE201166603300407530 /* dwarf_line_to_module.cc */, - B88FAE211166603300407530 /* dwarf_line_to_module.h */, - B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */, - B88FAE221166603300407530 /* language.cc */, - B88FAE231166603300407530 /* language.h */, - B88FAE241166603300407530 /* module.cc */, - B88FAE251166603300407530 /* module.h */, - B88FB0B5116CEA8A00407530 /* module_unittest.cc */, - B88FAE331166673E00407530 /* dwarf_cfi_to_module.cc */, - B88FAE341166673E00407530 /* dwarf_cfi_to_module.h */, - B88FB0D5116CEC0600407530 /* dwarf_cfi_to_module_unittest.cc */, - B88FAE3C11666C8900407530 /* stabs_to_module.cc */, - B88FAE3D11666C8900407530 /* stabs_to_module.h */, - B88FB0D8116CEC0600407530 /* stabs_to_module_unittest.cc */, - ); - name = MODULE; - sourceTree = ""; - }; - B88FAE3811666A1700407530 /* STABS */ = { - isa = PBXGroup; - children = ( - B88FB003116BDE7200407530 /* stabs_reader_unittest.cc */, - B88FAE3911666C6F00407530 /* stabs_reader.cc */, - B88FAE3A11666C6F00407530 /* stabs_reader.h */, - ); - name = STABS; - sourceTree = ""; - }; - B89E0E6C1166569700DD08C9 /* MACHO */ = { - isa = PBXGroup; - children = ( - B89E0E6D1166571D00DD08C9 /* macho_reader_unittest.cc */, - B89E0E6E1166571D00DD08C9 /* macho_reader.cc */, - B89E0E6F1166571D00DD08C9 /* macho_reader.h */, - 557800890BE1F3AB00EC23E0 /* macho_utilities.cc */, - 5578008A0BE1F3AB00EC23E0 /* macho_utilities.h */, - 9BE650430B52F6D800611104 /* macho_id.cc */, - 9BE650440B52F6D800611104 /* macho_id.h */, - 9BE650450B52F6D800611104 /* macho_walker.cc */, - 9BE650460B52F6D800611104 /* macho_walker.h */, - ); - name = MACHO; - sourceTree = ""; - }; - B89E0E9D11665A9500DD08C9 /* TESTING */ = { - isa = PBXGroup; - children = ( - B88FAE0911665B5700407530 /* test_assembler.cc */, - B88FAE0A11665B5700407530 /* test_assembler.h */, - B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */, - B89E0EA311665AEA00DD08C9 /* gmock-all.cc */, - B89E0E9F11665AC300DD08C9 /* gtest_main.cc */, - B89E0EA011665AC300DD08C9 /* gtest-all.cc */, - ); - name = TESTING; - sourceTree = ""; - }; - F9F5344B0E7C8FFC0012363F /* DWARF */ = { - isa = PBXGroup; - children = ( - B88FAF34116A595400407530 /* cfi_assembler.cc */, - B88FAF35116A595400407530 /* cfi_assembler.h */, - F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */, - F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */, - F95B42300E0E22D100DBDE83 /* dwarf2reader.h */, - B88FAF36116A595400407530 /* dwarf2reader_cfi_unittest.cc */, - F95B422D0E0E22D100DBDE83 /* bytereader.h */, - F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */, - F95B422C0E0E22D100DBDE83 /* bytereader.cc */, - B88FB0DA116CEC5800407530 /* bytereader_unittest.cc */, - F95B42310E0E22D100DBDE83 /* line_state_machine.h */, - B88FAE1711665FE400407530 /* dwarf2diehandler.cc */, - B88FAE1811665FE400407530 /* dwarf2diehandler.h */, - B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */, - 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */, - 8BCAAA4B1CE3A7980046090B /* elf_reader.h */, - ); - name = DWARF; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - B88FB020116BDFFF00407530 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - B84A91F3116CF784006C210E /* stabs_to_module_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B84A9202116CF7F0006C210E /* Build configuration list for PBXNativeTarget "stabs_to_module_unittest" */; - buildPhases = ( - B84A91F1116CF784006C210E /* Sources */, - B84A91F2116CF784006C210E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B84A91FA116CF796006C210E /* PBXTargetDependency */, - ); - name = stabs_to_module_unittest; - productName = stabs_to_module_unittest; - productReference = B84A91F4116CF784006C210E /* stabs_to_module_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FAF33116A594800407530 /* Build configuration list for PBXNativeTarget "dwarf2reader_cfi_unittest" */; - buildPhases = ( - B88FAF2C116A591D00407530 /* Sources */, - B88FAF2D116A591D00407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB03A116BE17E00407530 /* PBXTargetDependency */, - ); - name = dwarf2reader_cfi_unittest; - productName = dwarf2reader_cfi_unittest; - productReference = B88FAF2F116A591E00407530 /* dwarf2reader_cfi_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB006116BDE8300407530 /* stabs_reader_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB013116BDEC800407530 /* Build configuration list for PBXNativeTarget "stabs_reader_unittest" */; - buildPhases = ( - B88FB004116BDE8300407530 /* Sources */, - B88FB005116BDE8300407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB088116CE6D800407530 /* PBXTargetDependency */, - ); - name = stabs_reader_unittest; - productName = stabs_reader_unittest; - productReference = B88FB007116BDE8300407530 /* stabs_reader_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB023116BDFFF00407530 /* gtestmockall */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB027116BE02900407530 /* Build configuration list for PBXNativeTarget "gtestmockall" */; - buildPhases = ( - B88FB020116BDFFF00407530 /* Headers */, - B88FB021116BDFFF00407530 /* Sources */, - B88FB022116BDFFF00407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = gtestmockall; - productName = gtestmockall; - productReference = B88FB024116BDFFF00407530 /* libgtestmockall.a */; - productType = "com.apple.product-type.library.static"; - }; - B88FB0B8116CEABF00407530 /* module_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB0BE116CEAFE00407530 /* Build configuration list for PBXNativeTarget "module_unittest" */; - buildPhases = ( - B88FB0B6116CEABF00407530 /* Sources */, - B88FB0B7116CEABF00407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB0C0116CEAFE00407530 /* PBXTargetDependency */, - ); - name = module_unittest; - productName = module_unittest; - productReference = B88FB0B9116CEABF00407530 /* module_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB0E4116CEECE00407530 /* Build configuration list for PBXNativeTarget "dwarf2diehandler_unittest" */; - buildPhases = ( - B88FB0DC116CEEA800407530 /* Sources */, - B88FB0DD116CEEA800407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB0E8116CEEDA00407530 /* PBXTargetDependency */, - ); - name = dwarf2diehandler_unittest; - productName = dwarf2diehandler_unittest; - productReference = B88FB0DF116CEEA800407530 /* dwarf2diehandler_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB0F9116CEF9800407530 /* Build configuration list for PBXNativeTarget "dwarf_line_to_module_unittest" */; - buildPhases = ( - B88FB0EF116CEF1900407530 /* Sources */, - B88FB0F0116CEF1900407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB0F8116CEF2E00407530 /* PBXTargetDependency */, - ); - name = dwarf_line_to_module_unittest; - productName = dwarf_line_to_module_unittest; - productReference = B88FB0F2116CEF1900407530 /* dwarf_line_to_module_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB111116CF0A800407530 /* Build configuration list for PBXNativeTarget "dwarf_cu_to_module_unittest" */; - buildPhases = ( - B88FB107116CF07900407530 /* Sources */, - B88FB108116CF07900407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB110116CF08A00407530 /* PBXTargetDependency */, - ); - name = dwarf_cu_to_module_unittest; - productName = dwarf_cu_to_module_unittest; - productReference = B88FB10A116CF07900407530 /* dwarf_cu_to_module_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB128116CF2C800407530 /* Build configuration list for PBXNativeTarget "dwarf_cfi_to_module_unittest" */; - buildPhases = ( - B88FB11C116CF27F00407530 /* Sources */, - B88FB11D116CF27F00407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB125116CF29E00407530 /* PBXTargetDependency */, - ); - name = dwarf_cfi_to_module_unittest; - productName = dwarf_cfi_to_module_unittest; - productReference = B88FB11F116CF27F00407530 /* dwarf_cfi_to_module_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB134116CF30F00407530 /* bytereader_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB13A116CF33400407530 /* Build configuration list for PBXNativeTarget "bytereader_unittest" */; - buildPhases = ( - B88FB132116CF30F00407530 /* Sources */, - B88FB133116CF30F00407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB13C116CF35C00407530 /* PBXTargetDependency */, - ); - name = bytereader_unittest; - productName = bytereader_unittest; - productReference = B88FB135116CF30F00407530 /* bytereader_unittest */; - productType = "com.apple.product-type.tool"; - }; - B88FB14A116CF4A700407530 /* byte_cursor_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B88FB159116CF4F900407530 /* Build configuration list for PBXNativeTarget "byte_cursor_unittest" */; - buildPhases = ( - B88FB148116CF4A700407530 /* Sources */, - B88FB149116CF4A700407530 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB151116CF4C100407530 /* PBXTargetDependency */, - ); - name = byte_cursor_unittest; - productName = byte_cursor_unittest; - productReference = B88FB14B116CF4A700407530 /* byte_cursor_unittest */; - productType = "com.apple.product-type.tool"; - }; - B89E0E731166575200DD08C9 /* macho_dump */ = { - isa = PBXNativeTarget; - buildConfigurationList = B89E0E7F116657A100DD08C9 /* Build configuration list for PBXNativeTarget "macho_dump" */; - buildPhases = ( - B89E0E711166575200DD08C9 /* Sources */, - B89E0E721166575200DD08C9 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = macho_dump; - productName = macho_dump; - productReference = B89E0E741166575200DD08C9 /* macho_dump */; - productType = "com.apple.product-type.tool"; - }; - B89E0E9411665A6400DD08C9 /* macho_reader_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = B89E0E9E11665A9600DD08C9 /* Build configuration list for PBXNativeTarget "macho_reader_unittest" */; - buildPhases = ( - B89E0E9211665A6400DD08C9 /* Sources */, - B89E0E9311665A6400DD08C9 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - B88FB090116CE71000407530 /* PBXTargetDependency */, - ); - name = macho_reader_unittest; - productName = macho_reader_unittest; - productReference = B89E0E9511665A6400DD08C9 /* macho_reader_unittest */; - productType = "com.apple.product-type.tool"; - }; - B8C5B5101166531A00D34F4E /* dump_syms */ = { - isa = PBXNativeTarget; - buildConfigurationList = B8C5B5151166533900D34F4E /* Build configuration list for PBXNativeTarget "dump_syms" */; - buildPhases = ( - B8C5B50E1166531A00D34F4E /* Sources */, - B8C5B50F1166531A00D34F4E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = dump_syms; - productName = dump_syms; - productReference = B8C5B5111166531A00D34F4E /* dump_syms */; - productType = "com.apple.product-type.tool"; - }; - D21F97D111CBA0F200239E38 /* test_assembler_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = D21F97D611CBA11000239E38 /* Build configuration list for PBXNativeTarget "test_assembler_unittest" */; - buildPhases = ( - D21F97CF11CBA0F200239E38 /* Sources */, - D21F97D011CBA0F200239E38 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = test_assembler_unittest; - productName = test_assembler_unittest; - productReference = D21F97D211CBA0F200239E38 /* test_assembler_unittest */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - }; - buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */; - compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* dump_syms */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - B8C5B5101166531A00D34F4E /* dump_syms */, - B89E0E731166575200DD08C9 /* macho_dump */, - B88FB023116BDFFF00407530 /* gtestmockall */, - B88FB14A116CF4A700407530 /* byte_cursor_unittest */, - B89E0E9411665A6400DD08C9 /* macho_reader_unittest */, - B88FB006116BDE8300407530 /* stabs_reader_unittest */, - B88FB134116CF30F00407530 /* bytereader_unittest */, - B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */, - B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */, - B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */, - B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */, - B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */, - B84A91F3116CF784006C210E /* stabs_to_module_unittest */, - B88FB0B8116CEABF00407530 /* module_unittest */, - B88FAFC9116BDCAD00407530 /* all_unittests */, - D21F97D111CBA0F200239E38 /* test_assembler_unittest */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXShellScriptBuildPhase section */ - B88FB094116CE73E00407530 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -eu\n\ncd $BUILT_PRODUCTS_DIR\npwd\n\n./byte_cursor_unittest\n./macho_reader_unittest\n./stabs_reader_unittest\n./bytereader_unittest\n./dwarf2reader_cfi_unittest\n./dwarf2diehandler_unittest\n./dwarf_cu_to_module_unittest\n./dwarf_line_to_module_unittest\n./dwarf_cfi_to_module_unittest\n./stabs_to_module_unittest\n./module_unittest\n./test_assembler_unittest\n\necho \"Expect two warnings from the following tests:\"\necho \" Errors.BadFileNumber\"\necho \" Errors.BadDirectoryNumber\"\necho \"The proper behavior of these tests is to print text that XCode confuses with compiler warnings.\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - B84A91F1116CF784006C210E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B84A91FB116CF7AF006C210E /* module.cc in Sources */, - B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */, - B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FAF2C116A591D00407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FAF38116A595400407530 /* dwarf2reader_cfi_unittest.cc in Sources */, - B88FAF3F116A5A2E00407530 /* dwarf2reader.cc in Sources */, - 8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */, - B88FAF40116A5A2E00407530 /* bytereader.cc in Sources */, - B88FAF37116A595400407530 /* cfi_assembler.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB004116BDE8300407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB00F116BDEA700407530 /* stabs_reader_unittest.cc in Sources */, - B88FB010116BDEA700407530 /* stabs_reader.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB021116BDFFF00407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB028116BE03100407530 /* test_assembler.cc in Sources */, - B88FB029116BE03100407530 /* gmock-all.cc in Sources */, - B88FB02A116BE03100407530 /* gtest_main.cc in Sources */, - B88FB02B116BE03100407530 /* gtest-all.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0B6116CEABF00407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0BD116CEAE000407530 /* module_unittest.cc in Sources */, - B88FB0C4116CEB4100407530 /* module.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0DC116CEEA800407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0E5116CEED300407530 /* dwarf2diehandler.cc in Sources */, - B88FB0E6116CEED300407530 /* dwarf2diehandler_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB0EF116CEF1900407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB0FA116CF00E00407530 /* dwarf_line_to_module.cc in Sources */, - B88FB0FE116CF02400407530 /* module.cc in Sources */, - B88FB0FB116CF00E00407530 /* dwarf_line_to_module_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB107116CF07900407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB112116CF1F000407530 /* dwarf_cu_to_module.cc in Sources */, - B88FB113116CF1F000407530 /* dwarf_cu_to_module_unittest.cc in Sources */, - B88FB114116CF1F000407530 /* language.cc in Sources */, - B88FB115116CF1F000407530 /* module.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB11C116CF27F00407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB129116CF2DD00407530 /* module.cc in Sources */, - B88FB12A116CF2DD00407530 /* dwarf_cfi_to_module.cc in Sources */, - B88FB12B116CF2DD00407530 /* dwarf_cfi_to_module_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB132116CF30F00407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB13D116CF38300407530 /* cfi_assembler.cc in Sources */, - B88FB13E116CF38300407530 /* bytereader.cc in Sources */, - B88FB13F116CF38300407530 /* bytereader_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B88FB148116CF4A700407530 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B88FB152116CF4D300407530 /* byte_cursor_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B89E0E711166575200DD08C9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */, - B89E0E781166576C00DD08C9 /* macho_reader.cc in Sources */, - B89E0E7A1166576C00DD08C9 /* macho_dump.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B89E0E9211665A6400DD08C9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B89E0E9911665A7200DD08C9 /* macho_reader_unittest.cc in Sources */, - B89E0E9A11665A7200DD08C9 /* macho_reader.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B8C5B50E1166531A00D34F4E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */, - B88FAE2C1166606200407530 /* macho_reader.cc in Sources */, - 8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */, - B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */, - B8C5B5181166534700D34F4E /* bytereader.cc in Sources */, - B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */, - B8C5B51A1166534700D34F4E /* file_id.cc in Sources */, - B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */, - B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */, - B8C5B51D1166534700D34F4E /* dump_syms.cc in Sources */, - B8C5B51E1166534700D34F4E /* dump_syms_tool.cc in Sources */, - B88FAE1911665FE400407530 /* dwarf2diehandler.cc in Sources */, - B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */, - B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */, - B88FAE281166603300407530 /* language.cc in Sources */, - B88FAE291166603300407530 /* module.cc in Sources */, - B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */, - B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */, - B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */, - 4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D21F97CF11CBA0F200239E38 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */, - D21F97D711CBA12300239E38 /* test_assembler_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 8B31051511F100CF00FCF3E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D21F97D111CBA0F200239E38 /* test_assembler_unittest */; - targetProxy = 8B31051411F100CF00FCF3E4 /* PBXContainerItemProxy */; - }; - B84A91FA116CF796006C210E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B84A91F9116CF796006C210E /* PBXContainerItemProxy */; - }; - B84A9201116CF7D2006C210E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B84A91F3116CF784006C210E /* stabs_to_module_unittest */; - targetProxy = B84A9200116CF7D2006C210E /* PBXContainerItemProxy */; - }; - B88FAFCF116BDD7000407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B89E0E9411665A6400DD08C9 /* macho_reader_unittest */; - targetProxy = B88FAFCE116BDD7000407530 /* PBXContainerItemProxy */; - }; - B88FAFD1116BDD7000407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FAF2E116A591D00407530 /* dwarf2reader_cfi_unittest */; - targetProxy = B88FAFD0116BDD7000407530 /* PBXContainerItemProxy */; - }; - B88FB01D116BDF9800407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB006116BDE8300407530 /* stabs_reader_unittest */; - targetProxy = B88FB01C116BDF9800407530 /* PBXContainerItemProxy */; - }; - B88FB03A116BE17E00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB039116BE17E00407530 /* PBXContainerItemProxy */; - }; - B88FB088116CE6D800407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB087116CE6D800407530 /* PBXContainerItemProxy */; - }; - B88FB090116CE71000407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB08F116CE71000407530 /* PBXContainerItemProxy */; - }; - B88FB0C0116CEAFE00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB0BF116CEAFE00407530 /* PBXContainerItemProxy */; - }; - B88FB0C8116CEB4A00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB0B8116CEABF00407530 /* module_unittest */; - targetProxy = B88FB0C7116CEB4A00407530 /* PBXContainerItemProxy */; - }; - B88FB0E8116CEEDA00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB0E7116CEEDA00407530 /* PBXContainerItemProxy */; - }; - B88FB0F8116CEF2E00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB0F7116CEF2E00407530 /* PBXContainerItemProxy */; - }; - B88FB110116CF08A00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB10F116CF08A00407530 /* PBXContainerItemProxy */; - }; - B88FB125116CF29E00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB124116CF29E00407530 /* PBXContainerItemProxy */; - }; - B88FB13C116CF35C00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB13B116CF35C00407530 /* PBXContainerItemProxy */; - }; - B88FB151116CF4C100407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB023116BDFFF00407530 /* gtestmockall */; - targetProxy = B88FB150116CF4C100407530 /* PBXContainerItemProxy */; - }; - B88FB15B116CF53E00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB14A116CF4A700407530 /* byte_cursor_unittest */; - targetProxy = B88FB15A116CF53E00407530 /* PBXContainerItemProxy */; - }; - B88FB15D116CF54B00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB11E116CF27F00407530 /* dwarf_cfi_to_module_unittest */; - targetProxy = B88FB15C116CF54B00407530 /* PBXContainerItemProxy */; - }; - B88FB15F116CF54B00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB0F1116CEF1900407530 /* dwarf_line_to_module_unittest */; - targetProxy = B88FB15E116CF54B00407530 /* PBXContainerItemProxy */; - }; - B88FB161116CF54B00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB109116CF07900407530 /* dwarf_cu_to_module_unittest */; - targetProxy = B88FB160116CF54B00407530 /* PBXContainerItemProxy */; - }; - B88FB165116CF54B00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB0DE116CEEA800407530 /* dwarf2diehandler_unittest */; - targetProxy = B88FB164116CF54B00407530 /* PBXContainerItemProxy */; - }; - B88FB167116CF54B00407530 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B88FB134116CF30F00407530 /* bytereader_unittest */; - targetProxy = B88FB166116CF54B00407530 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 1DEB927908733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../../.., - ../../../common/mac/include/, - ../../../third_party/musl/include/, - ); - }; - name = Debug; - }; - 1DEB927A08733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */; - buildSettings = { - HEADER_SEARCH_PATHS = ( - ../../.., - ../../../common/mac/include/, - ../../../third_party/musl/include/, - ); - }; - name = Release; - }; - B84A91F6116CF784006C210E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = stabs_to_module_unittest; - }; - name = Debug; - }; - B84A91F7116CF784006C210E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = stabs_to_module_unittest; - }; - name = Release; - }; - B88FAF31116A591F00407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - ); - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - PRODUCT_NAME = dwarf2reader_cfi_unittest; - }; - name = Debug; - }; - B88FAF32116A591F00407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - ); - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - PRODUCT_NAME = dwarf2reader_cfi_unittest; - }; - name = Release; - }; - B88FAFCA116BDCAD00407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = all_unittests; - }; - name = Debug; - }; - B88FAFCB116BDCAD00407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = all_unittests; - }; - name = Release; - }; - B88FB009116BDE8400407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = stabs_reader_unittest; - }; - name = Debug; - }; - B88FB00A116BDE8400407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = stabs_reader_unittest; - }; - name = Release; - }; - B88FB025116BE00100407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = gtestmockall; - }; - name = Debug; - }; - B88FB026116BE00100407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = gtestmockall; - }; - name = Release; - }; - B88FB0BB116CEAC000407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = module_unittest; - }; - name = Debug; - }; - B88FB0BC116CEAC000407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = module_unittest; - }; - name = Release; - }; - B88FB0E1116CEEA800407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf2diehandler_unittest; - }; - name = Debug; - }; - B88FB0E2116CEEA800407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf2diehandler_unittest; - }; - name = Release; - }; - B88FB0F4116CEF1900407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_line_to_module_unittest; - }; - name = Debug; - }; - B88FB0F5116CEF1900407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_line_to_module_unittest; - }; - name = Release; - }; - B88FB10C116CF07A00407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_cu_to_module_unittest; - }; - name = Debug; - }; - B88FB10D116CF07A00407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_cu_to_module_unittest; - }; - name = Release; - }; - B88FB121116CF28000407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_cfi_to_module_unittest; - }; - name = Debug; - }; - B88FB122116CF28000407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = dwarf_cfi_to_module_unittest; - }; - name = Release; - }; - B88FB137116CF30F00407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = bytereader_unittest; - }; - name = Debug; - }; - B88FB138116CF30F00407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = bytereader_unittest; - }; - name = Release; - }; - B88FB14D116CF4A800407530 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = byte_cursor_unittest; - }; - name = Debug; - }; - B88FB14E116CF4A800407530 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = byte_cursor_unittest; - }; - name = Release; - }; - B89E0E761166575300DD08C9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = macho_dump; - }; - name = Debug; - }; - B89E0E771166575300DD08C9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = macho_dump; - }; - name = Release; - }; - B89E0E9711665A6400DD08C9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = macho_reader_unittest; - }; - name = Debug; - }; - B89E0E9811665A6400DD08C9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = macho_reader_unittest; - }; - name = Release; - }; - B8C5B5131166531B00D34F4E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - GCC_VERSION = ""; - PRODUCT_NAME = dump_syms; - }; - name = Debug; - }; - B8C5B5141166531B00D34F4E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H; - GCC_VERSION = ""; - PRODUCT_NAME = dump_syms; - }; - name = Release; - }; - D21F97D411CBA0F200239E38 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = test_assembler_unittest; - }; - name = Debug; - }; - D21F97D511CBA0F200239E38 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - $inherited, - ../../../testing, - ../../../testing/include, - ../../../testing/gtest, - ../../../testing/gtest/include, - ); - PRODUCT_NAME = test_assembler_unittest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927908733DD40010E9CD /* Debug */, - 1DEB927A08733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B84A9202116CF7F0006C210E /* Build configuration list for PBXNativeTarget "stabs_to_module_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B84A91F6116CF784006C210E /* Debug */, - B84A91F7116CF784006C210E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FAF33116A594800407530 /* Build configuration list for PBXNativeTarget "dwarf2reader_cfi_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FAF31116A591F00407530 /* Debug */, - B88FAF32116A591F00407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FAFCC116BDCCC00407530 /* Build configuration list for PBXAggregateTarget "all_unittests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FAFCA116BDCAD00407530 /* Debug */, - B88FAFCB116BDCAD00407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB013116BDEC800407530 /* Build configuration list for PBXNativeTarget "stabs_reader_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB009116BDE8400407530 /* Debug */, - B88FB00A116BDE8400407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB027116BE02900407530 /* Build configuration list for PBXNativeTarget "gtestmockall" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB025116BE00100407530 /* Debug */, - B88FB026116BE00100407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB0BE116CEAFE00407530 /* Build configuration list for PBXNativeTarget "module_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB0BB116CEAC000407530 /* Debug */, - B88FB0BC116CEAC000407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB0E4116CEECE00407530 /* Build configuration list for PBXNativeTarget "dwarf2diehandler_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB0E1116CEEA800407530 /* Debug */, - B88FB0E2116CEEA800407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB0F9116CEF9800407530 /* Build configuration list for PBXNativeTarget "dwarf_line_to_module_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB0F4116CEF1900407530 /* Debug */, - B88FB0F5116CEF1900407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB111116CF0A800407530 /* Build configuration list for PBXNativeTarget "dwarf_cu_to_module_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB10C116CF07A00407530 /* Debug */, - B88FB10D116CF07A00407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB128116CF2C800407530 /* Build configuration list for PBXNativeTarget "dwarf_cfi_to_module_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB121116CF28000407530 /* Debug */, - B88FB122116CF28000407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB13A116CF33400407530 /* Build configuration list for PBXNativeTarget "bytereader_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB137116CF30F00407530 /* Debug */, - B88FB138116CF30F00407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B88FB159116CF4F900407530 /* Build configuration list for PBXNativeTarget "byte_cursor_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B88FB14D116CF4A800407530 /* Debug */, - B88FB14E116CF4A800407530 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B89E0E7F116657A100DD08C9 /* Build configuration list for PBXNativeTarget "macho_dump" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B89E0E761166575300DD08C9 /* Debug */, - B89E0E771166575300DD08C9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B89E0E9E11665A9600DD08C9 /* Build configuration list for PBXNativeTarget "macho_reader_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B89E0E9711665A6400DD08C9 /* Debug */, - B89E0E9811665A6400DD08C9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B8C5B5151166533900D34F4E /* Build configuration list for PBXNativeTarget "dump_syms" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B8C5B5131166531B00D34F4E /* Debug */, - B8C5B5141166531B00D34F4E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D21F97D611CBA11000239E38 /* Build configuration list for PBXNativeTarget "test_assembler_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D21F97D411CBA0F200239E38 /* Debug */, - D21F97D511CBA0F200239E38 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc deleted file mode 100644 index 6f68457b4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms_tool.cc +++ /dev/null @@ -1,264 +0,0 @@ -// -*- mode: c++ -*- - -// Copyright (c) 2011, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// dump_syms_tool.cc: Command line tool that uses the DumpSymbols class. -// TODO(waylonis): accept stdin - -#include -#include - -#include -#include -#include - -#include "common/mac/dump_syms.h" -#include "common/mac/arch_utilities.h" -#include "common/mac/macho_utilities.h" -#include "common/scoped_ptr.h" - -using google_breakpad::DumpSymbols; -using google_breakpad::Module; -using google_breakpad::scoped_ptr; -using std::vector; - -struct Options { - Options() - : srcPath(), dsymPath(), arch(), header_only(false), - cfi(true), handle_inter_cu_refs(true) {} - - string srcPath; - string dsymPath; - const NXArchInfo *arch; - bool header_only; - bool cfi; - bool handle_inter_cu_refs; -}; - -static bool StackFrameEntryComparator(const Module::StackFrameEntry* a, - const Module::StackFrameEntry* b) { - return a->address < b->address; -} - -// Copy the CFI data from |from_module| into |to_module|, for any non- -// overlapping ranges. -static void CopyCFIDataBetweenModules(Module* to_module, - const Module* from_module) { - typedef vector::const_iterator Iterator; - - // Get the CFI data from both the source and destination modules and ensure - // it is sorted by start address. - vector from_data; - from_module->GetStackFrameEntries(&from_data); - std::sort(from_data.begin(), from_data.end(), &StackFrameEntryComparator); - - vector to_data; - to_module->GetStackFrameEntries(&to_data); - std::sort(to_data.begin(), to_data.end(), &StackFrameEntryComparator); - - Iterator to_it = to_data.begin(); - - for (Iterator it = from_data.begin(); it != from_data.end(); ++it) { - Module::StackFrameEntry* from_entry = *it; - Module::Address from_entry_end = from_entry->address + from_entry->size; - - // Find the first CFI record in the |to_module| that does not have an - // address less than the entry to be copied. - while (to_it != to_data.end()) { - if (from_entry->address > (*to_it)->address) - ++to_it; - else - break; - } - - // If the entry does not overlap, then it is safe to copy to |to_module|. - if (to_it == to_data.end() || (from_entry->address < (*to_it)->address && - from_entry_end < (*to_it)->address)) { - to_module->AddStackFrameEntry(new Module::StackFrameEntry(*from_entry)); - } - } -} - -static bool Start(const Options &options) { - SymbolData symbol_data = options.cfi ? ALL_SYMBOL_DATA : NO_CFI; - DumpSymbols dump_symbols(symbol_data, options.handle_inter_cu_refs); - - // For x86_64 binaries, the CFI data is in the __TEXT,__eh_frame of the - // Mach-O file, which is not copied into the dSYM. Whereas in i386, the CFI - // data is in the __DWARF,__debug_frame section, which is moved into the - // dSYM. Therefore, to get x86_64 CFI data, dump_syms needs to look at both - // the dSYM and the Mach-O file. If both paths are present and CFI was - // requested, then consider the Module as "split" and dump all the debug data - // from the primary debug info file, the dSYM, and then dump additional CFI - // data from the source Mach-O file. - bool split_module = - !options.dsymPath.empty() && !options.srcPath.empty() && options.cfi; - const string& primary_file = - split_module ? options.dsymPath : options.srcPath; - - if (!dump_symbols.Read(primary_file)) - return false; - - if (options.arch) { - if (!dump_symbols.SetArchitecture(options.arch->cputype, - options.arch->cpusubtype)) { - fprintf(stderr, "%s: no architecture '%s' is present in file.\n", - primary_file.c_str(), options.arch->name); - size_t available_size; - const SuperFatArch *available = - dump_symbols.AvailableArchitectures(&available_size); - if (available_size == 1) - fprintf(stderr, "the file's architecture is: "); - else - fprintf(stderr, "architectures present in the file are:\n"); - for (size_t i = 0; i < available_size; i++) { - const SuperFatArch *arch = &available[i]; - const NXArchInfo *arch_info = - google_breakpad::BreakpadGetArchInfoFromCpuType( - arch->cputype, arch->cpusubtype); - if (arch_info) - fprintf(stderr, "%s (%s)\n", arch_info->name, arch_info->description); - else - fprintf(stderr, "unrecognized cpu type 0x%x, subtype 0x%x\n", - arch->cputype, arch->cpusubtype); - } - return false; - } - } - - if (options.header_only) - return dump_symbols.WriteSymbolFileHeader(std::cout); - - // Read the primary file into a Breakpad Module. - Module* module = NULL; - if (!dump_symbols.ReadSymbolData(&module)) - return false; - scoped_ptr scoped_module(module); - - // If this is a split module, read the secondary Mach-O file, from which the - // CFI data will be extracted. - if (split_module && primary_file == options.dsymPath) { - if (!dump_symbols.Read(options.srcPath)) - return false; - - Module* cfi_module = NULL; - if (!dump_symbols.ReadSymbolData(&cfi_module)) - return false; - scoped_ptr scoped_cfi_module(cfi_module); - - // Ensure that the modules are for the same debug code file. - if (cfi_module->name() != module->name() || - cfi_module->os() != module->os() || - cfi_module->architecture() != module->architecture() || - cfi_module->identifier() != module->identifier()) { - fprintf(stderr, "Cannot generate a symbol file from split sources that do" - " not match.\n"); - return false; - } - - CopyCFIDataBetweenModules(module, cfi_module); - } - - return module->Write(std::cout, symbol_data); -} - -//============================================================================= -static void Usage(int argc, const char *argv[]) { - fprintf(stderr, "Output a Breakpad symbol file from a Mach-o file.\n"); - fprintf(stderr, "Usage: %s [-a ARCHITECTURE] [-c] [-g dSYM path] " - "\n", argv[0]); - fprintf(stderr, "\t-i: Output module header information only.\n"); - fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n"); - fprintf(stderr, "\t in the file, if it contains only one architecture]\n"); - fprintf(stderr, "\t-g: Debug symbol file (dSYM) to dump in addition to the " - "Mach-o file\n"); - fprintf(stderr, "\t-c: Do not generate CFI section\n"); - fprintf(stderr, "\t-r: Do not handle inter-compilation unit references\n"); - fprintf(stderr, "\t-h: Usage\n"); - fprintf(stderr, "\t-?: Usage\n"); -} - -//============================================================================= -static void SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - signed char ch; - - while ((ch = getopt(argc, (char * const *)argv, "ia:g:chr?")) != -1) { - switch (ch) { - case 'i': - options->header_only = true; - break; - case 'a': { - const NXArchInfo *arch_info = - google_breakpad::BreakpadGetArchInfoFromName(optarg); - if (!arch_info) { - fprintf(stderr, "%s: Invalid architecture: %s\n", argv[0], optarg); - Usage(argc, argv); - exit(1); - } - options->arch = arch_info; - break; - } - case 'g': - options->dsymPath = optarg; - break; - case 'c': - options->cfi = false; - break; - case 'r': - options->handle_inter_cu_refs = false; - break; - case '?': - case 'h': - Usage(argc, argv); - exit(0); - break; - } - } - - if ((argc - optind) != 1) { - fprintf(stderr, "Must specify Mach-o file\n"); - Usage(argc, argv); - exit(1); - } - - options->srcPath = argv[optind]; -} - -//============================================================================= -int main (int argc, const char * argv[]) { - Options options; - bool result; - - SetupOptions(argc, argv, &options); - result = Start(options); - - return !result; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc deleted file mode 100644 index d882bbe88..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/macho_dump.cc +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Original author: Jim Blandy - -// macho_dump.cc: Dump the contents of a Mach-O file. This is mostly -// a test program for the Mach_O::FatReader and Mach_O::Reader classes. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/byte_cursor.h" -#include "common/mac/arch_utilities.h" -#include "common/mac/macho_reader.h" - -using google_breakpad::ByteBuffer; -using std::ostringstream; -using std::string; -using std::vector; - -namespace { -namespace mach_o = google_breakpad::mach_o; - -string program_name; - -int check_syscall(int result, const char *operation, const char *filename) { - if (result < 0) { - fprintf(stderr, "%s: %s '%s': %s\n", - program_name.c_str(), operation, - filename, strerror(errno)); - exit(1); - } - return result; -} - -class DumpSection: public mach_o::Reader::SectionHandler { - public: - DumpSection() : index_(0) { } - bool HandleSection(const mach_o::Section §ion) { - printf(" section %d '%s' in segment '%s'\n" - " address: 0x%llx\n" - " alignment: 1 << %d B\n" - " flags: %d\n" - " size: %ld\n", - index_++, section.section_name.c_str(), section.segment_name.c_str(), - section.address, section.align, - mach_o::SectionFlags(section.flags), - section.contents.Size()); - return true; - } - - private: - int index_; -}; - -class DumpCommand: public mach_o::Reader::LoadCommandHandler { - public: - DumpCommand(mach_o::Reader *reader) : reader_(reader), index_(0) { } - bool UnknownCommand(mach_o::LoadCommandType type, - const ByteBuffer &contents) { - printf(" load command %d: %d", index_++, type); - return true; - } - bool SegmentCommand(const mach_o::Segment &segment) { - printf(" load command %d: %s-bit segment '%s'\n" - " address: 0x%llx\n" - " memory size: 0x%llx\n" - " maximum protection: 0x%x\n" - " initial protection: 0x%x\n" - " flags: %d\n" - " section_list size: %ld B\n", - index_++, (segment.bits_64 ? "64" : "32"), segment.name.c_str(), - segment.vmaddr, segment.vmsize, segment.maxprot, - segment.initprot, mach_o::SegmentFlags(segment.flags), - segment.section_list.Size()); - - DumpSection dump_section; - return reader_->WalkSegmentSections(segment, &dump_section); - } - private: - mach_o::Reader *reader_; - int index_; -}; - -void DumpFile(const char *filename) { - int fd = check_syscall(open(filename, O_RDONLY), "opening", filename); - struct stat attributes; - check_syscall(fstat(fd, &attributes), - "getting file attributes for", filename); - void *mapping = mmap(NULL, attributes.st_size, PROT_READ, - MAP_PRIVATE, fd, 0); - close(fd); - check_syscall(mapping == (void *)-1 ? -1 : 0, - "mapping contents of", filename); - - mach_o::FatReader::Reporter fat_reporter(filename); - mach_o::FatReader fat_reader(&fat_reporter); - if (!fat_reader.Read(reinterpret_cast(mapping), - attributes.st_size)) { - exit(1); - } - printf("filename: %s\n", filename); - size_t object_files_size; - const SuperFatArch* super_fat_object_files = - fat_reader.object_files(&object_files_size); - struct fat_arch *object_files; - if (!super_fat_object_files->ConvertToFatArch(object_files)) { - exit(1); - } - printf(" object file count: %ld\n", object_files_size); - for (size_t i = 0; i < object_files_size; i++) { - const struct fat_arch &file = object_files[i]; - const NXArchInfo *fat_arch_info = - google_breakpad::BreakpadGetArchInfoFromCpuType( - file.cputype, file.cpusubtype); - printf("\n object file %ld:\n" - " fat header:\n:" - " CPU type: %s (%s)\n" - " size: %d B\n" - " alignment: 1<<%d B\n", - i, fat_arch_info->name, fat_arch_info->description, - file.size, file.align); - - ostringstream name; - name << filename; - if (object_files_size > 1) - name << ", object file #" << i; - ByteBuffer file_contents(reinterpret_cast(mapping) - + file.offset, file.size); - mach_o::Reader::Reporter reporter(name.str()); - mach_o::Reader reader(&reporter); - if (!reader.Read(file_contents, file.cputype, file.cpusubtype)) { - exit(1); - } - - const NXArchInfo *macho_arch_info = - NXGetArchInfoFromCpuType(reader.cpu_type(), - reader.cpu_subtype()); - printf(" Mach-O header:\n" - " word size: %s\n" - " CPU type: %s (%s)\n" - " File type: %d\n" - " flags: %x\n", - (reader.bits_64() ? "64 bits" : "32 bits"), - macho_arch_info->name, macho_arch_info->description, - reader.file_type(), reader.flags()); - - DumpCommand dump_command(&reader); - reader.WalkLoadCommands(&dump_command); - } - munmap(mapping, attributes.st_size); -} - -} // namespace - -int main(int argc, char **argv) { - program_name = basename(argv[0]); - if (argc == 1) { - fprintf(stderr, "Usage: %s FILE ...\n" - "Dump the contents of the Mach-O or fat binary files " - "'FILE ...'.\n", program_name.c_str()); - } - for (int i = 1; i < argc; i++) { - DumpFile(argv[i]); - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build deleted file mode 100644 index 99ae82aa7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/moz.build +++ /dev/null @@ -1,40 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_SOURCES += [ - 'dump_syms_tool.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-g', - '-pthread', - '-stdlib=libc++', -] - -# Order matters here, but HOST_USE_LIBS must be sorted. -HOST_USE_LIBS += [ - 'host_breakpad_mac_common_s', -] -HOST_USE_LIBS += [ - 'host_breakpad_common_s', - 'host_breakpad_dwarf_s', -] - -# The HostProgram template may append 'host_stdc++compat' to -# HOST_USE_LIBS, which needs to appear after the entries above. -HostProgram('dump_syms') - -LOCAL_INCLUDES += [ - '../../../common/mac', -] - -if CONFIG['HOST_OS_ARCH'] != 'Darwin': - HOST_CXXFLAGS += [ - '-I%s/toolkit/crashreporter/google-breakpad/src/third_party/mac_headers/' % TOPSRCDIR, - ] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m deleted file mode 100644 index 741ad765e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/minidump_upload.m +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// minidump_upload.m: Upload a minidump to a HTTP server. The upload is sent as -// a multipart/form-data POST request with the following parameters: -// prod: the product name -// ver: the product version -// symbol_file: the breakpad format symbol file - -#import - -#import - -#import "common/mac/HTTPMultipartUpload.h" - -typedef struct { - NSString *minidumpPath; - NSString *uploadURLStr; - NSString *product; - NSString *version; - BOOL success; -} Options; - -//============================================================================= -static void Start(Options *options) { - NSURL *url = [NSURL URLWithString:options->uploadURLStr]; - HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url]; - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - - // Add parameters - [parameters setObject:options->product forKey:@"prod"]; - [parameters setObject:options->version forKey:@"ver"]; - [ul setParameters:parameters]; - - // Add file - [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"]; - - // Send it - NSError *error = nil; - NSData *data = [ul send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - - NSLog(@"Send: %@", error ? [error description] : @"No Error"); - NSLog(@"Response: %ld", (long)[[ul response] statusCode]); - NSLog(@"Result: %lu bytes\n%@", (unsigned long)[data length], result); - - [result release]; - [ul release]; - options->success = !error; -} - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit minidump information.\n"); - fprintf(stderr, "Usage: %s -p -v " - "\n", argv[0]); - fprintf(stderr, " should be a minidump.\n"); - fprintf(stderr, " is the destination for the upload\n"); - - fprintf(stderr, "\t-h: Usage\n"); - fprintf(stderr, "\t-?: Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - char ch; - - while ((ch = getopt(argc, (char * const *)argv, "p:v:h?")) != -1) { - switch (ch) { - case 'p': - options->product = [NSString stringWithUTF8String:optarg]; - break; - case 'v': - options->version = [NSString stringWithUTF8String:optarg]; - break; - - default: - Usage(argc, argv); - exit(0); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->minidumpPath = [NSString stringWithUTF8String:argv[optind]]; - options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]]; -} - -//============================================================================= -int main (int argc, const char * argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Options options; - - bzero(&options, sizeof(Options)); - SetupOptions(argc, argv, &options); - Start(&options); - - [pool release]; - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m deleted file mode 100644 index a7cce7b00..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.m +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// symupload.m: Upload a symbol file to a HTTP server. The upload is sent as -// a multipart/form-data POST request with the following parameters: -// code_file: the basename of the module, e.g. "app" -// debug_file: the basename of the debugging file, e.g. "app" -// debug_identifier: the debug file's identifier, usually consisting of -// the guid and age embedded in the pdb, e.g. -// "11111111BBBB3333DDDD555555555555F" -// os: the operating system that the module was built for -// cpu: the CPU that the module was built for (x86 or ppc) -// symbol_file: the contents of the breakpad-format symbol file - -#include -#include -#include - -#include -#include "HTTPMultipartUpload.h" - -typedef struct { - NSString *symbolsPath; - NSString *uploadURLStr; - BOOL success; -} Options; - -//============================================================================= -static NSArray *ModuleDataForSymbolFile(NSString *file) { - NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:file]; - NSData *data = [fh readDataOfLength:1024]; - NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSScanner *scanner = [NSScanner scannerWithString:str]; - NSString *line; - NSMutableArray *parts = nil; - const int MODULE_ID_INDEX = 3; - - if ([scanner scanUpToString:@"\n" intoString:&line]) { - parts = [[NSMutableArray alloc] init]; - NSScanner *moduleInfoScanner = [NSScanner scannerWithString:line]; - NSString *moduleInfo; - // Get everything BEFORE the module name. None of these properties - // can have spaces. - for (int i = 0; i <= MODULE_ID_INDEX; i++) { - [moduleInfoScanner scanUpToString:@" " intoString:&moduleInfo]; - [parts addObject:moduleInfo]; - } - - // Now get the module name. This can have a space so we scan to - // the end of the line. - [moduleInfoScanner scanUpToString:@"\n" intoString:&moduleInfo]; - [parts addObject:moduleInfo]; - } - - [str release]; - - return parts; -} - -//============================================================================= -static void Start(Options *options) { - NSURL *url = [NSURL URLWithString:options->uploadURLStr]; - HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url]; - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - NSArray *moduleParts = ModuleDataForSymbolFile(options->symbolsPath); - NSMutableString *compactedID = - [NSMutableString stringWithString:[moduleParts objectAtIndex:3]]; - [compactedID replaceOccurrencesOfString:@"-" withString:@"" options:0 - range:NSMakeRange(0, [compactedID length])]; - - // Add parameters - [parameters setObject:compactedID forKey:@"debug_identifier"]; - - // MODULE - // 0 1 2 3 4 - [parameters setObject:[moduleParts objectAtIndex:1] forKey:@"os"]; - [parameters setObject:[moduleParts objectAtIndex:2] forKey:@"cpu"]; - [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"debug_file"]; - [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"code_file"]; - [ul setParameters:parameters]; - - NSArray *keys = [parameters allKeys]; - int count = [keys count]; - for (int i = 0; i < count; ++i) { - NSString *key = [keys objectAtIndex:i]; - NSString *value = [parameters objectForKey:key]; - fprintf(stdout, "'%s' = '%s'\n", [key UTF8String], - [value UTF8String]); - } - - // Add file - [ul addFileAtPath:options->symbolsPath name:@"symbol_file"]; - - // Send it - NSError *error = nil; - NSData *data = [ul send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - int status = [[ul response] statusCode]; - - fprintf(stdout, "Send: %s\n", error ? [[error description] UTF8String] : - "No Error"); - fprintf(stdout, "Response: %d\n", status); - fprintf(stdout, "Result: %lu bytes\n%s\n", - (unsigned long)[data length], [result UTF8String]); - - [result release]; - [ul release]; - options->success = !error && status==200; -} - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit symbol information.\n"); - fprintf(stderr, "Usage: %s \n", argv[0]); - fprintf(stderr, " should be created by using the dump_syms tool.\n"); - fprintf(stderr, " is the destination for the upload\n"); - fprintf(stderr, "\t-h: Usage\n"); - fprintf(stderr, "\t-?: Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - char ch; - - while ((ch = getopt(argc, (char * const *)argv, "h?")) != -1) { - switch (ch) { - default: - Usage(argc, argv); - exit(0); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - int fd = open(argv[optind], O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: %s: %s\n", argv[0], argv[optind], strerror(errno)); - exit(1); - } - - struct stat statbuf; - if (fstat(fd, &statbuf) < 0) { - fprintf(stderr, "%s: %s: %s\n", argv[0], argv[optind], strerror(errno)); - close(fd); - exit(1); - } - close(fd); - - if (!S_ISREG(statbuf.st_mode)) { - fprintf(stderr, "%s: %s: not a regular file\n", argv[0], argv[optind]); - exit(1); - } - - options->symbolsPath = [NSString stringWithUTF8String:argv[optind]]; - options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]]; -} - -//============================================================================= -int main (int argc, const char * argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Options options; - - bzero(&options, sizeof(Options)); - SetupOptions(argc, argv, &options); - Start(&options); - - [pool release]; - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj b/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj deleted file mode 100644 index a6a78dc5f..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj +++ /dev/null @@ -1,254 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXBuildFile section */ - 8B31022C11F0CEBD00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; - 8DD76F9A0486AA7600D96B5E /* symupload.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* symupload.m */; settings = {ATTRIBUTES = (); }; }; - 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; - 9BC1D49E0B37427A00F2A2B4 /* minidump_upload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD836000B0544BA0055103E /* minidump_upload.m */; }; - 9BD8336A0B03E4080055103E /* HTTPMultipartUpload.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */; }; - 9BD8336B0B03E4080055103E /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */; }; - 9BD836180B0549F70055103E /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - 9BD8336A0B03E4080055103E /* HTTPMultipartUpload.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 08FB7796FE84155DC02AAC07 /* symupload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = symupload.m; sourceTree = ""; }; - 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 8B31022B11F0CE6900FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; - 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; - 8DD76FA10486AA7600D96B5E /* symupload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = symupload; sourceTree = BUILT_PRODUCTS_DIR; }; - 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPMultipartUpload.h; path = ../../../common/mac/HTTPMultipartUpload.h; sourceTree = ""; }; - 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPMultipartUpload.m; path = ../../../common/mac/HTTPMultipartUpload.m; sourceTree = ""; }; - 9BD835FB0B0544950055103E /* minidump_upload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_upload; sourceTree = BUILT_PRODUCTS_DIR; }; - 9BD836000B0544BA0055103E /* minidump_upload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = minidump_upload.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9BD835F90B0544950055103E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8B31022C11F0CEBD00FCF3E4 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* symupload */ = { - isa = PBXGroup; - children = ( - 8B31022B11F0CE6900FCF3E4 /* Breakpad.xcconfig */, - 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */, - 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */, - 08FB7796FE84155DC02AAC07 /* symupload.m */, - 9BD836000B0544BA0055103E /* minidump_upload.m */, - 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */, - 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */, - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = symupload; - sourceTree = ""; - }; - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 08FB779EFE84155DC02AAC07 /* Foundation.framework */, - ); - name = "External Frameworks and Libraries"; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8DD76FA10486AA7600D96B5E /* symupload */, - 9BD835FB0B0544950055103E /* minidump_upload */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8DD76F960486AA7600D96B5E /* symupload */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "symupload" */; - buildPhases = ( - 8DD76F990486AA7600D96B5E /* Sources */, - 8DD76F9B0486AA7600D96B5E /* Frameworks */, - 8DD76F9E0486AA7600D96B5E /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = symupload; - productInstallPath = "$(HOME)/bin"; - productName = symupload; - productReference = 8DD76FA10486AA7600D96B5E /* symupload */; - productType = "com.apple.product-type.tool"; - }; - 9BD835FA0B0544950055103E /* minidump_upload */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9BD836020B0544BB0055103E /* Build configuration list for PBXNativeTarget "minidump_upload" */; - buildPhases = ( - 9BD835F80B0544950055103E /* Sources */, - 9BD835F90B0544950055103E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = minidump_upload; - productName = minidump_upload; - productReference = 9BD835FB0B0544950055103E /* minidump_upload */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "symupload" */; - compatibilityVersion = "Xcode 3.1"; - hasScannedForEncodings = 1; - mainGroup = 08FB7794FE84155DC02AAC07 /* symupload */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8DD76F960486AA7600D96B5E /* symupload */, - 9BD835FA0B0544950055103E /* minidump_upload */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DD76F990486AA7600D96B5E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8DD76F9A0486AA7600D96B5E /* symupload.m in Sources */, - 9BD8336B0B03E4080055103E /* HTTPMultipartUpload.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9BD835F80B0544950055103E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9BD836180B0549F70055103E /* HTTPMultipartUpload.m in Sources */, - 9BC1D49E0B37427A00F2A2B4 /* minidump_upload.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB927508733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../..; - PRODUCT_NAME = symupload; - }; - name = Debug; - }; - 1DEB927608733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../..; - PRODUCT_NAME = symupload; - }; - name = Release; - }; - 1DEB927908733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 1DEB927A08733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 9BD836030B0544BB0055103E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../..; - PRODUCT_NAME = minidump_upload; - }; - name = Debug; - }; - 9BD836040B0544BB0055103E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ../../..; - PRODUCT_NAME = minidump_upload; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "symupload" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927508733DD40010E9CD /* Debug */, - 1DEB927608733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "symupload" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927908733DD40010E9CD /* Debug */, - 1DEB927A08733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9BD836020B0544BB0055103E /* Build configuration list for PBXNativeTarget "minidump_upload" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9BD836030B0544BB0055103E /* Debug */, - 9BD836040B0544BB0055103E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi b/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi deleted file mode 100644 index 7457573b4..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/tools_mac.gypi +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'target_defaults': { - 'include_dirs': [ - '../..', - ], - }, - 'targets': [ - { - 'target_name': 'crash_report', - 'type': 'executable', - 'sources': [ - 'crash_report/crash_report.mm', - 'crash_report/on_demand_symbol_supplier.h', - 'crash_report/on_demand_symbol_supplier.mm', - ], - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/Foundation.framework', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - '../processor/processor.gyp:processor', - ], - }, - { - 'target_name': 'dump_syms', - 'type': 'executable', - 'sources': [ - 'dump_syms/dump_syms_tool.cc', - ], - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/Foundation.framework', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'macho_dump', - 'type': 'executable', - 'sources': [ - 'dump_syms/macho_dump.cc', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'minidump_upload', - 'type': 'executable', - 'sources': [ - 'symupload/minidump_upload.m', - ], - 'include_dirs': [ - '../../common/mac', - ], - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/Foundation.framework', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'symupload', - 'type': 'executable', - 'sources': [ - 'symupload/symupload.m', - ], - 'include_dirs': [ - '../../common/mac', - ], - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/Foundation.framework', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h deleted file mode 100644 index 2115e54e6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_constants.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright 2014, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include - -// Go/Cgo does not support #define constants, so turn them into symbols -// that are reachable from Go. - -#ifndef CPU_TYPE_ARM64 -#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) -#endif - -#ifndef CPU_SUBTYPE_ARM64_ALL -#define CPU_SUBTYPE_ARM64_ALL 0 -#endif - -const cpu_type_t kCPU_TYPE_ARM = CPU_TYPE_ARM; -const cpu_type_t kCPU_TYPE_ARM64 = CPU_TYPE_ARM64; - -const cpu_subtype_t kCPU_SUBTYPE_ARM64_ALL = CPU_SUBTYPE_ARM64_ALL; -const cpu_subtype_t kCPU_SUBTYPE_ARM_V7S = CPU_SUBTYPE_ARM_V7S; - -const char* GetNXArchInfoName(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { - const NXArchInfo* arch_info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); - if (!arch_info) - return 0; - return arch_info->name; -} - -const uint32_t kMachHeaderFtypeDylib = MH_DYLIB; -const uint32_t kMachHeaderFtypeBundle = MH_BUNDLE; -const uint32_t kMachHeaderFtypeExe = MH_EXECUTE; diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go deleted file mode 100644 index f60648230..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/arch_reader.go +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright 2014, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package main - -import ( - "debug/macho" -) - -/* -#include "arch_constants.h" -*/ -import "C" - -// getArchStringFromHeader takes a MachO FileHeader and returns a string that -// represents the CPU type and subtype. -// This function is a Go version of src/common/mac/arch_utilities.cc:BreakpadGetArchInfoFromCpuType(). -func getArchStringFromHeader(header macho.FileHeader) string { - // TODO(rsesek): As of 10.9.4, OS X doesn't list these in /usr/include/mach/machine.h. - if header.Cpu == C.kCPU_TYPE_ARM64 && header.SubCpu == C.kCPU_SUBTYPE_ARM64_ALL { - return "arm64" - } - if header.Cpu == C.kCPU_TYPE_ARM && header.SubCpu == C.kCPU_SUBTYPE_ARM_V7S { - return "armv7s" - } - - cstr := C.GetNXArchInfoName(C.cpu_type_t(header.Cpu), C.cpu_subtype_t(header.SubCpu)) - if cstr == nil { - return "" - } - return C.GoString(cstr) -} - -const ( - MachODylib macho.Type = C.kMachHeaderFtypeDylib - MachOBundle = C.kMachHeaderFtypeBundle - MachOExe = C.kMachHeaderFtypeExe -) diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go deleted file mode 100644 index 355612086..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ /dev/null @@ -1,420 +0,0 @@ -/* Copyright 2014, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* -Tool upload_system_symbols generates and uploads Breakpad symbol files for OS X system libraries. - -This tool shells out to the dump_syms and symupload Breakpad tools. In its default mode, this -will find all dynamic libraries on the system, run dump_syms to create the Breakpad symbol files, -and then upload them to Google's crash infrastructure. - -The tool can also be used to only dump libraries or upload from a directory. See -help for more -information. - -Both i386 and x86_64 architectures will be dumped and uploaded. -*/ -package main - -import ( - "debug/macho" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "os/exec" - "path" - "regexp" - "strings" - "sync" - "time" -) - -var ( - breakpadTools = flag.String("breakpad-tools", "out/Release/", "Path to the Breakpad tools directory, containing dump_syms and symupload.") - uploadOnlyPath = flag.String("upload-from", "", "Upload a directory of symbol files that has been dumped independently.") - dumpOnlyPath = flag.String("dump-to", "", "Dump the symbols to the specified directory, but do not upload them.") - systemRoot = flag.String("system-root", "", "Path to the root of the Mac OS X system whose symbols will be dumped.") - dumpArchitecture = flag.String("arch", "", "The CPU architecture for which symbols should be dumped. If not specified, dumps all architectures.") -) - -var ( - // pathsToScan are the subpaths in the systemRoot that should be scanned for shared libraries. - pathsToScan = []string{ - "/Library/QuickTime", - "/System/Library/Components", - "/System/Library/Frameworks", - "/System/Library/PrivateFrameworks", - "/usr/lib", - } - - // uploadServers are the list of servers to which symbols should be uploaded. - uploadServers = []string{ - "https://clients2.google.com/cr/symbol", - "https://clients2.google.com/cr/staging_symbol", - } - - // blacklistRegexps match paths that should be excluded from dumping. - blacklistRegexps = []*regexp.Regexp{ - regexp.MustCompile(`/System/Library/Frameworks/Python\.framework/`), - regexp.MustCompile(`/System/Library/Frameworks/Ruby\.framework/`), - regexp.MustCompile(`_profile\.dylib$`), - regexp.MustCompile(`_debug\.dylib$`), - regexp.MustCompile(`\.a$`), - regexp.MustCompile(`\.dat$`), - } -) - -func main() { - flag.Parse() - log.SetFlags(0) - - var uq *UploadQueue - - if *uploadOnlyPath != "" { - // -upload-from specified, so handle that case early. - uq = StartUploadQueue() - uploadFromDirectory(*uploadOnlyPath, uq) - uq.Wait() - return - } - - if *systemRoot == "" { - log.Fatal("Need a -system-root to dump symbols for") - } - - if *dumpOnlyPath != "" { - // -dump-to specified, so make sure that the path is a directory. - if fi, err := os.Stat(*dumpOnlyPath); err != nil { - log.Fatal("-dump-to location: %v", err) - } else if !fi.IsDir() { - log.Fatal("-dump-to location is not a directory") - } - } - - dumpPath := *dumpOnlyPath - if *dumpOnlyPath == "" { - // If -dump-to was not specified, then run the upload pipeline and create - // a temporary dump output directory. - uq = StartUploadQueue() - - if p, err := ioutil.TempDir("", "upload_system_symbols"); err != nil { - log.Fatal("Failed to create temporary directory: %v", err) - } else { - dumpPath = p - defer os.RemoveAll(p) - } - } - - dq := StartDumpQueue(*systemRoot, dumpPath, uq) - dq.Wait() - if uq != nil { - uq.Wait() - } -} - -type WorkerPool struct { - wg sync.WaitGroup -} - -// StartWorkerPool will launch numWorkers goroutines all running workerFunc. -// When workerFunc exits, the goroutine will terminate. -func StartWorkerPool(numWorkers int, workerFunc func()) *WorkerPool { - p := new(WorkerPool) - for i := 0; i < numWorkers; i++ { - p.wg.Add(1) - go func() { - workerFunc() - p.wg.Done() - }() - } - return p -} - -// Wait for all the workers in the pool to complete the workerFunc. -func (p *WorkerPool) Wait() { - p.wg.Wait() -} - -type UploadQueue struct { - *WorkerPool - queue chan string -} - -// StartUploadQueue creates a new worker pool and queue, to which paths to -// Breakpad symbol files may be sent for uploading. -func StartUploadQueue() *UploadQueue { - uq := &UploadQueue{ - queue: make(chan string, 10), - } - uq.WorkerPool = StartWorkerPool(5, uq.worker) - return uq -} - -// Upload enqueues the contents of filepath to be uploaded. -func (uq *UploadQueue) Upload(filepath string) { - uq.queue <- filepath -} - -// Done tells the queue that no more files need to be uploaded. This must be -// called before WorkerPool.Wait. -func (uq *UploadQueue) Done() { - close(uq.queue) -} - -func (uq *UploadQueue) worker() { - symUpload := path.Join(*breakpadTools, "symupload") - - for symfile := range uq.queue { - for _, server := range uploadServers { - for i := 0; i < 3; i++ { // Give each upload 3 attempts to succeed. - cmd := exec.Command(symUpload, symfile, server) - if output, err := cmd.Output(); err == nil { - // Success. No retry needed. - fmt.Printf("Uploaded %s to %s\n", symfile, server) - break - } else { - log.Printf("Error running symupload(%s, %s), attempt %d: %v: %s\n", symfile, server, i, err, output) - time.Sleep(1 * time.Second) - } - } - } - } -} - -type DumpQueue struct { - *WorkerPool - dumpPath string - queue chan dumpRequest - uq *UploadQueue -} - -type dumpRequest struct { - path string - arch string -} - -// StartDumpQueue creates a new worker pool to find all the Mach-O libraries in -// root and dump their symbols to dumpPath. If an UploadQueue is passed, the -// path to the symbol file will be enqueued there, too. -func StartDumpQueue(root, dumpPath string, uq *UploadQueue) *DumpQueue { - dq := &DumpQueue{ - dumpPath: dumpPath, - queue: make(chan dumpRequest), - uq: uq, - } - dq.WorkerPool = StartWorkerPool(12, dq.worker) - - findLibsInRoot(root, dq) - - return dq -} - -// DumpSymbols enqueues the filepath to have its symbols dumped in the specified -// architecture. -func (dq *DumpQueue) DumpSymbols(filepath string, arch string) { - dq.queue <- dumpRequest{ - path: filepath, - arch: arch, - } -} - -func (dq *DumpQueue) Wait() { - dq.WorkerPool.Wait() - if dq.uq != nil { - dq.uq.Done() - } -} - -func (dq *DumpQueue) done() { - close(dq.queue) -} - -func (dq *DumpQueue) worker() { - dumpSyms := path.Join(*breakpadTools, "dump_syms") - - for req := range dq.queue { - filebase := path.Join(dq.dumpPath, strings.Replace(req.path, "/", "_", -1)) - symfile := fmt.Sprintf("%s_%s.sym", filebase, req.arch) - f, err := os.Create(symfile) - if err != nil { - log.Fatal("Error creating symbol file:", err) - } - - cmd := exec.Command(dumpSyms, "-a", req.arch, req.path) - cmd.Stdout = f - err = cmd.Run() - f.Close() - - if err != nil { - os.Remove(symfile) - log.Printf("Error running dump_syms(%s, %s): %v\n", req.arch, req.path, err) - } else if dq.uq != nil { - dq.uq.Upload(symfile) - } - } -} - -// uploadFromDirectory handles the upload-only case and merely uploads all files in -// a directory. -func uploadFromDirectory(directory string, uq *UploadQueue) { - d, err := os.Open(directory) - if err != nil { - log.Fatal("Could not open directory to upload: %v", err) - } - defer d.Close() - - entries, err := d.Readdirnames(0) - if err != nil { - log.Fatal("Could not read directory: %v", err) - } - - for _, entry := range entries { - uq.Upload(path.Join(directory, entry)) - } - - uq.Done() -} - -// findQueue is an implementation detail of the DumpQueue that finds all the -// Mach-O files and their architectures. -type findQueue struct { - *WorkerPool - queue chan string - dq *DumpQueue -} - -// findLibsInRoot looks in all the pathsToScan in the root and manages the -// interaction between findQueue and DumpQueue. -func findLibsInRoot(root string, dq *DumpQueue) { - fq := &findQueue{ - queue: make(chan string, 10), - dq: dq, - } - fq.WorkerPool = StartWorkerPool(12, fq.worker) - - for _, p := range pathsToScan { - fq.findLibsInPath(path.Join(root, p)) - } - - close(fq.queue) - fq.Wait() - dq.done() -} - -// findLibsInPath recursively walks the directory tree, sending file paths to -// test for being Mach-O to the findQueue. -func (fq *findQueue) findLibsInPath(loc string) { - d, err := os.Open(loc) - if err != nil { - log.Fatal("Could not open %s: %v", loc, err) - } - defer d.Close() - - for { - fis, err := d.Readdir(100) - if err != nil && err != io.EOF { - log.Fatal("Error reading directory %s: %v", loc, err) - } - - for _, fi := range fis { - fp := path.Join(loc, fi.Name()) - if fi.IsDir() { - fq.findLibsInPath(fp) - continue - } else if fi.Mode()&os.ModeSymlink != 0 { - continue - } - - // Test the blacklist in the worker to not slow down this main loop. - - fq.queue <- fp - } - - if err == io.EOF { - break - } - } -} - -func (fq *findQueue) worker() { - for fp := range fq.queue { - blacklisted := false - for _, re := range blacklistRegexps { - blacklisted = blacklisted || re.MatchString(fp) - } - if blacklisted { - continue - } - - f, err := os.Open(fp) - if err != nil { - log.Printf("%s: %v", fp, err) - continue - } - - fatFile, err := macho.NewFatFile(f) - if err == nil { - // The file is fat, so dump its architectures. - for _, fatArch := range fatFile.Arches { - fq.dumpMachOFile(fp, fatArch.File) - } - fatFile.Close() - } else if err == macho.ErrNotFat { - // The file isn't fat but may still be MachO. - thinFile, err := macho.NewFile(f) - if err != nil { - log.Printf("%s: %v", fp, err) - continue - } - fq.dumpMachOFile(fp, thinFile) - thinFile.Close() - } else { - f.Close() - } - } -} - -func (fq *findQueue) dumpMachOFile(fp string, image *macho.File) { - if image.Type != MachODylib && image.Type != MachOBundle { - return - } - - arch := getArchStringFromHeader(image.FileHeader) - if arch == "" { - // Don't know about this architecture type. - return - } - - if (*dumpArchitecture != "" && *dumpArchitecture == arch) || *dumpArchitecture == "" { - fq.dq.DumpSymbols(fp, arch) - } -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py b/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py deleted file mode 100644 index abddf7893..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/python/filter_syms.py +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Normalizes and de-duplicates paths within Breakpad symbol files. - -When using DWARF for storing debug symbols, some file information will be -stored relative to the current working directory of the current compilation -unit, and may be further relativized based upon how the file was #included. - -This helper can be used to parse the Breakpad symbol file generated from such -DWARF files and normalize and de-duplicate the FILE records found within, -updating any references to the FILE records in the other record types. -""" - -import macpath -import ntpath -import optparse -import os -import posixpath -import sys - -class BreakpadParseError(Exception): - """Unsupported Breakpad symbol record exception class.""" - pass - -class SymbolFileParser(object): - """Parser for Breakpad symbol files. - - The format of these files is documented at - https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md - """ - - def __init__(self, input_stream, output_stream, ignored_prefixes=None, - path_handler=os.path): - """Inits a SymbolFileParser to read symbol records from |input_stream| and - write the processed output to |output_stream|. - - |ignored_prefixes| contains a list of optional path prefixes that - should be stripped from the final, normalized path outputs. - - For example, if the Breakpad symbol file had all paths starting with a - common prefix, such as: - FILE 1 /b/build/src/foo.cc - FILE 2 /b/build/src/bar.cc - Then adding "/b/build/src" as an ignored prefix would result in an output - file that contained: - FILE 1 foo.cc - FILE 2 bar.cc - - Note that |ignored_prefixes| does not necessarily contain file system - paths, as the contents of the DWARF DW_AT_comp_dir attribute is dependent - upon the host system and compiler, and may contain additional information - such as hostname or compiler version. - """ - - self.unique_files = {} - self.duplicate_files = {} - self.input_stream = input_stream - self.output_stream = output_stream - self.ignored_prefixes = ignored_prefixes or [] - self.path_handler = path_handler - - def Process(self): - """Processes the Breakpad symbol file.""" - for line in self.input_stream: - parsed = self._ParseRecord(line.rstrip()) - if parsed: - self.output_stream.write(parsed + '\n') - - def _ParseRecord(self, record): - """Parses a single Breakpad symbol record - a single line from the symbol - file. - - Returns: - The modified string to write to the output file, or None if no line - should be written. - """ - record_type = record.partition(' ')[0] - if record_type == 'FILE': - return self._ParseFileRecord(record) - elif self._IsLineRecord(record_type): - return self._ParseLineRecord(record) - else: - # Simply pass the record through unaltered. - return record - - def _NormalizePath(self, path): - """Normalizes a file path to its canonical form. - - As this may not execute on the machine or file system originally - responsible for compilation, it may be necessary to further correct paths - for symlinks, junctions, or other such file system indirections. - - Returns: - A unique, canonical representation for the the file path. - """ - return self.path_handler.normpath(path) - - def _AdjustPath(self, path): - """Adjusts the supplied path after performing path de-duplication. - - This may be used to perform secondary adjustments, such as removing a - common prefix, such as "/D/build", or replacing the file system path with - information from the version control system. - - Returns: - The actual path to use when writing the FILE record. - """ - return path[len(filter(path.startswith, - self.ignored_prefixes + [''])[0]):] - - def _ParseFileRecord(self, file_record): - """Parses and corrects a FILE record.""" - file_info = file_record[5:].split(' ', 3) - if len(file_info) > 2: - raise BreakpadParseError('Unsupported FILE record: ' + file_record) - file_index = int(file_info[0]) - file_name = self._NormalizePath(file_info[1]) - existing_file_index = self.unique_files.get(file_name) - if existing_file_index is None: - self.unique_files[file_name] = file_index - file_info[1] = self._AdjustPath(file_name) - return 'FILE ' + ' '.join(file_info) - else: - self.duplicate_files[file_index] = existing_file_index - return None - - def _IsLineRecord(self, record_type): - """Determines if the current record type is a Line record""" - try: - line = int(record_type, 16) - except (ValueError, TypeError): - return False - return True - - def _ParseLineRecord(self, line_record): - """Parses and corrects a Line record.""" - line_info = line_record.split(' ', 5) - if len(line_info) > 4: - raise BreakpadParseError('Unsupported Line record: ' + line_record) - file_index = int(line_info[3]) - line_info[3] = str(self.duplicate_files.get(file_index, file_index)) - return ' '.join(line_info) - -def main(): - option_parser = optparse.OptionParser() - option_parser.add_option("-p", "--prefix", - action="append", dest="prefixes", type="string", - default=[], - help="A path prefix that should be removed from " - "all FILE lines. May be repeated to specify " - "multiple prefixes.") - option_parser.add_option("-t", "--path_type", - action="store", type="choice", dest="path_handler", - choices=['win32', 'posix'], - help="Indicates how file paths should be " - "interpreted. The default is to treat paths " - "the same as the OS running Python (eg: " - "os.path)") - options, args = option_parser.parse_args() - if args: - option_parser.error('Unknown argument: %s' % args) - - path_handler = { 'win32': ntpath, - 'posix': posixpath }.get(options.path_handler, os.path) - try: - symbol_parser = SymbolFileParser(sys.stdin, sys.stdout, options.prefixes, - path_handler) - symbol_parser.Process() - except BreakpadParseError, e: - print >> sys.stderr, 'Got an error while processing symbol file' - print >> sys.stderr, str(e) - return 1 - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py b/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py deleted file mode 100644 index b111f3498..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/python/tests/filter_syms_unittest.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Unit tests for filter_syms.py""" - -import cStringIO -import ntpath -import os -import StringIO -import sys -import unittest - -ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.join(ROOT_DIR, '..')) - -# In root -import filter_syms - -class FilterSysmsTest(unittest.TestCase): - def assertParsed(self, input_data, ignored_prefixes, expected): - input_io = cStringIO.StringIO(input_data) - output_io = cStringIO.StringIO() - parser = filter_syms.SymbolFileParser(input_io, output_io, - ignored_prefixes, ntpath) - parser.Process() - self.assertEqual(output_io.getvalue(), expected) - - def testDuplicateFiles(self): - """Tests that duplicate files in FILE records are correctly removed and - that Line records are updated.""" - - INPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 foo/../file1_1.cc -FILE 2 bar/../file1_1.cc -FILE 3 baz/../file1_1.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 2 -1008 4 46 3 -100c 4 44 1 -""" - EXPECTED_OUTPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 file1_1.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 1 -1008 4 46 1 -100c 4 44 1 -""" - self.assertParsed(INPUT, [], EXPECTED_OUTPUT) - - def testIgnoredPrefix(self): - """Tests that prefixes in FILE records are correctly removed.""" - - INPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 /src/build/foo/../file1_1.cc -FILE 2 /src/build/bar/../file1_2.cc -FILE 3 /src/build/baz/../file1_2.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 2 -1008 4 46 3 -100c 4 44 1 -""" - EXPECTED_OUTPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 file1_1.cc -FILE 2 file1_2.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 2 -1008 4 46 2 -100c 4 44 1 -""" - IGNORED_PREFIXES = ['\\src\\build\\'] - self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT) - - def testIgnoredPrefixesDuplicateFiles(self): - """Tests that de-duplication of FILE records happens BEFORE prefixes - are removed.""" - - INPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 /src/build/foo/../file1_1.cc -FILE 2 /src/build/bar/../file1_2.cc -FILE 3 D:/src/build2/baz/../file1_2.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 2 -1008 4 46 3 -100c 4 44 1 -""" - EXPECTED_OUTPUT = \ -"""MODULE windows x86 111111111111111111111111111111111 module1.pdb -INFO CODE_ID FFFFFFFF module1.exe -FILE 1 file1_1.cc -FILE 2 file1_2.cc -FILE 3 file1_2.cc -FUNC 1000 c 0 Function1_1 -1000 8 45 2 -1008 4 46 3 -100c 4 44 1 -""" - IGNORED_PREFIXES = ['\\src\\build\\', 'D:\\src\\build2\\'] - self.assertParsed(INPUT, IGNORED_PREFIXES, EXPECTED_OUTPUT) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile deleted file mode 100644 index ff77105c6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Author: Alfred Peng - -CXX=CC -CC=cc - -CXXFLAGS=-g -xs -xdebugformat=stabs -I../../.. -I../../../common/solaris -lelf -ldemangle -D_REENTRANT - -.PHONY:all clean - -BIN=dump_syms - -all:$(BIN) - -DUMP_OBJ=dump_symbols.o guid_creator.o dump_syms.o file_id.o md5.o - -dump_syms:$(DUMP_OBJ) - $(CXX) $(CXXFLAGS) -o $@ $^ - -dump_symbols.o:../../../common/solaris/dump_symbols.cc - $(CXX) $(CXXFLAGS) -c $^ - -guid_creator.o:../../../common/solaris/guid_creator.cc - $(CXX) $(CXXFLAGS) -c $^ - -file_id.o:../../../common/solaris/file_id.cc - $(CXX) $(CXXFLAGS) -c $^ - -md5.o:../../../common/md5.cc - $(CXX) $(CXXFLAGS) -c $^ - -test:all - ./run_regtest.sh - -clean: - rm -f $(BIN) $(DUMP_OBJ) diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in deleted file mode 100644 index 7bef51e07..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_LDFLAGS += -lelf -ldemangle diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc deleted file mode 100644 index 54cea57e7..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/dump_syms.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: Alfred Peng - -#include -#include - -#include "common/solaris/dump_symbols.h" - -using namespace google_breakpad; - -int main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - const char *binary = argv[1]; - - DumpSymbols dumper; - if (!dumper.WriteSymbolFile(binary, fileno(stdout))) { - fprintf(stderr, "Failed to write symbol file.\n"); - return 1; - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build deleted file mode 100644 index 3efeac039..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/moz.build +++ /dev/null @@ -1,29 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_SOURCES += [ - 'dump_syms.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -HOST_USE_LIBS += [ - 'host_breakpad_common_s', - 'host_breakpad_solaris_common_s', -] - -# The HostProgram template may append 'host_stdc++compat' to -# HOST_USE_LIBS, which needs to appear after the entries above. -HostProgram('dump_syms') - -LOCAL_INCLUDES += [ - '../../../common/solaris', -] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh deleted file mode 100644 index ffb343306..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/run_regtest.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -./dump_syms testdata/dump_syms_regtest.o > testdata/dump_syms_regtest.new -status=$? - -if [ $status -ne 0 ] ; then - echo "FAIL, dump_syms failed" - exit $status -fi - -diff -u testdata/dump_syms_regtest.new testdata/dump_syms_regtest.sym > \ - testdata/dump_syms_regtest.diff -status=$? - -if [ $status -eq 0 ] ; then - rm testdata/dump_syms_regtest.diff testdata/dump_syms_regtest.new - echo "PASS" -else - echo "FAIL, see testdata/dump_syms_regtest.[new|diff]" -fi - -exit $status diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc deleted file mode 100644 index e617a23b8..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ./dump_syms dump_syms_regtest.pdb > dump_syms_regtest.sym - -namespace google_breakpad { - -class C { - public: - C() : member_(1) {} - virtual ~C() {} - - void set_member(int value) { member_ = value; } - int member() const { return member_; } - - void f() { member_ = g(); } - virtual int g() { return 2; } - static char* h(const C &that) { return 0; } - - private: - int member_; -}; - -static int i() { - return 3; -} - -} // namespace google_breakpad - -int main(int argc, char **argv) { - google_breakpad::C object; - object.set_member(google_breakpad::i()); - object.f(); - int value = object.g(); - char *nothing = object.h(object); - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs deleted file mode 100644 index c5f93ef78..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.stabs +++ /dev/null @@ -1,129 +0,0 @@ - - -Debugging Stab table -- 104 entries - - 0: .stabs "dump_syms_regtest.cc",N_UNDF,0x0,0x67,0x71c - 1: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/",N_SO,0x0,0x0,0x0 - 2: .stabs "dump_syms_regtest.cc",N_SO,0x0,0x4,0x0 - 3: .stabs "",N_OBJ,0x0,0x0,0x0 - 4: .stabs "",N_OBJ,0x0,0x0,0x0 - 5: .stabs "V=9.0;DBG_GEN=5.0.8;dm;cd;backend;ptf;ptx;ptk;s;g;R=5.8<>;G=.XAB6Z2hOiL$Gl1b.;A=2",N_OPT,0x0,0x0,0x46fcb88e - 6: .stabs "dump_syms_regtest.cc",N_SOL,0x0,0x0,0x0 - 7: .stabs "char:t(0,1)=bsc1;0;8",N_ISYM,0x0,0x0,0x0 - 8: .stabs "short:t(0,2)=bs2;0;16",N_ISYM,0x0,0x0,0x0 - 9: .stabs "int:t(0,3)=bs4;0;32",N_ISYM,0x0,0x0,0x0 - 10: .stabs "long:t(0,4)=bs4;0;32",N_ISYM,0x0,0x0,0x0 - 11: .stabs "long long:t(0,5)=bs8;0;64",N_ISYM,0x0,0x0,0x0 - 12: .stabs "unsigned char:t(0,6)=buc1;0;8",N_ISYM,0x0,0x0,0x0 - 13: .stabs "unsigned short:t(0,7)=bu2;0;16",N_ISYM,0x0,0x0,0x0 - 14: .stabs "unsigned:t(0,8)=bu4;0;32",N_ISYM,0x0,0x0,0x0 - 15: .stabs "unsigned long:t(0,9)=bu4;0;32",N_ISYM,0x0,0x0,0x0 - 16: .stabs "unsigned long long:t(0,10)=bu8;0;64",N_ISYM,0x0,0x0,0x0 - 17: .stabs "signed char:t(0,11)=bsc1;0;8",N_ISYM,0x0,0x0,0x0 - 18: .stabs "wchar_t:t(0,12)=buc4;0;32",N_ISYM,0x0,0x0,0x0 - 19: .stabs "void:t(0,13)=bs0;0;0",N_ISYM,0x0,0x0,0x0 - 20: .stabs "float:t(0,14)=R1;4",N_ISYM,0x0,0x0,0x0 - 21: .stabs "double:t(0,15)=R2;8",N_ISYM,0x0,0x0,0x0 - 22: .stabs "long double:t(0,16)=R6;12",N_ISYM,0x0,0x0,0x0 - 23: .stabs "...:t(0,17)=buv4;0;32",N_ISYM,0x0,0x0,0x0 - 24: .stabs "bool:t(0,18)=bub1;0;8",N_ISYM,0x0,0x0,0x0 - 25: .stabs "__1nPgoogle_breakpad_:T(0,19)=Yn0google_breakpad;",N_ISYM,0x0,0x0,0x0 - 26: .stabs "nBC(0,19):U(0,20)",N_ESYM,0x0,0x0,0x0 - 27: .stabs "nBC(0,19):T(0,20)=Yc8C;;AcHmember_:(0,3),32,32;;Cc2t6M_v K2c2T6M_v CcKset_member6Mi_v CcGmember6kM_i CcBf6M_v K3cBg6M_i GcBh6Frk1_pc;;;2 0;;;;110;",N_ESYM,0x0,0x8,0x0 - 28: .stabs "main:F(0,3);(0,3);(0,21)=*(0,22)=*(0,1)",N_FUN,0x0,0x38,0x0 - 29: .stabs "main",N_MAIN,0x0,0x0,0x0 - 30: .stabs "argc:p(0,3)",N_PSYM,0x0,0x4,0x8 - 31: .stabs "argv:p(0,21)",N_PSYM,0x0,0x4,0xc - 32: .stabn N_LBRAC,0x0,0x1,0x12 - 33: .stabs "object:(0,20)",N_LSYM,0x0,0x8,0xfffffff4 - 34: .stabs "value:(0,3)",N_LSYM,0x0,0x4,0xfffffff0 - 35: .stabs "nothing:(0,22)",N_LSYM,0x0,0x4,0xffffffec - 36: .stabn N_SLINE,0x0,0x39,0x12 - 37: .stabs "object:2",N_CONSTRUCT,0x0,0xc,0x12 - 38: .stabn N_SLINE,0x2,0x3a,0x1e - 39: .stabn N_SLINE,0x0,0x3b,0x36 - 40: .stabn N_SLINE,0x0,0x3c,0x42 - 41: .stabn N_SLINE,0x0,0x3d,0x57 - 42: .stabn N_SLINE,0x0,0x3f,0x6c - 43: .stabs "2:0",N_DESTRUCT,0x0,0xc,0x73 - 44: .stabn N_SLINE,0xfffffffe,0x40,0x9c - 45: .stabn N_RBRAC,0x0,0x1,0x9c - 46: .stabs "__1cPgoogle_breakpadBi6F_i_:f(0,3)",N_FUN,0x0,0x32,0x0 - 47: .stabn N_LBRAC,0x0,0x1,0x6 - 48: .stabn N_SLINE,0x0,0x33,0x6 - 49: .stabn N_SLINE,0x0,0x34,0x10 - 50: .stabn N_RBRAC,0x0,0x1,0x10 - 51: .stabs "__1cPgoogle_breakpadBC2t6M_v_:F(0,13);(0,23)=*(0,20)",N_FUN,0x0,0x24,0x0 - 52: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 53: .stabn N_LBRAC,0x0,0x1,0x3 - 54: .stabn N_SLINE,0x0,0x24,0x25 - 55: .stabn N_RBRAC,0x0,0x1,0x25 - 56: .stabs "__1cPgoogle_breakpadBC2T6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x25,0x0 - 57: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 58: .stabn N_LBRAC,0x0,0x1,0x3 - 59: .stabn N_SLINE,0x0,0x25,0x3 - 60: .stabn N_RBRAC,0x0,0x1,0x3 - 61: .stabs "__1cPgoogle_breakpadBCKset_member6Mi_v_:F(0,13);(0,23);(0,3)",N_FUN,0x0,0x27,0x0 - 62: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 63: .stabs "value:p(0,3)",N_PSYM,0x0,0x4,0xc - 64: .stabn N_LBRAC,0x0,0x1,0x3 - 65: .stabn N_SLINE,0x0,0x27,0x3 - 66: .stabn N_SLINE,0x0,0x27,0xc - 67: .stabn N_RBRAC,0x0,0x1,0xc - 68: .stabs "__1cPgoogle_breakpadBCBf6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x2a,0x0 - 69: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 70: .stabn N_LBRAC,0x0,0x1,0x3 - 71: .stabn N_SLINE,0x0,0x2a,0x3 - 72: .stabn N_SLINE,0x0,0x2a,0x1d - 73: .stabn N_RBRAC,0x0,0x1,0x1d - 74: .stabs "__1cPgoogle_breakpadBCBg6M_i_:F(0,3);(0,23)",N_FUN,0x0,0x2b,0x0 - 75: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 76: .stabn N_LBRAC,0x0,0x1,0x6 - 77: .stabn N_SLINE,0x0,0x2b,0x6 - 78: .stabn N_SLINE,0x0,0x2b,0x10 - 79: .stabn N_RBRAC,0x0,0x1,0x10 - 80: .stabs "__1cPgoogle_breakpadBCBh6Frk1_pc_:F(0,22);(0,24)=&(0,25)=k(0,20)",N_FUN,0x0,0x2c,0x0 - 81: .stabs "that:p(0,24)",N_PSYM,0x0,0x4,0x8 - 82: .stabn N_LBRAC,0x0,0x1,0x6 - 83: .stabn N_SLINE,0x0,0x2c,0x6 - 84: .stabn N_SLINE,0x0,0x2c,0x10 - 85: .stabn N_RBRAC,0x0,0x1,0x10 - 86: .stabs "__1cPgoogle_breakpadBC2T5B6M_v_:F(0,13);(0,23)",N_FUN,0x0,0x25,0x0 - 87: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 88: .stabn N_LBRAC,0x0,0x1,0x3 - 89: .stabn N_SLINE,0x0,0x25,0xf - 90: .stabn N_RBRAC,0x0,0x1,0xf - 91: .stabs "__SLIP.DELETER__A:f(0,13);(0,23);(0,3)",N_FUN,0x0,0x25,0x0 - 92: .stabs "this:p(0,23)",N_PSYM,0x0,0x4,0x8 - 93: .stabs "delete:p(0,3)",N_PSYM,0x0,0x4,0xc - 94: .stabn N_LBRAC,0x0,0x1,0x3 - 95: .stabn N_LBRAC,0x0,0x2,0x3 - 96: .stabn N_RBRAC,0x0,0x2,0x28 - 97: .stabn N_RBRAC,0x0,0x1,0x28 - 98: .stabs "true:l(0,18);1",N_LSYM,0x0,0x4,0x0 - 99: .stabs "false:l(0,18);0",N_LSYM,0x0,0x4,0x0 - 100: .stabs "__1c2k6Fpv_v_:P(0,13);(0,26)=*(0,13)",N_FUN,0x0,0x0,0x0 - 101: .stabs "__1cPgoogle_breakpadBC2t5B6M_v_:F__1cPgoogle_breakpadBC2t6M_v_",N_ALIAS,0x0,0x0,0x0 - 102: .stabs "cbD__RTTI__1nPgoogle_breakpadBC_(0,19):YR(0,20)",N_LSYM,0x0,0x0,0x0 - 103: .stabn N_ENDM,0x0,0x0,0x0 - - -Index Stab table -- 17 entries - - 0: .stabs "dump_syms_regtest.cc",N_UNDF,0x0,0x10,0x3b1 - 1: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/",N_SO,0x0,0x0,0x0 - 2: .stabs "dump_syms_regtest.cc",N_SO,0x0,0x4,0x0 - 3: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata",N_OBJ,0x0,0x0,0x0 - 4: .stabs "dump_syms_regtest.o",N_OBJ,0x0,0x0,0x0 - 5: .stabs "V=9.0;DBG_GEN=5.0.8;dm;cd;backend;ptf;ptx;ptk;s;g;R=5.8<>;G=.XAB6Z2hOiL$Gl1b.;A=2",N_OPT,0x0,0x0,0x46fcb88e - 6: .stabs "/export/home/alfred/cvs/breakpad/google-breakpad20070927/src/tools/solaris/dump_syms/testdata/; /ws/on10-tools-prc/SUNWspro/SS11/prod/bin/CC -g -xs -xdebugformat=stabs -I../../.. -I../../../common/solaris -D_REENTRANT -xs dump_syms_regtest.cc -Qoption ccfe -prefix -Qoption ccfe .XAB6Z2hOiL\$Gl1b.",N_CMDLINE,0x0,0x0,0x0 - 7: .stabs "__1nPgoogle_breakpadBC_:U",N_ESYM,0x0,0x0,0x0 - 8: .stabs "main",N_MAIN,0x0,0x0,0x0 - 9: .stabs "main",N_FUN,0x0,0x0,0x0 - 10: .stabs "__1cPgoogle_breakpadBC2t6M_v_",N_FUN,0x0,0x0,0x0 - 11: .stabs "__1cPgoogle_breakpadBC2T6M_v_",N_FUN,0x0,0x0,0x0 - 12: .stabs "__1cPgoogle_breakpadBCKset_member6Mi_v_",N_FUN,0x0,0x0,0x0 - 13: .stabs "__1cPgoogle_breakpadBCBf6M_v_",N_FUN,0x0,0x0,0x0 - 14: .stabs "__1cPgoogle_breakpadBCBg6M_i_",N_FUN,0x0,0x0,0x0 - 15: .stabs "__1cPgoogle_breakpadBCBh6Frk1_pc_",N_FUN,0x0,0x0,0x0 - 16: .stabs "__1cPgoogle_breakpadBC2T5B6M_v_",N_FUN,0x0,0x0,0x0 diff --git a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym b/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym deleted file mode 100644 index 44d3c5391..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym +++ /dev/null @@ -1,33 +0,0 @@ -MODULE solaris x86 3DC8191474338D8587339B5FB3E2C62A0 dump_syms_regtest.o -FILE 0 dump_syms_regtest.cc -FUNC 0 156 0 main -12 18 57 0 -1e 12 58 0 -36 24 59 0 -42 12 60 0 -57 21 61 0 -6c 21 63 0 -9c 48 64 0 -FUNC 0 16 0 int google_breakpad::i() -6 6 51 0 -10 10 52 0 -FUNC 0 37 0 google_breakpad::C::C() -25 37 36 0 -FUNC 0 3 0 google_breakpad::C::~C() -3 3 37 0 -FUNC 0 12 0 void google_breakpad::C::set_member(int) -3 3 39 0 -c 9 39 0 -FUNC 0 29 0 void google_breakpad::C::f() -3 3 42 0 -1d 26 42 0 -FUNC 0 16 0 int google_breakpad::C::g() -6 6 43 0 -10 10 43 0 -FUNC 0 16 0 char*google_breakpad::C::h(const google_breakpad::C&) -6 6 44 0 -10 10 44 0 -FUNC 0 15 0 google_breakpad::C::~C #Nvariant 1() -f 15 37 0 -FUNC 0 0 0 __SLIP.DELETER__A -FUNC 0 0 0 void operator delete(void*) diff --git a/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp b/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp deleted file mode 100644 index e6a4210fe..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/tools.gyp +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'conditions': [ - ['OS=="mac"', { - 'includes': ['mac/tools_mac.gypi'], - }], - ['OS=="linux"', { - 'includes': ['linux/tools_linux.gypi'], - }], - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe deleted file mode 100644 index ca4676f50..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/dump_syms.exe and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe b/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe deleted file mode 100644 index ba319b269..000000000 Binary files a/toolkit/crashreporter/google-breakpad/src/tools/windows/binaries/symupload.exe and /dev/null differ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc deleted file mode 100644 index dd3f770f5..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.cc +++ /dev/null @@ -1,576 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ms_symbol_server_converter.cc: Obtain symbol files from a Microsoft -// symbol server, and convert them to Breakpad's dumped format. -// -// See ms_symbol_server_converter.h for documentation. -// -// Author: Mark Mentovai - -#include -#include - -#include -#include - -#include "tools/windows/converter/ms_symbol_server_converter.h" -#include "common/windows/pdb_source_line_writer.h" -#include "common/windows/string_utils-inl.h" - -// SYMOPT_NO_PROMPTS is not defined in earlier platform SDKs. Define it -// in that case, in the event that this code is used with a newer version -// of DbgHelp at runtime that recognizes the option. The presence of this -// bit in the symbol options should not harm earlier versions of DbgHelp. -#ifndef SYMOPT_NO_PROMPTS -#define SYMOPT_NO_PROMPTS 0x00080000 -#endif // SYMOPT_NO_PROMPTS - -namespace google_breakpad { - -// Use sscanf_s if it is available, to quench the warning about scanf being -// deprecated. Use scanf where sscanf_is not available. Note that the -// parameters passed to sscanf and sscanf_s are only compatible as long as -// fields of type c, C, s, S, and [ are not used. -#if _MSC_VER >= 1400 // MSVC 2005/8 -#define SSCANF sscanf_s -#else // _MSC_VER >= 1400 -#define SSCANF sscanf -#endif // _MSC_VER >= 1400 - -bool GUIDOrSignatureIdentifier::InitializeFromString( - const string &identifier) { - type_ = TYPE_NONE; - - size_t length = identifier.length(); - - if (length > 32 && length <= 40) { - // GUID - if (SSCANF(identifier.c_str(), - "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X", - &guid_.Data1, &guid_.Data2, &guid_.Data3, - &guid_.Data4[0], &guid_.Data4[1], - &guid_.Data4[2], &guid_.Data4[3], - &guid_.Data4[4], &guid_.Data4[5], - &guid_.Data4[6], &guid_.Data4[7], - &age_) != 12) { - return false; - } - - type_ = TYPE_GUID; - } else if (length > 8 && length <= 15) { - // Signature - if (SSCANF(identifier.c_str(), "%08X%x", &signature_, &age_) != 2) { - return false; - } - - type_ = TYPE_SIGNATURE; - } else { - return false; - } - - return true; -} - -#undef SSCANF - -MSSymbolServerConverter::MSSymbolServerConverter( - const string &local_cache, const vector &symbol_servers) - : symbol_path_(), - fail_dns_(false), - fail_timeout_(false), - fail_not_found_(false) { - // Setting local_cache can be done without verifying that it exists because - // SymSrv will create it if it is missing - any creation failures will occur - // at that time, so there's nothing to check here, making it safe to - // assign this in the constructor. - - assert(symbol_servers.size() > 0); - -#if !defined(NDEBUG) - // These are characters that are interpreted as having special meanings in - // symbol_path_. - const char kInvalidCharacters[] = "*;"; - assert(local_cache.find_first_of(kInvalidCharacters) == string::npos); -#endif // !defined(NDEBUG) - - for (vector::const_iterator symbol_server = symbol_servers.begin(); - symbol_server != symbol_servers.end(); - ++symbol_server) { - // The symbol path format is explained by - // http://msdn.microsoft.com/library/en-us/debug/base/using_symsrv.asp . - // "srv*" is the same as "symsrv*symsrv.dll*", which means that - // symsrv.dll is to be responsible for locating symbols. symsrv.dll - // interprets the rest of the string as a series of symbol stores separated - // by '*'. "srv*local_cache*symbol_server" means to check local_cache - // first for the symbol file, and if it is not found there, to check - // symbol_server. Symbol files found on the symbol server will be placed - // in the local cache, decompressed. - // - // Multiple specifications in this format may be presented, separated by - // semicolons. - - assert((*symbol_server).find_first_of(kInvalidCharacters) == string::npos); - symbol_path_ += "srv*" + local_cache + "*" + *symbol_server + ";"; - } - - // Strip the trailing semicolon. - symbol_path_.erase(symbol_path_.length() - 1); -} - -// A stack-based class that manages SymInitialize and SymCleanup calls. -class AutoSymSrv { - public: - AutoSymSrv() : initialized_(false) {} - - ~AutoSymSrv() { - if (!Cleanup()) { - // Print the error message here, because destructors have no return - // value. - fprintf(stderr, "~AutoSymSrv: SymCleanup: error %d\n", GetLastError()); - } - } - - bool Initialize(HANDLE process, char *path, bool invade_process) { - process_ = process; - initialized_ = SymInitialize(process, path, invade_process) == TRUE; - return initialized_; - } - - bool Cleanup() { - if (initialized_) { - if (SymCleanup(process_)) { - initialized_ = false; - return true; - } - return false; - } - - return true; - } - - private: - HANDLE process_; - bool initialized_; -}; - -// A stack-based class that "owns" a pathname and deletes it when destroyed, -// unless told not to by having its Release() method called. Early deletions -// are supported by calling Delete(). -class AutoDeleter { - public: - explicit AutoDeleter(const string &path) : path_(path) {} - - ~AutoDeleter() { - int error; - if ((error = Delete()) != 0) { - // Print the error message here, because destructors have no return - // value. - fprintf(stderr, "~AutoDeleter: Delete: error %d for %s\n", - error, path_.c_str()); - } - } - - int Delete() { - if (path_.empty()) - return 0; - - int error = remove(path_.c_str()); - Release(); - return error; - } - - void Release() { - path_.clear(); - } - - private: - string path_; -}; - -MSSymbolServerConverter::LocateResult -MSSymbolServerConverter::LocateFile(const string &debug_or_code_file, - const string &debug_or_code_id, - const string &version, - string *file_name) { - assert(file_name); - file_name->clear(); - - GUIDOrSignatureIdentifier identifier; - if (!identifier.InitializeFromString(debug_or_code_id)) { - fprintf(stderr, - "LocateFile: Unparseable identifier for %s %s %s\n", - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_FAILURE; - } - - HANDLE process = GetCurrentProcess(); // CloseHandle is not needed. - AutoSymSrv symsrv; - if (!symsrv.Initialize(process, - const_cast(symbol_path_.c_str()), - false)) { - fprintf(stderr, "LocateFile: SymInitialize: error %d for %s %s %s\n", - GetLastError(), - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_FAILURE; - } - - if (!SymRegisterCallback64(process, SymCallback, - reinterpret_cast(this))) { - fprintf(stderr, - "LocateFile: SymRegisterCallback64: error %d for %s %s %s\n", - GetLastError(), - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_FAILURE; - } - - // SYMOPT_DEBUG arranges for SymCallback to be called with additional - // debugging information. This is used to determine the nature of failures. - DWORD options = SymGetOptions() | SYMOPT_DEBUG | SYMOPT_NO_PROMPTS | - SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_SECURE; - SymSetOptions(options); - - // SymCallback will set these as needed inisde the SymFindFileInPath call. - fail_dns_ = false; - fail_timeout_ = false; - fail_not_found_ = false; - - // Do the lookup. - char path[MAX_PATH]; - if (!SymFindFileInPath( - process, NULL, - const_cast(debug_or_code_file.c_str()), - const_cast(identifier.guid_or_signature_pointer()), - identifier.age(), 0, - identifier.type() == GUIDOrSignatureIdentifier::TYPE_GUID ? - SSRVOPT_GUIDPTR : SSRVOPT_DWORDPTR, - path, SymFindFileInPathCallback, this)) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) { - // This can be returned for a number of reasons. Use the crumbs - // collected by SymCallback to determine which one is relevant. - - // These errors are possibly transient. - if (fail_dns_ || fail_timeout_) { - return LOCATE_RETRY; - } - - // This is an authoritiative file-not-found message. - if (fail_not_found_) { - fprintf(stderr, - "LocateFile: SymFindFileInPath: LOCATE_NOT_FOUND error " - "for %s %s %s\n", - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_NOT_FOUND; - } - - // If the error is FILE_NOT_FOUND but none of the known error - // conditions are matched, fall through to LOCATE_FAILURE. - } - - fprintf(stderr, - "LocateFile: SymFindFileInPath: error %d for %s %s %s\n", - error, - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_FAILURE; - } - - // Making sure path is null-terminated. - path[MAX_PATH - 1] = '\0'; - - // The AutoDeleter ensures that the file is only kept when returning - // LOCATE_SUCCESS. - AutoDeleter deleter(path); - - // Do the cleanup here even though it will happen when symsrv goes out of - // scope, to allow it to influence the return value. - if (!symsrv.Cleanup()) { - fprintf(stderr, "LocateFile: SymCleanup: error %d for %s %s %s\n", - GetLastError(), - debug_or_code_file.c_str(), - debug_or_code_id.c_str(), - version.c_str()); - return LOCATE_FAILURE; - } - - deleter.Release(); - - printf("Downloaded: %s\n", path); - *file_name = path; - return LOCATE_SUCCESS; -} - - -MSSymbolServerConverter::LocateResult -MSSymbolServerConverter::LocatePEFile(const MissingSymbolInfo &missing, - string *pe_file) { - return LocateFile(missing.code_file, missing.code_identifier, - missing.version, pe_file); -} - -MSSymbolServerConverter::LocateResult -MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, - string *symbol_file) { - return LocateFile(missing.debug_file, missing.debug_identifier, - missing.version, symbol_file); -} - - -// static -BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process, - ULONG action, - ULONG64 data, - ULONG64 context) { - MSSymbolServerConverter *self = - reinterpret_cast(context); - - switch (action) { - case CBA_EVENT: { - IMAGEHLP_CBA_EVENT *cba_event = - reinterpret_cast(data); - - // Put the string into a string object to be able to use string::find - // for substring matching. This is important because the not-found - // message does not use the entire string but is appended to the URL - // that SymSrv attempted to retrieve. - string desc(cba_event->desc); - - // desc_action maps strings (in desc) to boolean pointers that are to - // be set to true if the string matches. - struct desc_action { - const char *desc; // The substring to match. - bool *action; // On match, this pointer will be set to true. - }; - - static const desc_action desc_actions[] = { - // When a DNS error occurs, it could be indiciative of network - // problems. - { "SYMSRV: The server name or address could not be resolved\n", - &self->fail_dns_ }, - - // This message is produced if no connection is opened. - { "SYMSRV: A connection with the server could not be established\n", - &self->fail_timeout_ }, - - // This message is produced if a connection is established but the - // server fails to respond to the HTTP request. - { "SYMSRV: The operation timed out\n", - &self->fail_timeout_ }, - - // This message is produced when the requested file is not found, - // even if one or more of the above messages are also produced. - // It's trapped to distinguish between not-found and unknown-failure - // conditions. Note that this message will not be produced if a - // connection is established and the server begins to respond to the - // HTTP request but does not finish transmitting the file. - { " not found\n", - &self->fail_not_found_ } - }; - - for (int desc_action_index = 0; - desc_action_index < sizeof(desc_actions) / sizeof(desc_action); - ++desc_action_index) { - if (desc.find(desc_actions[desc_action_index].desc) != string::npos) { - *(desc_actions[desc_action_index].action) = true; - break; - } - } - - break; - } - } - - // This function is a mere fly on the wall. Treat everything as unhandled. - return FALSE; -} - -// static -BOOL CALLBACK MSSymbolServerConverter::SymFindFileInPathCallback( - const char *filename, void *context) { - // FALSE ends the search, indicating that the located symbol file is - // satisfactory. - return FALSE; -} - -MSSymbolServerConverter::LocateResult -MSSymbolServerConverter::LocateAndConvertSymbolFile( - const MissingSymbolInfo &missing, - bool keep_symbol_file, - bool keep_pe_file, - string *converted_symbol_file, - string *symbol_file, - string *out_pe_file) { - assert(converted_symbol_file); - converted_symbol_file->clear(); - if (symbol_file) { - symbol_file->clear(); - } - - string pdb_file; - LocateResult result = LocateSymbolFile(missing, &pdb_file); - if (result != LOCATE_SUCCESS) { - return result; - } - - if (symbol_file && keep_symbol_file) { - *symbol_file = pdb_file; - } - - // The conversion of a symbol file for a Windows 64-bit module requires - // loading of the executable file. If there is no executable file, convert - // using only the PDB file. Without an executable file, the conversion will - // fail for 64-bit modules but it should succeed for 32-bit modules. - string pe_file; - result = LocatePEFile(missing, &pe_file); - if (result != LOCATE_SUCCESS) { - fprintf(stderr, "WARNING: Could not download: %s\n", pe_file.c_str()); - } - - if (out_pe_file && keep_pe_file) { - *out_pe_file = pe_file; - } - - // Conversion may fail because the file is corrupt. If a broken file is - // kept in the local cache, LocateSymbolFile will not hit the network again - // to attempt to locate it. To guard against problems like this, the - // symbol file in the local cache will be removed if conversion fails. - AutoDeleter pdb_deleter(pdb_file); - AutoDeleter pe_deleter(pe_file); - - // Be sure that it's a .pdb file, since we'll be replacing .pdb with .sym - // for the converted file's name. - string pdb_extension = pdb_file.substr(pdb_file.length() - 4); - // strcasecmp is called _stricmp here. - if (_stricmp(pdb_extension.c_str(), ".pdb") != 0) { - fprintf(stderr, "LocateAndConvertSymbolFile: " - "no .pdb extension for %s %s %s %s\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str(), - pdb_file.c_str()); - return LOCATE_FAILURE; - } - - PDBSourceLineWriter writer; - wstring pe_file_w; - if (!WindowsStringUtils::safe_mbstowcs(pe_file, &pe_file_w)) { - fprintf(stderr, - "LocateAndConvertSymbolFile: " - "WindowsStringUtils::safe_mbstowcs failed for %s\n", - pe_file.c_str()); - return LOCATE_FAILURE; - } - wstring pdb_file_w; - if (!WindowsStringUtils::safe_mbstowcs(pdb_file, &pdb_file_w)) { - fprintf(stderr, - "LocateAndConvertSymbolFile: " - "WindowsStringUtils::safe_mbstowcs failed for %s\n", - pdb_file_w.c_str()); - return LOCATE_FAILURE; - } - if (!writer.Open(pdb_file_w, PDBSourceLineWriter::PDB_FILE)) { - fprintf(stderr, - "ERROR: PDBSourceLineWriter::Open failed for %s %s %s %ws\n", - missing.debug_file.c_str(), missing.debug_identifier.c_str(), - missing.version.c_str(), pdb_file_w.c_str()); - return LOCATE_FAILURE; - } - if (!writer.SetCodeFile(pe_file_w)) { - fprintf(stderr, - "ERROR: PDBSourceLineWriter::SetCodeFile failed for %s %s %s %ws\n", - missing.debug_file.c_str(), missing.debug_identifier.c_str(), - missing.version.c_str(), pe_file_w.c_str()); - return LOCATE_FAILURE; - } - - *converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym"; - - FILE *converted_output = NULL; -#if _MSC_VER >= 1400 // MSVC 2005/8 - errno_t err; - if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w")) - != 0) { -#else // _MSC_VER >= 1400 - // fopen_s and errno_t were introduced in MSVC8. Use fopen for earlier - // environments. Don't use fopen with MSVC8 and later, because it's - // deprecated. fopen does not provide reliable error codes, so just use - // -1 in the event of a failure. - int err; - if (!(converted_output = fopen(converted_symbol_file->c_str(), "w"))) { - err = -1; -#endif // _MSC_VER >= 1400 - fprintf(stderr, "LocateAndConvertSymbolFile: " - "fopen_s: error %d for %s %s %s %s\n", - err, - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str(), - converted_symbol_file->c_str()); - return LOCATE_FAILURE; - } - - AutoDeleter sym_deleter(*converted_symbol_file); - - bool success = writer.WriteMap(converted_output); - fclose(converted_output); - - if (!success) { - fprintf(stderr, "LocateAndConvertSymbolFile: " - "PDBSourceLineWriter::WriteMap failed for %s %s %s %s\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str(), - pdb_file.c_str()); - return LOCATE_FAILURE; - } - - if (keep_symbol_file) { - pdb_deleter.Release(); - } - - if (keep_pe_file) { - pe_deleter.Release(); - } - - sym_deleter.Release(); - - return LOCATE_SUCCESS; -} - -} // namespace google_breakpad diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp deleted file mode 100644 index 57ec79068..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.gyp +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2013 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'ms_symbol_server_converter', - 'type': 'static_library', - 'msvs_guid': '1463C4CD-23FC-4DE9-BFDE-283338200157', - 'sources': [ - 'ms_symbol_server_converter.cc', - ], - 'dependencies': [ - '../../../common/windows/common_windows.gyp:common_windows_lib', - ], - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h b/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h deleted file mode 100644 index d601b4333..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ms_symbol_server_converter.h: Obtain symbol files from a Microsoft -// symbol server, and convert them to Breakpad's dumped format. -// -// At runtime, MSSymbolServerConverter and code that it calls depend on being -// able to locate suitable versions of dbghelp.dll and symsrv.dll. For best -// results, place these files in the same directory as the executable. -// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are -// both redistributable, as indicated by the package's redist.txt file. -// -// When connecting to Microsoft's symbol server at -// http://msdl.microsoft.com/download/symbols/, which provides access to -// symbols for the operating system itself, symsrv.dll requires agreement to -// Microsoft's "Terms of Use for Microsoft Symbols and Binaries." Because this -// library places the symbol engine into a promptless mode, the dialog with the -// terms will not appear, and use of Microsoft's symbol server will not be -// possible. To indicate agreement to the terms, create a file called -// symsrv.yes in the same directory as symsrv.dll. (Note that symsrv.dll will -// also recognize a symsrv.no file as indicating that you do not accept the -// terms; the .yes file takes priority over the .no file.) The terms of use -// are contained within symsrv.dll; they were formerly available online at -// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but -// do not appear to be available online any longer as of January, 2007. It is -// possible to view the terms from within WinDbg (Debugging Tools for Windows) -// by removing any symsrv.yes and symsrv.no files from WinDbg's directory, -// setting the symbol path to include Microsoft's symbol server (.sympath), and -// attempting to load symbols from their server (.reload). -// -// This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8, -// included with Microsoft Visual Studio 8 in Common7/IDE. This has also been -// tested with dbghelp.dll and symsrv.dll versions 6.6.7.5 and 6.12.2.633, -// included with the same versions of Debugging Tools for Windows, available at -// http://www.microsoft.com/whdc/devtools/debugging/ . -// -// Author: Mark Mentovai - -#ifndef TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ -#define TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ - -#include - -#include -#include - -namespace google_breakpad { - -using std::string; -using std::vector; - -// MissingSymbolInfo contains the subset of the information in the processor's -// CodeModule structure relevant to obtaining a missing symbol file. Only -// debug_file and debug_identifier are relevant in actually obtaining the -// missing file; the other fields are for convenience. -struct MissingSymbolInfo { - string code_file; - string code_identifier; - string debug_file; - string debug_identifier; - string version; -}; - -class GUIDOrSignatureIdentifier { - public: - enum GUIDOrSignatureType { - TYPE_NONE = 0, - TYPE_GUID, - TYPE_SIGNATURE - }; - - GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {} - - // Converts |identifier|, a debug_identifier-formatted string, into its - // component fields: either a GUID and age, or signature and age. If - // successful, sets the relevant fields in the object, including the type - // field, and returns true. On error, returns false. - bool InitializeFromString(const string &identifier); - - GUIDOrSignatureType type() const { return type_; } - GUID guid() const { return guid_; } - DWORD signature() const { return signature_; } - int age() const { return age_; } - const void *guid_or_signature_pointer() const { return &guid_; } - - private: - GUIDOrSignatureType type_; - - // An identifier contains either a 128-bit uuid or a 32-bit signature. - union { - GUID guid_; - DWORD signature_; - }; - - // All identifiers used here have age fields, which indicate a specific - // revision given a uuid or signature. - int age_; -}; - -class MSSymbolServerConverter { - public: - enum LocateResult { - LOCATE_FAILURE = 0, - LOCATE_NOT_FOUND, // Authoritative: the file is not present. - LOCATE_RETRY, // Transient (network?) error, try again later. - LOCATE_SUCCESS - }; - - // Create a new object. local_cache is the location (pathname) of a local - // symbol store used to hold downloaded and converted symbol files. This - // directory will be created by LocateSymbolFile when it successfully - // retrieves a symbol file. symbol_servers contains a list of locations (URLs - // or pathnames) of the upstream symbol server stores, given in order of - // preference, with the first string in the vector identifying the first - // store to try. The vector must contain at least one string. None of the - // strings passed to this constructor may contain asterisk ('*') or semicolon - // (';') characters, as the symbol engine uses these characters as separators. - MSSymbolServerConverter(const string &local_cache, - const vector &symbol_servers); - - // Locates the PE file (DLL or EXE) specified by the identifying information - // in |missing|, by checking the symbol stores identified when the object - // was created. When returning LOCATE_SUCCESS, pe_file is set to - // the pathname of the decompressed PE file as it is stored in the - // local cache. - LocateResult LocatePEFile(const MissingSymbolInfo &missing, string *pe_file); - - // Locates the symbol file specified by the identifying information in - // |missing|, by checking the symbol stores identified when the object - // was created. When returning LOCATE_SUCCESS, symbol_file is set to - // the pathname of the decompressed symbol file as it is stored in the - // local cache. - LocateResult LocateSymbolFile(const MissingSymbolInfo &missing, - string *symbol_file); - - // Calls LocateSymbolFile and converts the returned symbol file to the - // dumped-symbol format, storing it adjacent to the symbol file. The - // only conversion supported is from pdb files. Returns the return - // value of LocateSymbolFile, or if LocateSymbolFile succeeds but - // conversion fails, returns LOCATE_FAILURE. The pathname to the - // pdb file and to the converted symbol file are returned in - // |converted_symbol_file|, |symbol_file|, and |pe_file|. |symbol_file| and - // |pe_file| are optional and may be NULL. If only the converted symbol file - // is desired, set |keep_symbol_file| and |keep_pe_file| to false to indicate - // that the original symbol file (pdb) and executable file (exe, dll) should - // be deleted after conversion. - LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing, - bool keep_symbol_file, - bool keep_pe_file, - string *converted_symbol_file, - string *symbol_file, - string *pe_file); - - private: - // Locates the PDB or PE file (DLL or EXE) specified by the identifying - // information in |debug_or_code_file| and |debug_or_code_id|, by checking - // the symbol stores identified when the object was created. When - // returning LOCATE_SUCCESS, file_name is set to the pathname of the - // decompressed PDB or PE file file as it is stored in the local cache. - LocateResult LocateFile(const string &debug_or_code_file, - const string &debug_or_code_id, - const string &version, string *file_name); - - // Called by various SymSrv functions to report status as progress is made - // and to allow the callback to influence processing. Messages sent to this - // callback can be used to distinguish between the various failure modes - // that SymFindFileInPath might encounter. - static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data, - ULONG64 context); - - // Called by SymFindFileInPath (in LocateSymbolFile) after a candidate - // symbol file is located, when it's present in the local cache. - // SymFindFileInPath actually seems to accept NULL for a callback function - // and behave properly for our needs in that case, but the documentation - // doesn't mention it, so this little callback is provided. - static BOOL CALLBACK SymFindFileInPathCallback(const char *filename, - void *context); - - // The search path used by SymSrv, built based on the arguments to the - // constructor. - string symbol_path_; - - // SymCallback will set at least one of these failure variables if - // SymFindFileInPath fails for an expected reason. - bool fail_dns_; // DNS failures (fail_not_found_ will also be set). - bool fail_timeout_; // Timeouts (fail_not_found_ will also be set). - bool fail_not_found_; // The file could not be found. If this is the only - // fail_* member set, then it is authoritative. -}; - -} // namespace google_breakpad - -#endif // TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc deleted file mode 100644 index 3e8827b61..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Windows utility to dump the line number data from a pdb file to -// a text-based format that we can use from the minidump processor. - -#include - -#include - -#include "common/windows/pdb_source_line_writer.h" - -using std::wstring; -using google_breakpad::PDBSourceLineWriter; - -int wmain(int argc, wchar_t **argv) { - if (argc < 2) { - fprintf(stderr, "Usage: %ws \n", argv[0]); - return 1; - } - - PDBSourceLineWriter writer; - if (!writer.Open(wstring(argv[1]), PDBSourceLineWriter::ANY_FILE)) { - fprintf(stderr, "Open failed\n"); - return 1; - } - - if (!writer.WriteMap(stdout)) { - fprintf(stderr, "WriteMap failed\n"); - return 1; - } - - writer.Close(); - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp deleted file mode 100644 index b815574b2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms.gyp +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2013 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'dump_syms', - 'type': 'executable', - 'sources': [ - 'dump_syms.cc', - ], - 'dependencies': [ - '../../../common/windows/common_windows.gyp:common_windows_lib', - ], - }, - { - 'target_name': 'dump_syms_unittest', - 'type': 'executable', - 'sources': [ - 'dump_syms_unittest.cc', - ], - 'dependencies': [ - '<(DEPTH)/client/windows/unittests/testing.gyp:gmock', - '<(DEPTH)/client/windows/unittests/testing.gyp:gtest', - 'dump_syms', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalDependencies': [ - 'shell32.lib', - ], - }, - }, - }, - ], -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc deleted file mode 100644 index 61f84431e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/dump_syms_unittest.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2003 Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include - -#include -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace tools { -namespace windows { -namespace dump_syms { - -namespace { - -// Root names of PDB and dumped symbol files to be regression tested. These are -// specified in complexity of the resulting dumped symbol files. -const wchar_t* kRootNames[] = { - // A PDB file with no OMAP data. - L"dump_syms_regtest", - // A PDB file with OMAP data for an image that has been function-level - // reordered. - L"omap_reorder_funcs", - // A PDB file with OMAP data for an image that had new content injected, all - // of it with source data. - L"omap_stretched_filled", - // A PDB file with OMAP data for an image that had new content injected, but - // without source data. - L"omap_stretched", - // A PDB file with OMAP data for an image that has been basic block reordered. - L"omap_reorder_bbs", - // A 64bit PDB file with no OMAP data. - L"dump_syms_regtest64", -}; - -void TrimLastComponent(const std::wstring& path, - std::wstring* trimmed, - std::wstring* component) { - size_t len = path.size(); - while (len > 0 && path[len - 1] != '\\') - --len; - - if (component != NULL) - component->assign(path.c_str() + len, path.c_str() + path.size()); - - while (len > 0 && path[len - 1] == '\\') - --len; - - if (trimmed != NULL) - trimmed->assign(path.c_str(), len); -} - -// Get the directory of the current executable. -bool GetSelfDirectory(std::wstring* self_dir) { - std::wstring command_line = GetCommandLineW(); - - int num_args = 0; - wchar_t** args = NULL; - args = ::CommandLineToArgvW(command_line.c_str(), &num_args); - if (args == NULL) - return false; - - *self_dir = args[0]; - TrimLastComponent(*self_dir, self_dir, NULL); - - return true; -} - -void RunCommand(const std::wstring& command_line, - std::string* stdout_string) { - // Create a PIPE for the child process stdout. - HANDLE child_stdout_read = 0; - HANDLE child_stdout_write = 0; - SECURITY_ATTRIBUTES sec_attr_stdout = {}; - sec_attr_stdout.nLength = sizeof(sec_attr_stdout); - sec_attr_stdout.bInheritHandle = TRUE; - ASSERT_TRUE(::CreatePipe(&child_stdout_read, &child_stdout_write, - &sec_attr_stdout, 0)); - ASSERT_TRUE(::SetHandleInformation(child_stdout_read, HANDLE_FLAG_INHERIT, - 0)); - - // Create a PIPE for the child process stdin. - HANDLE child_stdin_read = 0; - HANDLE child_stdin_write = 0; - SECURITY_ATTRIBUTES sec_attr_stdin = {}; - sec_attr_stdin.nLength = sizeof(sec_attr_stdin); - sec_attr_stdin.bInheritHandle = TRUE; - ASSERT_TRUE(::CreatePipe(&child_stdin_read, &child_stdin_write, - &sec_attr_stdin, 0)); - ASSERT_TRUE(::SetHandleInformation(child_stdin_write, HANDLE_FLAG_INHERIT, - 0)); - - // Startup the child. - STARTUPINFO startup_info = {}; - PROCESS_INFORMATION process_info = {}; - startup_info.cb = sizeof(STARTUPINFO); - startup_info.hStdError = child_stdout_write; - startup_info.hStdInput = child_stdin_read; - startup_info.hStdOutput = child_stdout_write; - startup_info.dwFlags = STARTF_USESTDHANDLES; - ASSERT_TRUE(::CreateProcessW(NULL, (LPWSTR)command_line.c_str(), NULL, NULL, - TRUE, 0, NULL, NULL, - &startup_info, &process_info)); - - // Collect the output. - ASSERT_TRUE(::CloseHandle(child_stdout_write)); - char buffer[4096] = {}; - DWORD bytes_read = 0; - while (::ReadFile(child_stdout_read, buffer, sizeof(buffer), &bytes_read, - NULL) && bytes_read > 0) { - stdout_string->append(buffer, bytes_read); - } - - // Wait for the process to finish. - ::WaitForSingleObject(process_info.hProcess, INFINITE); - - // Shut down all of our handles. - ASSERT_TRUE(::CloseHandle(process_info.hThread)); - ASSERT_TRUE(::CloseHandle(process_info.hProcess)); - ASSERT_TRUE(::CloseHandle(child_stdin_write)); - ASSERT_TRUE(::CloseHandle(child_stdin_read)); - ASSERT_TRUE(::CloseHandle(child_stdout_read)); -} - -void GetFileContents(const std::wstring& path, std::string* content) { - FILE* f = ::_wfopen(path.c_str(), L"rb"); - ASSERT_TRUE(f != NULL); - - char buffer[4096] = {}; - while (true) { - size_t bytes_read = ::fread(buffer, 1, sizeof(buffer), f); - if (bytes_read == 0) - break; - content->append(buffer, bytes_read); - } -} - -class DumpSymsRegressionTest : public testing::Test { - public: - virtual void SetUp() { - std::wstring self_dir; - ASSERT_TRUE(GetSelfDirectory(&self_dir)); - dump_syms_exe = self_dir + L"\\dump_syms.exe"; - - TrimLastComponent(self_dir, &testdata_dir, NULL); - testdata_dir += L"\\testdata"; - } - - std::wstring dump_syms_exe; - std::wstring testdata_dir; -}; - -} //namespace - -TEST_F(DumpSymsRegressionTest, EnsureDumpedSymbolsMatch) { - for (size_t i = 0; i < sizeof(kRootNames) / sizeof(kRootNames[0]); ++i) { - const wchar_t* root_name = kRootNames[i]; - std::wstring root_path = testdata_dir + L"\\" + root_name; - - std::wstring sym_path = root_path + L".sym"; - std::string expected_symbols; - ASSERT_NO_FATAL_FAILURE(GetFileContents(sym_path, &expected_symbols)); - - std::wstring pdb_path = root_path + L".pdb"; - std::wstring command_line = L"\"" + dump_syms_exe + L"\" \"" + - pdb_path + L"\""; - std::string symbols; - ASSERT_NO_FATAL_FAILURE(RunCommand(command_line, &symbols)); - - EXPECT_EQ(expected_symbols, symbols); - } -} - -} // namespace dump_syms -} // namespace windows -} // namespace tools \ No newline at end of file diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build deleted file mode 100644 index 2a286da53..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/moz.build +++ /dev/null @@ -1,31 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HostProgram('dump_syms') - -HOST_SOURCES += [ - '../../../common/windows/dia_util.cc', - '../../../common/windows/guid_string.cc', - '../../../common/windows/omap.cc', - '../../../common/windows/pdb_source_line_writer.cc', - '../../../common/windows/string_utils.cc', - 'dump_syms.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-EHsc', - '-MD' -] - -HOST_OS_LIBS += [ - 'diaguids', - 'imagehlp' -] - -LOCAL_INCLUDES += [ - '../../..' -] diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh b/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh deleted file mode 100755 index 1f20f64fd..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/dump_syms/run_regtest.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2006, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Release/dump_syms.exe testdata/dump_syms_regtest.pdb | \ - tr -d '\015' > \ - testdata/dump_syms_regtest.new -status=$? - -if [ $status -ne 0 ] ; then - echo "FAIL, dump_syms.exe failed" - exit $status -fi - -diff -u testdata/dump_syms_regtest.new testdata/dump_syms_regtest.sym > \ - testdata/dump_syms_regtest.diff -status=$? - -if [ $status -eq 0 ] ; then - rm testdata/dump_syms_regtest.diff testdata/dump_syms_regtest.new - echo "PASS" -else - echo "FAIL, see testdata/dump_syms_regtest.[new|diff]" -fi - -exit $status diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat b/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat deleted file mode 100644 index d881ae64b..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/refresh_binaries.bat +++ /dev/null @@ -1,27 +0,0 @@ -REM This batch file is meant to facilitate regenerating prebuilt binaries for -REM the Windows tools. -REM You MUST run it from a Visual Studio xxxx Command Prompt. To do this, -REM navigate to: -REM -REM Start->Programs->Microsoft Visual Studio XXXX->Tools-> -REM Visual Studio Command Prompt -REM -REM Then run this batch file. It performs an SVN update, edits the -REM README.binaries file to contain -REM the revision number, and builds the tools. You must run 'svn commit' to -REM commit the pending edits to the repository. - -pushd %~dp0\..\..\ -call svn update --accept postpone -cd tools\windows -devenv symupload\symupload.vcproj /rebuild Release -copy symupload\Release\symupload.exe binaries\ -REM switch back to top level so that 'svn info' displays useful information. -cd ..\..\ -echo This checkin of the binaries was created by refresh_binaries.bat. > %TEMP%\checkin.txt -echo Date: %DATE% %TIME% >> %TEMP%\checkin.txt -echo Repository information (output of 'svn info') follows: >> %TEMP%\checkin.txt -call svn info >> %TEMP%\checkin.txt -echo Done! -echo type 'svn commit -F %%TEMP%%\checkin.txt' to commit. -popd diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc deleted file mode 100644 index fa5294ded..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.cc +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Tool to upload an exe/dll and its associated symbols to an HTTP server. -// The PDB file is located automatically, using the path embedded in the -// executable. The upload is sent as a multipart/form-data POST request, -// with the following parameters: -// code_file: the basename of the module, e.g. "app.exe" -// debug_file: the basename of the debugging file, e.g. "app.pdb" -// debug_identifier: the debug file's identifier, usually consisting of -// the guid and age embedded in the pdb, e.g. -// "11111111BBBB3333DDDD555555555555F" -// product: the HTTP-friendly product name, e.g. "MyApp" -// version: the file version of the module, e.g. "1.2.3.4" -// os: the operating system that the module was built for, always -// "windows" in this implementation. -// cpu: the CPU that the module was built for, typically "x86". -// symbol_file: the contents of the breakpad-format symbol file - -#include -#include -#include - -#include -#include -#include -#include - -#include "common/windows/string_utils-inl.h" - -#include "common/windows/http_upload.h" -#include "common/windows/pdb_source_line_writer.h" - -using std::string; -using std::wstring; -using std::vector; -using std::map; -using google_breakpad::HTTPUpload; -using google_breakpad::PDBModuleInfo; -using google_breakpad::PDBSourceLineWriter; -using google_breakpad::WindowsStringUtils; - -// Extracts the file version information for the given filename, -// as a string, for example, "1.2.3.4". Returns true on success. -static bool GetFileVersionString(const wchar_t *filename, wstring *version) { - DWORD handle; - DWORD version_size = GetFileVersionInfoSize(filename, &handle); - if (version_size < sizeof(VS_FIXEDFILEINFO)) { - return false; - } - - vector version_info(version_size); - if (!GetFileVersionInfo(filename, handle, version_size, &version_info[0])) { - return false; - } - - void *file_info_buffer = NULL; - unsigned int file_info_length; - if (!VerQueryValue(&version_info[0], L"\\", - &file_info_buffer, &file_info_length)) { - return false; - } - - // The maximum value of each version component is 65535 (0xffff), - // so the max length is 24, including the terminating null. - wchar_t ver_string[24]; - VS_FIXEDFILEINFO *file_info = - reinterpret_cast(file_info_buffer); - swprintf(ver_string, sizeof(ver_string) / sizeof(ver_string[0]), - L"%d.%d.%d.%d", - file_info->dwFileVersionMS >> 16, - file_info->dwFileVersionMS & 0xffff, - file_info->dwFileVersionLS >> 16, - file_info->dwFileVersionLS & 0xffff); - - // remove when VC++7.1 is no longer supported - ver_string[sizeof(ver_string) / sizeof(ver_string[0]) - 1] = L'\0'; - - *version = ver_string; - return true; -} - -// Creates a new temporary file and writes the symbol data from the given -// exe/dll file to it. Returns the path to the temp file in temp_file_path -// and information about the pdb in pdb_info. -static bool DumpSymbolsToTempFile(const wchar_t *file, - wstring *temp_file_path, - PDBModuleInfo *pdb_info) { - google_breakpad::PDBSourceLineWriter writer; - // Use EXE_FILE to get information out of the exe/dll in addition to the - // pdb. The name and version number of the exe/dll are of value, and - // there's no way to locate an exe/dll given a pdb. - if (!writer.Open(file, PDBSourceLineWriter::EXE_FILE)) { - return false; - } - - wchar_t temp_path[_MAX_PATH]; - if (GetTempPath(_MAX_PATH, temp_path) == 0) { - return false; - } - - wchar_t temp_filename[_MAX_PATH]; - if (GetTempFileName(temp_path, L"sym", 0, temp_filename) == 0) { - return false; - } - - FILE *temp_file = NULL; -#if _MSC_VER >= 1400 // MSVC 2005/8 - if (_wfopen_s(&temp_file, temp_filename, L"w") != 0) -#else // _MSC_VER >= 1400 - // _wfopen_s was introduced in MSVC8. Use _wfopen for earlier environments. - // Don't use it with MSVC8 and later, because it's deprecated. - if (!(temp_file = _wfopen(temp_filename, L"w"))) -#endif // _MSC_VER >= 1400 - { - return false; - } - - bool success = writer.WriteMap(temp_file); - fclose(temp_file); - if (!success) { - _wunlink(temp_filename); - return false; - } - - *temp_file_path = temp_filename; - - return writer.GetModuleInfo(pdb_info); -} - -__declspec(noreturn) void printUsageAndExit() { - wprintf(L"Usage:\n\n" - L" symupload [--timeout NN] [--product product_name] ^\n" - L" ^\n" - L" [...]\n\n"); - wprintf(L" - Timeout is in milliseconds, or can be 0 to be unlimited.\n"); - wprintf(L" - product_name is an HTTP-friendly product name. It must only\n" - L" contain an ascii subset: alphanumeric and punctuation.\n" - L" This string is case-sensitive.\n\n"); - wprintf(L"Example:\n\n" - L" symupload.exe --timeout 0 --product Chrome ^\n" - L" chrome.dll http://no.free.symbol.server.for.you\n"); - exit(0); -} -int wmain(int argc, wchar_t *argv[]) { - const wchar_t *module; - const wchar_t *product = nullptr; - int timeout = -1; - int currentarg = 1; - while (argc > currentarg + 1) { - if (!wcscmp(L"--timeout", argv[currentarg])) { - timeout = _wtoi(argv[currentarg + 1]); - currentarg += 2; - continue; - } - if (!wcscmp(L"--product", argv[currentarg])) { - product = argv[currentarg + 1]; - currentarg += 2; - continue; - } - break; - } - - if (argc >= currentarg + 2) - module = argv[currentarg++]; - else - printUsageAndExit(); - - wstring symbol_file; - PDBModuleInfo pdb_info; - if (!DumpSymbolsToTempFile(module, &symbol_file, &pdb_info)) { - fwprintf(stderr, L"Could not get symbol data from %s\n", module); - return 1; - } - - wstring code_file = WindowsStringUtils::GetBaseName(wstring(module)); - - map parameters; - parameters[L"code_file"] = code_file; - parameters[L"debug_file"] = pdb_info.debug_file; - parameters[L"debug_identifier"] = pdb_info.debug_identifier; - parameters[L"os"] = L"windows"; // This version of symupload is Windows-only - parameters[L"cpu"] = pdb_info.cpu; - - // Don't make a missing product name a hard error. Issue a warning and let - // the server decide whether to reject files without product name. - if (product) { - parameters[L"product"] = product; - } else { - fwprintf( - stderr, - L"Warning: No product name (flag --product) was specified for %s\n", - module); - } - - // Don't make a missing version a hard error. Issue a warning, and let the - // server decide whether to reject files without versions. - wstring file_version; - if (GetFileVersionString(module, &file_version)) { - parameters[L"version"] = file_version; - } else { - fwprintf(stderr, L"Warning: Could not get file version for %s\n", module); - } - - map files; - files[L"symbol_file"] = symbol_file; - - bool success = true; - - while (currentarg < argc) { - int response_code; - if (!HTTPUpload::SendRequest(argv[currentarg], parameters, files, - timeout == -1 ? NULL : &timeout, - nullptr, &response_code)) { - success = false; - fwprintf(stderr, - L"Symbol file upload to %s failed. Response code = %ld\n", - argv[currentarg], response_code); - } - currentarg++; - } - - _wunlink(symbol_file.c_str()); - - if (success) { - wprintf(L"Uploaded symbols for windows-%s/%s/%s (%s %s)\n", - pdb_info.cpu.c_str(), pdb_info.debug_file.c_str(), - pdb_info.debug_identifier.c_str(), code_file.c_str(), - file_version.c_str()); - } - - return success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp b/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp deleted file mode 100644 index d7e5fb7b9..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/windows/symupload/symupload.gyp +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2013 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'includes': [ - '../../../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'symupload', - 'type': 'executable', - 'sources': [ - 'symupload.cc', - ], - 'dependencies': [ - '../../../common/windows/common_windows.gyp:common_windows_lib', - ], - }, - ], -} -- cgit v1.2.3